Default spring-faces component support now based on Dojo. Ext support moved to faces-ext tag namespace.
This commit is contained in:
260
spring-faces/src/main/java/META-INF/dijit/ColorPalette.js
Normal file
260
spring-faces/src/main/java/META-INF/dijit/ColorPalette.js
Normal file
@@ -0,0 +1,260 @@
|
||||
if(!dojo._hasResource["dijit.ColorPalette"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.ColorPalette"] = true;
|
||||
dojo.provide("dijit.ColorPalette");
|
||||
|
||||
dojo.require("dijit._Widget");
|
||||
dojo.require("dijit._Templated");
|
||||
dojo.require("dojo.colors");
|
||||
dojo.require("dojo.i18n");
|
||||
dojo.requireLocalization("dojo", "colors", null, "ROOT");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.ColorPalette",
|
||||
[dijit._Widget, dijit._Templated],
|
||||
{
|
||||
// summary
|
||||
// Grid showing various colors, so the user can pick a certain color
|
||||
|
||||
// defaultTimeout: Number
|
||||
// number of milliseconds before a held key or button becomes typematic
|
||||
defaultTimeout: 500,
|
||||
|
||||
// timeoutChangeRate: Number
|
||||
// fraction of time used to change the typematic timer between events
|
||||
// 1.0 means that each typematic event fires at defaultTimeout intervals
|
||||
// < 1.0 means that each typematic event fires at an increasing faster rate
|
||||
timeoutChangeRate: 0.90,
|
||||
|
||||
// palette: String
|
||||
// Size of grid, either "7x10" or "3x4".
|
||||
palette: "7x10",
|
||||
|
||||
//_value: String
|
||||
// The value of the selected color.
|
||||
value: null,
|
||||
|
||||
//_currentFocus: Integer
|
||||
// Index of the currently focused color.
|
||||
_currentFocus: 0,
|
||||
|
||||
// _xDim: Integer
|
||||
// This is the number of colors horizontally across.
|
||||
_xDim: null,
|
||||
|
||||
// _yDim: Integer
|
||||
/// This is the number of colors vertically down.
|
||||
_yDim: null,
|
||||
|
||||
// _palettes: Map
|
||||
// This represents the value of the colors.
|
||||
// The first level is a hashmap of the different arrays available
|
||||
// The next two dimensions represent the columns and rows of colors.
|
||||
_palettes: {
|
||||
|
||||
"7x10": [["white", "seashell", "cornsilk", "lemonchiffon","lightyellow", "palegreen", "paleturquoise", "lightcyan", "lavender", "plum"],
|
||||
["lightgray", "pink", "bisque", "moccasin", "khaki", "lightgreen", "lightseagreen", "lightskyblue", "cornflowerblue", "violet"],
|
||||
["silver", "lightcoral", "sandybrown", "orange", "palegoldenrod", "chartreuse", "mediumturquoise", "skyblue", "mediumslateblue","orchid"],
|
||||
["gray", "red", "orangered", "darkorange", "yellow", "limegreen", "darkseagreen", "royalblue", "slateblue", "mediumorchid"],
|
||||
["dimgray", "crimson", "chocolate", "coral", "gold", "forestgreen", "seagreen", "blue", "blueviolet", "darkorchid"],
|
||||
["darkslategray","firebrick","saddlebrown", "sienna", "olive", "green", "darkcyan", "mediumblue","darkslateblue", "darkmagenta" ],
|
||||
["black", "darkred", "maroon", "brown", "darkolivegreen", "darkgreen", "midnightblue", "navy", "indigo", "purple"]],
|
||||
|
||||
"3x4": [["white", "lime", "green", "blue"],
|
||||
["silver", "yellow", "fuchsia", "navy"],
|
||||
["gray", "red", "purple", "black"]]
|
||||
|
||||
},
|
||||
|
||||
// _imagePaths: Map
|
||||
// This is stores the path to the palette images
|
||||
_imagePaths: {
|
||||
"7x10": dojo.moduleUrl("dijit", "templates/colors7x10.png"),
|
||||
"3x4": dojo.moduleUrl("dijit", "templates/colors3x4.png")
|
||||
},
|
||||
|
||||
// _paletteCoords: Map
|
||||
// This is a map that is used to calculate the coordinates of the
|
||||
// images that make up the palette.
|
||||
_paletteCoords: {
|
||||
"leftOffset": 3, "topOffset": 3,
|
||||
"cWidth": 18, "cHeight": 16
|
||||
},
|
||||
|
||||
// templatePath: String
|
||||
// Path to the template of this widget.
|
||||
templateString:"<fieldset class=\"dijitInlineBox\">\n\t<div style=\"overflow: hidden\" dojoAttachPoint=\"divNode\" waiRole=\"grid\" tabIndex=\"-1\">\n\t\t<img style=\"border-style: none;\" dojoAttachPoint=\"imageNode\" tabIndex=\"-1\" />\n\t</div>\t\n</fieldset>\n",
|
||||
|
||||
|
||||
_paletteDims: {
|
||||
"7x10": {"width": "185px", "height": "117px"},
|
||||
"3x4": {"width": "77px", "height": "53px"}
|
||||
},
|
||||
|
||||
|
||||
postCreate: function(){
|
||||
// A name has to be given to the colorMap, this needs to be unique per Palette.
|
||||
dojo.mixin(this.divNode.style, this._paletteDims[this.palette]);
|
||||
this.imageNode.setAttribute("src", this._imagePaths[this.palette]);
|
||||
var choices = this._palettes[this.palette];
|
||||
this.domNode.style.position = "relative";
|
||||
this._highlightNodes = [];
|
||||
this.colorNames = dojo.i18n.getLocalization("dojo", "colors", this.lang);
|
||||
|
||||
for(var row=0; row < choices.length; row++){
|
||||
for(var col=0; col < choices[row].length; col++){
|
||||
var highlightNode = document.createElement("img");
|
||||
highlightNode.src = dojo.moduleUrl("dijit", "templates/blank.gif");
|
||||
dojo.addClass(highlightNode, "dijitPaletteImg");
|
||||
var color = choices[row][col];
|
||||
var colorValue = new dojo.Color(dojo.Color.named[color]);
|
||||
highlightNode.alt = this.colorNames[color];
|
||||
highlightNode.color = colorValue.toHex();
|
||||
var highlightStyle = highlightNode.style;
|
||||
highlightStyle.color = highlightStyle.backgroundColor = highlightNode.color;
|
||||
dojo.forEach(["Dijitclick", "MouseOut", "MouseOver", "Blur", "Focus"], function(handler){
|
||||
this.connect(highlightNode, "on"+handler.toLowerCase(), "_onColor"+handler);
|
||||
}, this);
|
||||
this.divNode.appendChild(highlightNode);
|
||||
var coords = this._paletteCoords;
|
||||
highlightStyle.top = coords.topOffset + (row * coords.cHeight) + "px";
|
||||
highlightStyle.left = coords.leftOffset + (col * coords.cWidth) + "px";
|
||||
highlightNode.setAttribute("tabIndex","-1");
|
||||
highlightNode.title = this.colorNames[color];
|
||||
dijit.wai.setAttr(highlightNode, "waiRole", "role", "gridcell");
|
||||
highlightNode.index = this._highlightNodes.length;
|
||||
this._highlightNodes.push(highlightNode);
|
||||
}
|
||||
}
|
||||
this._highlightNodes[this._currentFocus].tabIndex = 0;
|
||||
this._xDim = choices[0].length;
|
||||
this._yDim = choices.length;
|
||||
|
||||
// Now set all events
|
||||
// The palette itself is navigated to with the tab key on the keyboard
|
||||
// Keyboard navigation within the Palette is with the arrow keys
|
||||
// Spacebar selects the color.
|
||||
// For the up key the index is changed by negative the x dimension.
|
||||
|
||||
var keyIncrementMap = {
|
||||
UP_ARROW: -this._xDim,
|
||||
// The down key the index is increase by the x dimension.
|
||||
DOWN_ARROW: this._xDim,
|
||||
// Right and left move the index by 1.
|
||||
RIGHT_ARROW: 1,
|
||||
LEFT_ARROW: -1
|
||||
};
|
||||
for(var key in keyIncrementMap){
|
||||
dijit.typematic.addKeyListener(this.domNode,
|
||||
{keyCode:dojo.keys[key], ctrlKey:false, altKey:false, shiftKey:false},
|
||||
this,
|
||||
function(){
|
||||
var increment = keyIncrementMap[key];
|
||||
return function(count){ this._navigateByKey(increment, count); };
|
||||
}(),
|
||||
this.timeoutChangeRate, this.defaultTimeout);
|
||||
}
|
||||
},
|
||||
|
||||
focus: function(){
|
||||
// summary:
|
||||
// Focus this ColorPalette.
|
||||
dijit.focus(this._highlightNodes[this._currentFocus]);
|
||||
},
|
||||
|
||||
onChange: function(color){
|
||||
// summary:
|
||||
// Callback when a color is selected.
|
||||
// color: String
|
||||
// Hex value corresponding to color.
|
||||
console.debug("Color selected is: "+color);
|
||||
},
|
||||
|
||||
_onColorDijitclick: function(/*Event*/ evt){
|
||||
// summary:
|
||||
// Handler for click, enter key & space key. Selects the color.
|
||||
// evt:
|
||||
// The event.
|
||||
var target = evt.currentTarget;
|
||||
if (this._currentFocus != target.index){
|
||||
this._currentFocus = target.index;
|
||||
dijit.focus(target);
|
||||
}
|
||||
this._selectColor(target);
|
||||
dojo.stopEvent(evt);
|
||||
},
|
||||
|
||||
_onColorMouseOut: function(/*Event*/ evt){
|
||||
// summary:
|
||||
// Handler for onMouseOut. Removes highlight.
|
||||
// evt:
|
||||
// The mouse event.
|
||||
dojo.removeClass(evt.currentTarget, "dijitPaletteImgHighlight");
|
||||
},
|
||||
|
||||
_onColorMouseOver: function(/*Event*/ evt){
|
||||
// summary:
|
||||
// Handler for onMouseOver. Highlights the color.
|
||||
// evt:
|
||||
// The mouse event.
|
||||
var target = evt.currentTarget;
|
||||
target.tabIndex = 0;
|
||||
target.focus();
|
||||
},
|
||||
|
||||
_onColorBlur: function(/*Event*/ evt){
|
||||
// summary:
|
||||
// Handler for onBlur. Removes highlight and sets
|
||||
// the first color as the palette's tab point.
|
||||
// evt:
|
||||
// The blur event.
|
||||
dojo.removeClass(evt.currentTarget, "dijitPaletteImgHighlight");
|
||||
evt.currentTarget.tabIndex = -1;
|
||||
this._currentFocus = 0;
|
||||
this._highlightNodes[0].tabIndex = 0;
|
||||
},
|
||||
|
||||
_onColorFocus: function(/*Event*/ evt){
|
||||
// summary:
|
||||
// Handler for onFocus. Highlights the color.
|
||||
// evt:
|
||||
// The focus event.
|
||||
if(this._currentFocus != evt.currentTarget.index){
|
||||
this._highlightNodes[this._currentFocus].tabIndex = -1;
|
||||
}
|
||||
this._currentFocus = evt.currentTarget.index;
|
||||
dojo.addClass(evt.currentTarget, "dijitPaletteImgHighlight");
|
||||
|
||||
},
|
||||
|
||||
_selectColor: function(selectNode){
|
||||
// summary:
|
||||
// This selects a color. It triggers the onChange event
|
||||
// area:
|
||||
// The area node that covers the color being selected.
|
||||
this.value = selectNode.color;
|
||||
this.onChange(selectNode.color);
|
||||
},
|
||||
|
||||
_navigateByKey: function(increment, typeCount){
|
||||
// summary:we
|
||||
// This is the callback for typematic.
|
||||
// It changes the focus and the highlighed color.
|
||||
// increment:
|
||||
// How much the key is navigated.
|
||||
// typeCount:
|
||||
// How many times typematic has fired.
|
||||
|
||||
// typecount == -1 means the key is released.
|
||||
if(typeCount == -1){ return; }
|
||||
|
||||
var newFocusIndex = this._currentFocus + increment;
|
||||
if(newFocusIndex < this._highlightNodes.length && newFocusIndex > -1)
|
||||
{
|
||||
var focusNode = this._highlightNodes[newFocusIndex];
|
||||
focusNode.tabIndex = 0;
|
||||
focusNode.focus();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
66
spring-faces/src/main/java/META-INF/dijit/Declaration.js
Normal file
66
spring-faces/src/main/java/META-INF/dijit/Declaration.js
Normal file
@@ -0,0 +1,66 @@
|
||||
if(!dojo._hasResource["dijit.Declaration"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.Declaration"] = true;
|
||||
dojo.provide("dijit.Declaration");
|
||||
dojo.require("dijit._Widget");
|
||||
dojo.require("dijit._Templated");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.Declaration",
|
||||
dijit._Widget,
|
||||
{
|
||||
// summary:
|
||||
// The Declaration widget allows a user to declare new widget
|
||||
// classes directly from a snippet of markup.
|
||||
|
||||
_noScript: true,
|
||||
widgetClass: "",
|
||||
replaceVars: true,
|
||||
defaults: null,
|
||||
mixins: [],
|
||||
buildRendering: function(){
|
||||
var src = this.srcNodeRef.parentNode.removeChild(this.srcNodeRef);
|
||||
var preambles = dojo.query("> script[type='dojo/method'][event='preamble']", src).orphan();
|
||||
var scripts = dojo.query("> script[type^='dojo/']", src).orphan();
|
||||
var srcType = src.nodeName;
|
||||
|
||||
var propList = this.defaults||{};
|
||||
|
||||
this.mixins = this.mixins.length ?
|
||||
dojo.map(this.mixins, dojo.getObject) :
|
||||
[ dijit._Widget, dijit._Templated ];
|
||||
|
||||
if(preambles.length){
|
||||
// we only support one preamble. So be it.
|
||||
propList.preamble = dojo.parser._functionFromScript(preambles[0]);
|
||||
}
|
||||
propList.widgetsInTemplate = true;
|
||||
propList.templateString = "<"+srcType+" class='"+src.className+"'>"+src.innerHTML.replace(/\%7B/g,"{").replace(/\%7D/g,"}")+"</"+srcType+">";
|
||||
|
||||
// strip things so we don't create stuff under us in the initial setup phase
|
||||
dojo.query("[dojoType]", src).forEach(function(node){
|
||||
node.removeAttribute("dojoType");
|
||||
});
|
||||
scripts.forEach(function(s){
|
||||
if(!s.getAttribute("event")){
|
||||
this.mixins.push(dojo.parser._functionFromScript(s));
|
||||
}
|
||||
}, this);
|
||||
|
||||
// create the new widget class
|
||||
dojo.declare(
|
||||
this.widgetClass,
|
||||
this.mixins,
|
||||
propList
|
||||
);
|
||||
|
||||
var wcp = dojo.getObject(this.widgetClass).prototype;
|
||||
scripts.forEach(function(s){
|
||||
if(s.getAttribute("event")){
|
||||
dojo.parser._wireUpMethod(wcp, s);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
362
spring-faces/src/main/java/META-INF/dijit/Dialog.js
Normal file
362
spring-faces/src/main/java/META-INF/dijit/Dialog.js
Normal file
@@ -0,0 +1,362 @@
|
||||
if(!dojo._hasResource["dijit.Dialog"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.Dialog"] = true;
|
||||
dojo.provide("dijit.Dialog");
|
||||
|
||||
dojo.require("dojo.dnd.move");
|
||||
dojo.require("dojo.fx");
|
||||
|
||||
dojo.require("dijit._Widget");
|
||||
dojo.require("dijit._Templated");
|
||||
dojo.require("dijit.layout.ContentPane");
|
||||
dojo.require("dijit.form.Form");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.DialogUnderlay",
|
||||
[dijit._Widget, dijit._Templated],
|
||||
{
|
||||
// summary: the thing that grays out the screen behind the dialog
|
||||
|
||||
// Template has two divs; outer div is used for fade-in/fade-out, and also to hold background iframe.
|
||||
// Inner div has opacity specified in CSS file.
|
||||
templateString: "<div class=dijitDialogUnderlayWrapper id='${id}_underlay'><div class=dijitDialogUnderlay dojoAttachPoint='node'></div></div>",
|
||||
|
||||
postCreate: function(){
|
||||
dojo.body().appendChild(this.domNode);
|
||||
this.bgIframe = new dijit.BackgroundIframe(this.domNode);
|
||||
},
|
||||
|
||||
layout: function(){
|
||||
// summary
|
||||
// Sets the background to the size of the viewport (rather than the size
|
||||
// of the document) since we need to cover the whole browser window, even
|
||||
// if the document is only a few lines long.
|
||||
|
||||
var viewport = dijit.getViewport();
|
||||
var is = this.node.style,
|
||||
os = this.domNode.style;
|
||||
|
||||
os.top = viewport.t + "px";
|
||||
os.left = viewport.l + "px";
|
||||
is.width = viewport.w + "px";
|
||||
is.height = viewport.h + "px";
|
||||
|
||||
// process twice since the scroll bar may have been removed
|
||||
// by the previous resizing
|
||||
var viewport2 = dijit.getViewport();
|
||||
if(viewport.w != viewport2.w){ is.width = viewport2.w + "px"; }
|
||||
if(viewport.h != viewport2.h){ is.height = viewport2.h + "px"; }
|
||||
},
|
||||
|
||||
show: function(){
|
||||
this.domNode.style.display = "block";
|
||||
this.layout();
|
||||
if(this.bgIframe.iframe){
|
||||
this.bgIframe.iframe.style.display = "block";
|
||||
}
|
||||
this._resizeHandler = this.connect(window, "onresize", "layout");
|
||||
},
|
||||
|
||||
hide: function(){
|
||||
this.domNode.style.display = "none";
|
||||
this.domNode.style.width = this.domNode.style.height = "1px";
|
||||
if(this.bgIframe.iframe){
|
||||
this.bgIframe.iframe.style.display = "none";
|
||||
}
|
||||
this.disconnect(this._resizeHandler);
|
||||
},
|
||||
|
||||
uninitialize: function(){
|
||||
if(this.bgIframe){
|
||||
this.bgIframe.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
dojo.declare(
|
||||
"dijit.Dialog",
|
||||
[dijit.layout.ContentPane, dijit._Templated, dijit.form._FormMixin],
|
||||
{
|
||||
// summary:
|
||||
// Pops up a modal dialog window, blocking access to the screen
|
||||
// and also graying out the screen Dialog is extended from
|
||||
// ContentPane so it supports all the same parameters (href, etc.)
|
||||
|
||||
templateString: null,
|
||||
templateString:"<div class=\"dijitDialog\">\n\t\t<div dojoAttachPoint=\"titleBar\" class=\"dijitDialogTitleBar\" tabindex=\"0\" waiRole=\"dialog\" title=\"${title}\">\n\t\t<span dojoAttachPoint=\"titleNode\" class=\"dijitDialogTitle\">${title}</span>\n\t\t<span dojoAttachPoint=\"closeButtonNode\" class=\"dijitDialogCloseIcon\" dojoAttachEvent=\"onclick: hide\">\n\t\t\t<span dojoAttachPoint=\"closeText\" class=\"closeText\">x</span>\n\t\t</span>\n\t</div>\n\t\t<div dojoAttachPoint=\"containerNode\" class=\"dijitDialogPaneContent\"></div>\n\t<span dojoAttachPoint=\"tabEnd\" dojoAttachEvent=\"onfocus:_cycleFocus\" tabindex=\"0\"></span>\n</div>\n",
|
||||
|
||||
// title: String
|
||||
// Title of the dialog
|
||||
title: "",
|
||||
|
||||
duration: 400,
|
||||
|
||||
_lastFocusItem:null,
|
||||
|
||||
postCreate: function(){
|
||||
dojo.body().appendChild(this.domNode);
|
||||
dijit.Dialog.superclass.postCreate.apply(this, arguments);
|
||||
this.domNode.style.display="none";
|
||||
this.connect(this, "onExecute", "hide");
|
||||
this.connect(this, "onCancel", "hide");
|
||||
},
|
||||
|
||||
onLoad: function(){
|
||||
// when href is specified we need to reposition
|
||||
// the dialog after the data is loaded
|
||||
this._position();
|
||||
dijit.Dialog.superclass.onLoad.call(this);
|
||||
},
|
||||
|
||||
_setup: function(){
|
||||
// summary:
|
||||
// stuff we need to do before showing the Dialog for the first
|
||||
// time (but we defer it until right beforehand, for
|
||||
// performance reasons)
|
||||
|
||||
this._modalconnects = [];
|
||||
|
||||
if(this.titleBar){
|
||||
this._moveable = new dojo.dnd.Moveable(this.domNode, { handle: this.titleBar });
|
||||
}
|
||||
|
||||
this._underlay = new dijit.DialogUnderlay();
|
||||
|
||||
var node = this.domNode;
|
||||
this._fadeIn = dojo.fx.combine(
|
||||
[dojo.fadeIn({
|
||||
node: node,
|
||||
duration: this.duration
|
||||
}),
|
||||
dojo.fadeIn({
|
||||
node: this._underlay.domNode,
|
||||
duration: this.duration,
|
||||
onBegin: dojo.hitch(this._underlay, "show")
|
||||
})
|
||||
]
|
||||
);
|
||||
|
||||
this._fadeOut = dojo.fx.combine(
|
||||
[dojo.fadeOut({
|
||||
node: node,
|
||||
duration: this.duration,
|
||||
onEnd: function(){
|
||||
node.style.display="none";
|
||||
}
|
||||
}),
|
||||
dojo.fadeOut({
|
||||
node: this._underlay.domNode,
|
||||
duration: this.duration,
|
||||
onEnd: dojo.hitch(this._underlay, "hide")
|
||||
})
|
||||
]
|
||||
);
|
||||
},
|
||||
|
||||
uninitialize: function(){
|
||||
if(this._underlay){
|
||||
this._underlay.destroy();
|
||||
}
|
||||
},
|
||||
|
||||
_position: function(){
|
||||
// summary: position modal dialog in center of screen
|
||||
|
||||
var viewport = dijit.getViewport();
|
||||
var mb = dojo.marginBox(this.domNode);
|
||||
|
||||
var style = this.domNode.style;
|
||||
style.left = (viewport.l + (viewport.w - mb.w)/2) + "px";
|
||||
style.top = (viewport.t + (viewport.h - mb.h)/2) + "px";
|
||||
},
|
||||
|
||||
_findLastFocus: function(/*Event*/ evt){
|
||||
// summary: called from onblur of dialog container to determine the last focusable item
|
||||
this._lastFocused = evt.target;
|
||||
},
|
||||
|
||||
_cycleFocus: function(/*Event*/ evt){
|
||||
// summary: when tabEnd receives focus, advance focus around to titleBar
|
||||
|
||||
// on first focus to tabEnd, store the last focused item in dialog
|
||||
if(!this._lastFocusItem){
|
||||
this._lastFocusItem = this._lastFocused;
|
||||
}
|
||||
this.titleBar.focus();
|
||||
},
|
||||
|
||||
_onKey: function(/*Event*/ evt){
|
||||
if(evt.keyCode){
|
||||
var node = evt.target;
|
||||
// see if we are shift-tabbing from titleBar
|
||||
if(node == this.titleBar && evt.shiftKey && evt.keyCode == dojo.keys.TAB){
|
||||
if (this._lastFocusItem){
|
||||
this._lastFocusItem.focus(); // send focus to last item in dialog if known
|
||||
}
|
||||
dojo.stopEvent(evt);
|
||||
}else{
|
||||
// see if the key is for the dialog
|
||||
while (node){
|
||||
if(node == this.domNode){
|
||||
if (evt.keyCode == dojo.keys.ESCAPE){
|
||||
this.hide();
|
||||
}else{
|
||||
return; // just let it go
|
||||
}
|
||||
}
|
||||
node = node.parentNode;
|
||||
}
|
||||
// this key is for the disabled document window
|
||||
if (evt.keyCode != dojo.keys.TAB){ // allow tabbing into the dialog for a11y
|
||||
dojo.stopEvent(evt);
|
||||
// opera won't tab to a div
|
||||
}else if (!dojo.isOpera){
|
||||
try{
|
||||
this.titleBar.focus();
|
||||
}catch(e){/*squelch*/}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
show: function(){
|
||||
// summary: display the dialog
|
||||
|
||||
// first time we show the dialog, there's some initialization stuff to do
|
||||
if(!this._alreadyInitialized){
|
||||
this._setup();
|
||||
this._alreadyInitialized=true;
|
||||
}
|
||||
|
||||
if(this._fadeOut.status() == "playing"){
|
||||
this._fadeOut.stop();
|
||||
}
|
||||
|
||||
this._modalconnects.push(dojo.connect(window, "onscroll", this, "layout"));
|
||||
this._modalconnects.push(dojo.connect(document.documentElement, "onkeypress", this, "_onKey"));
|
||||
|
||||
// IE doesn't bubble onblur events - use ondeactivate instead
|
||||
var ev = typeof(document.ondeactivate) == "object" ? "ondeactivate" : "onblur";
|
||||
this._modalconnects.push(dojo.connect(this.containerNode, ev, this, "_findLastFocus"));
|
||||
|
||||
|
||||
dojo.style(this.domNode, "opacity", 0);
|
||||
this.domNode.style.display="block";
|
||||
|
||||
this._loadCheck(); // lazy load trigger
|
||||
|
||||
this._position();
|
||||
|
||||
this._fadeIn.play();
|
||||
|
||||
this._savedFocus = dijit.getFocus(this);
|
||||
|
||||
// set timeout to allow the browser to render dialog
|
||||
setTimeout(dojo.hitch(this, function(){
|
||||
dijit.focus(this.titleBar);
|
||||
}), 50);
|
||||
},
|
||||
|
||||
hide: function(){
|
||||
// summary
|
||||
// Hide the dialog
|
||||
|
||||
// if we haven't been initialized yet then we aren't showing and we can just return
|
||||
if(!this._alreadyInitialized){
|
||||
return;
|
||||
}
|
||||
|
||||
if(this._fadeIn.status() == "playing"){
|
||||
this._fadeIn.stop();
|
||||
}
|
||||
this._fadeOut.play();
|
||||
|
||||
if (this._scrollConnected){
|
||||
this._scrollConnected = false;
|
||||
}
|
||||
dojo.forEach(this._modalconnects, dojo.disconnect);
|
||||
this._modalconnects = [];
|
||||
|
||||
// TODO: this is failing on FF presumably because the DialogUnderlay hasn't disappeared yet?
|
||||
// Attach it to fire at the end of the animation
|
||||
dijit.focus(this._savedFocus);
|
||||
},
|
||||
|
||||
layout: function() {
|
||||
if(this.domNode.style.display == "block"){
|
||||
this._underlay.layout();
|
||||
this._position();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
dojo.declare(
|
||||
"dijit.TooltipDialog",
|
||||
[dijit.layout.ContentPane, dijit._Templated, dijit.form._FormMixin],
|
||||
{
|
||||
// summary:
|
||||
// Pops up a dialog that appears like a Tooltip
|
||||
|
||||
// title: String
|
||||
// Description of tooltip dialog (required for a11Y)
|
||||
title: "",
|
||||
|
||||
_lastFocusItem: null,
|
||||
|
||||
templateString: null,
|
||||
templateString:"<div id=\"${id}\" class=\"dijitTooltipDialog\" >\n\t<div class=\"dijitTooltipContainer\">\n\t\t<div class =\"dijitTooltipContents dijitTooltipFocusNode\" dojoAttachPoint=\"containerNode\" tabindex=\"0\" waiRole=\"dialog\"></div>\n\t</div>\n\t<span dojoAttachPoint=\"tabEnd\" tabindex=\"0\" dojoAttachEvent=\"focus:_cycleFocus\"></span>\n\t<div class=\"dijitTooltipConnector\" ></div>\n</div>\n",
|
||||
|
||||
postCreate: function(){
|
||||
dijit.TooltipDialog.superclass.postCreate.apply(this, arguments);
|
||||
this.connect(this.containerNode, "onkeypress", "_onKey");
|
||||
|
||||
// IE doesn't bubble onblur events - use ondeactivate instead
|
||||
var ev = typeof(document.ondeactivate) == "object" ? "ondeactivate" : "onblur";
|
||||
this.connect(this.containerNode, ev, "_findLastFocus");
|
||||
this.containerNode.title=this.title;
|
||||
},
|
||||
|
||||
orient: function(/*Object*/ corner){
|
||||
// summary: configure widget to be displayed in given position relative to the button
|
||||
this.domNode.className="dijitTooltipDialog " +" dijitTooltipAB"+(corner.charAt(1)=='L'?"Left":"Right")+" dijitTooltip"+(corner.charAt(0)=='T' ? "Below" : "Above");
|
||||
},
|
||||
|
||||
onOpen: function(/*Object*/ pos){
|
||||
// summary: called when dialog is displayed
|
||||
this.orient(pos.corner);
|
||||
this._loadCheck(); // lazy load trigger
|
||||
this.containerNode.focus();
|
||||
},
|
||||
|
||||
_onKey: function(/*Event*/ evt){
|
||||
//summary: keep keyboard focus in dialog; close dialog on escape key
|
||||
if (evt.keyCode == dojo.keys.ESCAPE){
|
||||
this.onCancel();
|
||||
}else if (evt.target == this.containerNode && evt.shiftKey && evt.keyCode == dojo.keys.TAB){
|
||||
if (this._lastFocusItem){
|
||||
this._lastFocusItem.focus();
|
||||
}
|
||||
dojo.stopEvent(evt);
|
||||
}
|
||||
},
|
||||
|
||||
_findLastFocus: function(/*Event*/ evt){
|
||||
// summary: called from onblur of dialog container to determine the last focusable item
|
||||
this._lastFocused = evt.target;
|
||||
},
|
||||
|
||||
_cycleFocus: function(/*Event*/ evt){
|
||||
// summary: when tabEnd receives focus, advance focus around to containerNode
|
||||
|
||||
// on first focus to tabEnd, store the last focused item in dialog
|
||||
if(!this._lastFocusItem){
|
||||
this._lastFocusItem = this._lastFocused;
|
||||
}
|
||||
this.containerNode.focus();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
368
spring-faces/src/main/java/META-INF/dijit/Editor.js
Normal file
368
spring-faces/src/main/java/META-INF/dijit/Editor.js
Normal file
@@ -0,0 +1,368 @@
|
||||
if(!dojo._hasResource["dijit.Editor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.Editor"] = true;
|
||||
dojo.provide("dijit.Editor");
|
||||
dojo.require("dijit._editor.RichText");
|
||||
dojo.require("dijit.Toolbar");
|
||||
dojo.require("dijit._editor._Plugin");
|
||||
dojo.require("dijit._Container");
|
||||
dojo.require("dojo.i18n");
|
||||
dojo.requireLocalization("dijit._editor", "commands", null, "it,ROOT,de");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.Editor",
|
||||
[ dijit._editor.RichText, dijit._Container ],
|
||||
{
|
||||
// plugins:
|
||||
// a list of plugin names (as strings) or instances (as objects)
|
||||
// for this widget.
|
||||
// plugins: [ "dijit._editor.plugins.DefaultToolbar" ],
|
||||
plugins: null,
|
||||
extraPlugins: null,
|
||||
preamble: function(){
|
||||
this.inherited('preamble',arguments);
|
||||
this.plugins=["undo","redo","|","cut","copy","paste","|","bold","italic","underline","strikethrough","|",
|
||||
"insertOrderedList","insertUnorderedList","indent","outdent","|","justifyLeft","justifyRight","justifyCenter","justifyFull"/*"createlink"*/];
|
||||
|
||||
this._plugins=[];
|
||||
this._editInterval = this.editActionInterval * 1000;
|
||||
},
|
||||
toolbar: null,
|
||||
postCreate: function(){
|
||||
//for custom undo/redo
|
||||
if(this.customUndo){
|
||||
dojo['require']("dijit._editor.range");
|
||||
this._steps=this._steps.slice(0);
|
||||
this._undoedSteps=this._undoedSteps.slice(0);
|
||||
// this.addKeyHandler('z',this.KEY_CTRL,this.undo);
|
||||
// this.addKeyHandler('y',this.KEY_CTRL,this.redo);
|
||||
}
|
||||
if(dojo.isArray(this.extraPlugins)){
|
||||
this.plugins=this.plugins.concat(this.extraPlugins);
|
||||
}
|
||||
|
||||
// try{
|
||||
dijit.Editor.superclass.postCreate.apply(this, arguments);
|
||||
|
||||
this.commands = dojo.i18n.getLocalization("dijit._editor", "commands", this.lang);
|
||||
|
||||
if(!this.toolbar){
|
||||
// if we haven't been assigned a toolbar, create one
|
||||
this.toolbar = new dijit.Toolbar();
|
||||
dojo.place(this.toolbar.domNode, this.editingArea, "before");
|
||||
}
|
||||
|
||||
dojo.forEach(this.plugins, this.addPlugin, this);
|
||||
// }catch(e){ console.debug(e); }
|
||||
},
|
||||
destroy: function(){
|
||||
dojo.forEach(this._plugins, function(p){
|
||||
if(p.destroy){
|
||||
p.destroy();
|
||||
}
|
||||
});
|
||||
this._plugins=[];
|
||||
this.inherited('destroy',arguments);
|
||||
},
|
||||
addPlugin: function(/*String||Object*/plugin, /*Integer?*/index){
|
||||
// summary:
|
||||
// takes a plugin name as a string or a plugin instance and
|
||||
// adds it to the toolbar and associates it with this editor
|
||||
// instance. The resulting plugin is added to the Editor's
|
||||
// plugins array. If index is passed, it's placed in the plugins
|
||||
// array at that index. No big magic, but a nice helper for
|
||||
// passing in plugin names via markup.
|
||||
// plugin: String, args object or plugin instance. Required.
|
||||
// args: This object will be passed to the plugin constructor.
|
||||
// index:
|
||||
// Integer, optional. Used when creating an instance from
|
||||
// something already in this.plugins. Ensures that the new
|
||||
// instance is assigned to this.plugins at that index.
|
||||
var args=dojo.isString(plugin)?{name:plugin}:plugin;
|
||||
if(!args.setEditor){
|
||||
var o={"args":args,"plugin":null,"editor":this};
|
||||
dojo.publish("dijit.Editor.getPlugin",[o]);
|
||||
if(!o.plugin){
|
||||
var pc = dojo.getObject(args.name);
|
||||
if(pc){
|
||||
o.plugin=new pc(args);
|
||||
}
|
||||
}
|
||||
if(!o.plugin){
|
||||
console.debug('Can not find plugin',plugin);
|
||||
return;
|
||||
}
|
||||
plugin=o.plugin;
|
||||
}
|
||||
if(arguments.length > 1){
|
||||
this._plugins[index] = plugin;
|
||||
}else{
|
||||
this._plugins.push(plugin);
|
||||
}
|
||||
plugin.setEditor(this);
|
||||
if(dojo.isFunction(plugin.setToolbar)){
|
||||
plugin.setToolbar(this.toolbar);
|
||||
}
|
||||
},
|
||||
/* beginning of custom undo/redo support */
|
||||
|
||||
// customUndo: Boolean
|
||||
// Whether we shall use custom undo/redo support instead of the native
|
||||
// browser support. By default, we only enable customUndo for IE, as it
|
||||
// has broken native undo/redo support. Note: the implementation does
|
||||
// support other browsers which have W3C DOM2 Range API.
|
||||
customUndo: dojo.isIE,
|
||||
|
||||
// editActionInterval: Integer
|
||||
// When using customUndo, not every keystroke will be saved as a step.
|
||||
// Instead typing (including delete) will be grouped together: after
|
||||
// a user stop typing for editActionInterval seconds, a step will be
|
||||
// saved; if a user resume typing within editActionInterval seconds,
|
||||
// the timeout will be restarted. By default, editActionInterval is 3
|
||||
// seconds.
|
||||
editActionInterval: 3,
|
||||
beginEditing: function(cmd){
|
||||
if(!this._inEditing){
|
||||
this._inEditing=true;
|
||||
this._beginEditing(cmd);
|
||||
}
|
||||
if(this.editActionInterval>0){
|
||||
if(this._editTimer){
|
||||
clearTimeout(this._editTimer);
|
||||
}
|
||||
this._editTimer = setTimeout(dojo.hitch(this, this.endEditing), this._editInterval);
|
||||
}
|
||||
},
|
||||
_steps:[],
|
||||
_undoedSteps:[],
|
||||
execCommand: function(cmd){
|
||||
if(this.customUndo && (cmd=='undo' || cmd=='redo')){
|
||||
return cmd=='undo'?this.undo():this.redo();
|
||||
}else{
|
||||
try{
|
||||
if(this.customUndo){
|
||||
this.endEditing();
|
||||
this._beginEditing();
|
||||
}
|
||||
var r = this.inherited('execCommand',arguments);
|
||||
if(this.customUndo){
|
||||
this._endEditing();
|
||||
}
|
||||
return r;
|
||||
}catch(e){
|
||||
if(dojo.isMoz){
|
||||
if('copy'==cmd){
|
||||
alert(this.commands['copyErrorFF']);
|
||||
}else if('cut'==cmd){
|
||||
alert(this.commands['cutErrorFF']);
|
||||
}else if('paste'==cmd){
|
||||
alert(this.commands['pasteErrorFF']);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
queryCommandEnabled: function(cmd){
|
||||
if(this.customUndo && (cmd=='undo' || cmd=='redo')){
|
||||
return cmd=='undo'?(this._steps.length>1):(this._undoedSteps.length>0);
|
||||
}else{
|
||||
return this.inherited('queryCommandEnabled',arguments);
|
||||
}
|
||||
},
|
||||
_changeToStep: function(from,to){
|
||||
this.setValue(to.text);
|
||||
var b=to.bookmark;
|
||||
if(!b){ return; }
|
||||
if(dojo.isIE){
|
||||
if(dojo.isArray(b)){//IE CONTROL
|
||||
var tmp=[];
|
||||
dojo.forEach(b,function(n){
|
||||
tmp.push(dijit.range.getNode(n,this.editNode));
|
||||
},this);
|
||||
b=tmp;
|
||||
}
|
||||
}else{//w3c range
|
||||
var r=dijit.range.create();
|
||||
r.setStart(dijit.range.getNode(b.startContainer,this.editNode),b.startOffset);
|
||||
r.setEnd(dijit.range.getNode(b.endContainer,this.editNode),b.endOffset);
|
||||
b=r;
|
||||
}
|
||||
dojo.withGlobal(this.window,'moveToBookmark',dijit,[b]);
|
||||
},
|
||||
undo: function(){
|
||||
console.log('undo');
|
||||
this.endEditing(true);
|
||||
var s=this._steps.pop();
|
||||
if(this._steps.length>0){
|
||||
this.focus();
|
||||
this._changeToStep(s,this._steps[this._steps.length-1]);
|
||||
this._undoedSteps.push(s);
|
||||
this.onDisplayChanged();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
redo: function(){
|
||||
console.log('redo');
|
||||
this.endEditing(true);
|
||||
var s=this._undoedSteps.pop();
|
||||
if(s && this._steps.length>0){
|
||||
this.focus();
|
||||
this._changeToStep(this._steps[this._steps.length-1],s);
|
||||
this._steps.push(s);
|
||||
this.onDisplayChanged();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
endEditing: function(ignore_caret){
|
||||
if(this._editTimer){
|
||||
clearTimeout(this._editTimer);
|
||||
}
|
||||
if(this._inEditing){
|
||||
this._endEditing(ignore_caret);
|
||||
this._inEditing=false;
|
||||
}
|
||||
},
|
||||
_getBookmark: function(){
|
||||
var b=dojo.withGlobal(this.window,dijit.getBookmark);
|
||||
if(dojo.isIE){
|
||||
if(dojo.isArray(b)){//CONTROL
|
||||
var tmp=[];
|
||||
dojo.forEach(b,function(n){
|
||||
tmp.push(dijit.range.getIndex(n,this.editNode).o);
|
||||
},this);
|
||||
b=tmp;
|
||||
}
|
||||
}else{//w3c range
|
||||
var tmp=dijit.range.getIndex(b.startContainer,this.editNode).o
|
||||
b={startContainer:tmp,
|
||||
startOffset:b.startOffset,
|
||||
endContainer:b.endContainer===b.startContainer?tmp:dijit.range.getIndex(b.endContainer,this.editNode).o,
|
||||
endOffset:b.endOffset};
|
||||
}
|
||||
return b;
|
||||
},
|
||||
_beginEditing: function(cmd){
|
||||
if(this._steps.length===0){
|
||||
this._steps.push({'text':this.savedContent,'bookmark':this._getBookmark()});
|
||||
}
|
||||
},
|
||||
_endEditing: function(ignore_caret){
|
||||
var v=this.getValue(true);
|
||||
|
||||
this._undoedSteps=[];//clear undoed steps
|
||||
this._steps.push({'text':v,'bookmark':this._getBookmark()});
|
||||
},
|
||||
onKeyDown: function(e){
|
||||
if(!this.customUndo){
|
||||
this.inherited('onKeyDown',arguments);
|
||||
return;
|
||||
}
|
||||
var k=e.keyCode,ks=dojo.keys;
|
||||
if(e.ctrlKey){
|
||||
if(k===90||k===122){ //z
|
||||
dojo.stopEvent(e);
|
||||
this.undo();
|
||||
return;
|
||||
}else if(k===89||k===121){ //y
|
||||
dojo.stopEvent(e);
|
||||
this.redo();
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.inherited('onKeyDown',arguments);
|
||||
|
||||
switch(k){
|
||||
case ks.ENTER:
|
||||
this.beginEditing();
|
||||
break;
|
||||
case ks.BACKSPACE:
|
||||
case ks.DELETE:
|
||||
this.beginEditing();
|
||||
break;
|
||||
case 88: //x
|
||||
case 86: //v
|
||||
if(e.ctrlKey && !e.altKey && !e.metaKey){
|
||||
this.endEditing();//end current typing step if any
|
||||
if(e.keyCode == 88){
|
||||
this.beginEditing('cut');
|
||||
//use timeout to trigger after the cut is complete
|
||||
setTimeout(dojo.hitch(this, this.endEditing), 1);
|
||||
}else{
|
||||
this.beginEditing('paste');
|
||||
//use timeout to trigger after the paste is complete
|
||||
setTimeout(dojo.hitch(this, this.endEditing), 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
//pass through
|
||||
default:
|
||||
if(!e.ctrlKey && !e.altKey && !e.metaKey && (e.keyCode<dojo.keys.F1 || e.keyCode>dojo.keys.F15)){
|
||||
this.beginEditing();
|
||||
break;
|
||||
}
|
||||
//pass through
|
||||
case ks.ALT:
|
||||
this.endEditing();
|
||||
break;
|
||||
case ks.UP_ARROW:
|
||||
case ks.DOWN_ARROW:
|
||||
case ks.LEFT_ARROW:
|
||||
case ks.RIGHT_ARROW:
|
||||
case ks.HOME:
|
||||
case ks.END:
|
||||
case ks.PAGE_UP:
|
||||
case ks.PAGE_DOWN:
|
||||
this.endEditing(true);
|
||||
break;
|
||||
//maybe ctrl+backspace/delete, so don't endEditing when ctrl is pressed
|
||||
case ks.CTRL:
|
||||
case ks.SHIFT:
|
||||
break;
|
||||
}
|
||||
},
|
||||
_onBlur: function(){
|
||||
this.inherited('_onBlur',arguments);
|
||||
this.endEditing(true);
|
||||
},
|
||||
onClick: function(){
|
||||
this.endEditing(true);
|
||||
this.inherited('onClick',arguments);
|
||||
}
|
||||
/* end of custom undo/redo support */
|
||||
}
|
||||
);
|
||||
|
||||
dojo.subscribe("dijit.Editor.getPlugin",null,function(o){
|
||||
if(o.plugin){ return; }
|
||||
var args=o.args, p;
|
||||
var _p = dijit._editor._Plugin;
|
||||
var name=args.name;
|
||||
switch(name){
|
||||
case "undo": case "redo": case "cut": case "copy": case "paste": case "insertOrderedList":
|
||||
case "insertUnorderedList": case "indent": case "outdent": case "justifyCenter":
|
||||
case "justifyFull": case "justifyLeft": case "justifyRight": case "delete":
|
||||
case "selectAll": case "removeFormat":
|
||||
p = new _p({ command: name });
|
||||
break;
|
||||
|
||||
case "bold": case "italic": case "underline": case "strikethrough":
|
||||
case "subscript": case "superscript":
|
||||
//shall we try to auto require here? or require user to worry about it?
|
||||
// dojo['require']('dijit.form.Button');
|
||||
p = new _p({ buttonClass: dijit.form.ToggleButton, command: name });
|
||||
break;
|
||||
case "|":
|
||||
p = new _p({ button: new dijit.ToolbarSeparator() });
|
||||
break;
|
||||
case "createlink":
|
||||
// dojo['require']('dijit._editor.plugins.LinkDialog');
|
||||
p = new dijit._editor.plugins.LinkDialog();
|
||||
break;
|
||||
}
|
||||
// console.log('name',name,p);
|
||||
o.plugin=p;
|
||||
});
|
||||
|
||||
}
|
||||
538
spring-faces/src/main/java/META-INF/dijit/Menu.js
Normal file
538
spring-faces/src/main/java/META-INF/dijit/Menu.js
Normal file
@@ -0,0 +1,538 @@
|
||||
if(!dojo._hasResource["dijit.Menu"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.Menu"] = true;
|
||||
dojo.provide("dijit.Menu");
|
||||
|
||||
dojo.require("dijit._Widget");
|
||||
dojo.require("dijit._Container");
|
||||
dojo.require("dijit._Templated");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.Menu",
|
||||
[dijit._Widget, dijit._Templated, dijit._Container],
|
||||
{
|
||||
preamble: function() {
|
||||
this._bindings = [];
|
||||
},
|
||||
|
||||
templateString:
|
||||
'<table class="dijit dijitMenu dijitReset dijitMenuTable" waiRole="menu" dojoAttachEvent="onkeypress:_onKeyPress">' +
|
||||
'<tbody class="dijitReset" dojoAttachPoint="containerNode"></tbody>'+
|
||||
'</table>',
|
||||
|
||||
// targetNodeIds: String[]
|
||||
// Array of dom node ids of nodes to attach to.
|
||||
// Fill this with nodeIds upon widget creation and it becomes context menu for those nodes.
|
||||
targetNodeIds: [],
|
||||
|
||||
// contextMenuForWindow: Boolean
|
||||
// if true, right clicking anywhere on the window will cause this context menu to open;
|
||||
// if false, must specify targetNodeIds
|
||||
contextMenuForWindow: false,
|
||||
|
||||
// parentMenu: Widget
|
||||
// pointer to menu that displayed me
|
||||
parentMenu: null,
|
||||
|
||||
// popupDelay: Integer
|
||||
// number of milliseconds before hovering (without clicking) causes the popup to automatically open
|
||||
popupDelay: 500,
|
||||
|
||||
// _contextMenuWithMouse: Boolean
|
||||
// used to record mouse and keyboard events to determine if a context
|
||||
// menu is being opened with the keyboard or the mouse
|
||||
_contextMenuWithMouse: false,
|
||||
|
||||
postCreate: function(){
|
||||
if(this.contextMenuForWindow){
|
||||
this.bindDomNode(dojo.body());
|
||||
}else{
|
||||
dojo.forEach(this.targetNodeIds, this.bindDomNode, this);
|
||||
}
|
||||
},
|
||||
|
||||
startup: function(){
|
||||
dojo.forEach(this.getChildren(), function(child){ child.startup(); });
|
||||
},
|
||||
|
||||
onExecute: function(){
|
||||
// summary: attach point for notification about when a menu item has been executed
|
||||
},
|
||||
|
||||
onCancel: function(/*Boolean*/ closeAll){
|
||||
// summary: attach point for notification about when the user cancels the current menu
|
||||
},
|
||||
|
||||
focus: function(){
|
||||
this._focusFirstItem();
|
||||
},
|
||||
|
||||
_moveToPopup: function(/*Event*/ evt){
|
||||
if(this._focusedItem && this._focusedItem.popup && !this._focusedItem.disabled){
|
||||
return this._activateCurrentItem(evt);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
_activateCurrentItem: function(/*Event*/ evt){
|
||||
if(this._focusedItem){
|
||||
this._focusedItem._onClick(evt);
|
||||
return true; //do not pass to parent menu
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
_onKeyPress: function(/*Event*/ evt){
|
||||
// summary
|
||||
// Handle keyboard based menu navigation.
|
||||
if(evt.ctrlKey || evt.altKey){ return; }
|
||||
|
||||
var key = (evt.charCode == dojo.keys.SPACE ? dojo.keys.SPACE : evt.keyCode);
|
||||
switch(key){
|
||||
case dojo.keys.DOWN_ARROW:
|
||||
this._focusNeighborItem(1);
|
||||
dojo.stopEvent(evt);
|
||||
break;
|
||||
case dojo.keys.UP_ARROW:
|
||||
this._focusNeighborItem(-1);
|
||||
dojo.stopEvent(evt);
|
||||
break;
|
||||
case dojo.keys.RIGHT_ARROW:
|
||||
this._moveToPopup(evt);
|
||||
dojo.stopEvent(evt);
|
||||
break;
|
||||
case dojo.keys.LEFT_ARROW:
|
||||
if(this.parentMenu){
|
||||
this.onCancel(false);
|
||||
}else{
|
||||
dojo.stopEvent(evt);
|
||||
}
|
||||
break;
|
||||
case dojo.keys.TAB:
|
||||
dojo.stopEvent(evt);
|
||||
// Hmm, there's no good infrastructure to support cancel closing the whole tree
|
||||
// of menus, but it's close to an execute event, in the sense that focus is returned
|
||||
// to the previously focused node (for a context menu) or to the DropDownButton
|
||||
this.onExecute();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
_findValidItem: function(dir){
|
||||
// summary: find the next/previous item to focus on (depending on dir setting).
|
||||
|
||||
var curItem = this._focusedItem;
|
||||
if(curItem){
|
||||
curItem = dir>0 ? curItem.getNextSibling() : curItem.getPreviousSibling();
|
||||
}
|
||||
|
||||
var children = this.getChildren();
|
||||
for(var i=0; i < children.length; ++i){
|
||||
if(!curItem){
|
||||
curItem = children[(dir>0) ? 0 : (children.length-1)];
|
||||
}
|
||||
//find next/previous visible menu item, not including separators
|
||||
if(curItem._onHover && dojo.style(curItem.domNode, "display") != "none"){
|
||||
return curItem;
|
||||
}
|
||||
curItem = dir>0 ? curItem.getNextSibling() : curItem.getPreviousSibling();
|
||||
}
|
||||
},
|
||||
|
||||
_focusNeighborItem: function(dir){
|
||||
// summary: focus on the next / previous item (depending on dir setting)
|
||||
var item = this._findValidItem(dir);
|
||||
this._focusItem(item);
|
||||
},
|
||||
|
||||
_focusFirstItem: function(){
|
||||
// blur focused item to make findValidItem() find the first item in the menu
|
||||
if(this._focusedItem){
|
||||
this._blurFocusedItem();
|
||||
}
|
||||
var item = this._findValidItem(1);
|
||||
this._focusItem(item);
|
||||
},
|
||||
|
||||
_focusItem: function(/*MenuItem*/ item){
|
||||
// summary: internal function to focus a given menu item
|
||||
|
||||
if(!item || item==this._focusedItem){
|
||||
return;
|
||||
}
|
||||
|
||||
if(this._focusedItem){
|
||||
this._blurFocusedItem();
|
||||
}
|
||||
item._focus();
|
||||
this._focusedItem = item;
|
||||
},
|
||||
|
||||
onItemHover: function(/*MenuItem*/ item){
|
||||
this._focusItem(item);
|
||||
|
||||
if(this._focusedItem.popup && !this._focusedItem.disabled && !this.hover_timer){
|
||||
this.hover_timer = setTimeout(dojo.hitch(this, "_openPopup"), this.popupDelay);
|
||||
}
|
||||
},
|
||||
|
||||
_blurFocusedItem: function(){
|
||||
// summary: internal function to remove focus from the currently focused item
|
||||
if(this._focusedItem){
|
||||
// Close all popups that are open and descendants of this menu
|
||||
dijit.popup.closeTo(this);
|
||||
this._focusedItem._blur();
|
||||
this._stopPopupTimer();
|
||||
this._focusedItem = null;
|
||||
}
|
||||
},
|
||||
|
||||
onItemUnhover: function(/*MenuItem*/ item){
|
||||
//this._blurFocusedItem();
|
||||
},
|
||||
|
||||
_stopPopupTimer: function(){
|
||||
if(this.hover_timer){
|
||||
clearTimeout(this.hover_timer);
|
||||
this.hover_timer = null;
|
||||
}
|
||||
},
|
||||
|
||||
_getTopMenu: function(){
|
||||
for(var top=this; top.parentMenu; top=top.parentMenu);
|
||||
return top;
|
||||
},
|
||||
|
||||
onItemClick: function(/*Widget*/ item){
|
||||
// summary: user defined function to handle clicks on an item
|
||||
// summary: internal function for clicks
|
||||
if(item.disabled){ return false; }
|
||||
|
||||
if(item.popup){
|
||||
if(!this.is_open){
|
||||
this._openPopup();
|
||||
}
|
||||
}else{
|
||||
// before calling user defined handler, close hierarchy of menus
|
||||
// and restore focus to place it was when menu was opened
|
||||
this.onExecute();
|
||||
|
||||
// user defined handler for click
|
||||
item.onClick();
|
||||
}
|
||||
},
|
||||
|
||||
// thanks burstlib!
|
||||
_iframeContentWindow: function(/* HTMLIFrameElement */iframe_el) {
|
||||
// summary
|
||||
// returns the window reference of the passed iframe
|
||||
var win = dijit.getDocumentWindow(dijit.Menu._iframeContentDocument(iframe_el)) ||
|
||||
// Moz. TODO: is this available when defaultView isn't?
|
||||
dijit.Menu._iframeContentDocument(iframe_el)['__parent__'] ||
|
||||
(iframe_el.name && document.frames[iframe_el.name]) || null;
|
||||
return win; // Window
|
||||
},
|
||||
|
||||
_iframeContentDocument: function(/* HTMLIFrameElement */iframe_el){
|
||||
// summary
|
||||
// returns a reference to the document object inside iframe_el
|
||||
var doc = iframe_el.contentDocument // W3
|
||||
|| (iframe_el.contentWindow && iframe_el.contentWindow.document) // IE
|
||||
|| (iframe_el.name && document.frames[iframe_el.name] && document.frames[iframe_el.name].document)
|
||||
|| null;
|
||||
return doc; // HTMLDocument
|
||||
},
|
||||
|
||||
bindDomNode: function(/*String|DomNode*/ node){
|
||||
// summary: attach menu to given node
|
||||
node = dojo.byId(node);
|
||||
|
||||
//TODO: this is to support context popups in Editor. Maybe this shouldn't be in dijit.Menu
|
||||
var win = dijit.getDocumentWindow(node.ownerDocument);
|
||||
if(node.tagName.toLowerCase()=="iframe"){
|
||||
win = this._iframeContentWindow(node);
|
||||
node = dojo.withGlobal(win, dojo.body);
|
||||
}
|
||||
|
||||
// to capture these events at the top level,
|
||||
// attach to document, not body
|
||||
var cn = (node == dojo.body() ? dojo.doc : node);
|
||||
|
||||
node[this.id] = this._bindings.push([
|
||||
dojo.connect(cn, "oncontextmenu", this, "_openMyself"),
|
||||
dojo.connect(cn, "onkeydown", this, "_contextKey"),
|
||||
dojo.connect(cn, "onmousedown", this, "_contextMouse")
|
||||
]);
|
||||
},
|
||||
|
||||
unBindDomNode: function(/*String|DomNode*/ nodeName){
|
||||
// summary: detach menu from given node
|
||||
var node = dojo.byId(nodeName);
|
||||
var bid = node[this.id]-1, b = this._bindings[bid];
|
||||
dojo.forEach(b, dojo.disconnect);
|
||||
delete this._bindings[bid];
|
||||
},
|
||||
|
||||
_contextKey: function(e){
|
||||
this._contextMenuWithMouse = false;
|
||||
if (e.keyCode == dojo.keys.F10) {
|
||||
dojo.stopEvent(e);
|
||||
if (e.shiftKey && e.type=="keydown") {
|
||||
// FF: copying the wrong property from e will cause the system
|
||||
// context menu to appear in spite of stopEvent. Don't know
|
||||
// exactly which properties cause this effect.
|
||||
var _e = { target: e.target, pageX: e.pageX, pageY: e.pageY };
|
||||
_e.preventDefault = _e.stopPropagation = function(){};
|
||||
// IE: without the delay, focus work in "open" causes the system
|
||||
// context menu to appear in spite of stopEvent.
|
||||
window.setTimeout(dojo.hitch(this, function(){ this._openMyself(_e); }), 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_contextMouse: function(e){
|
||||
this._contextMenuWithMouse = true;
|
||||
},
|
||||
|
||||
_openMyself: function(/*Event*/ e){
|
||||
// summary:
|
||||
// Internal function for opening myself when the user
|
||||
// does a right-click or something similar
|
||||
|
||||
dojo.stopEvent(e);
|
||||
|
||||
// Get coordinates.
|
||||
// if we are opening the menu with the mouse or on safari open
|
||||
// the menu at the mouse cursor
|
||||
// (Safari does not have a keyboard command to open the context menu
|
||||
// and we don't currently have a reliable way to determine
|
||||
// _contextMenuWithMouse on Safari)
|
||||
var x,y;
|
||||
if(dojo.isSafari || this._contextMenuWithMouse){
|
||||
x=e.pageX;
|
||||
y=e.pageY;
|
||||
}else{
|
||||
// otherwise open near e.target
|
||||
var coords = dojo.coords(e.target, true);
|
||||
x = coords.x + 10;
|
||||
y = coords.y + 10;
|
||||
}
|
||||
|
||||
var self=this;
|
||||
var savedFocus = dijit.getFocus(this);
|
||||
function closeAndRestoreFocus(){
|
||||
// user has clicked on a menu or popup
|
||||
dijit.focus(savedFocus);
|
||||
dijit.popup.closeAll();
|
||||
}
|
||||
dijit.popup.open({
|
||||
popup: this,
|
||||
x: x,
|
||||
y: y,
|
||||
onExecute: closeAndRestoreFocus,
|
||||
onCancel: closeAndRestoreFocus,
|
||||
orient: this.isLeftToRight() ? 'L' : 'R'
|
||||
});
|
||||
this.focus();
|
||||
|
||||
this._onBlur = function(){
|
||||
// Usually the parent closes the child widget but if this is a context
|
||||
// menu then there is no parent
|
||||
dijit.popup.closeAll();
|
||||
// don't try to restor focus; user has clicked another part of the screen
|
||||
// and set focus there
|
||||
}
|
||||
},
|
||||
|
||||
onOpen: function(/*Event*/ e){
|
||||
// summary
|
||||
// Open menu relative to the mouse
|
||||
this.isShowingNow = true;
|
||||
},
|
||||
|
||||
onClose: function(){
|
||||
// summary: callback when this menu is closed
|
||||
this._stopPopupTimer();
|
||||
this.parentMenu = null;
|
||||
this.isShowingNow = false;
|
||||
this.currentPopup = null;
|
||||
if(this._focusedItem){
|
||||
this._blurFocusedItem();
|
||||
}
|
||||
},
|
||||
|
||||
_openPopup: function(){
|
||||
// summary: open the popup to the side of the current menu item
|
||||
this._stopPopupTimer();
|
||||
var from_item = this._focusedItem;
|
||||
var popup = from_item.popup;
|
||||
|
||||
if(popup.isShowingNow){ return; }
|
||||
popup.parentMenu = this;
|
||||
var self = this;
|
||||
dijit.popup.open({
|
||||
parent: this,
|
||||
popup: popup,
|
||||
around: from_item.arrowCell,
|
||||
orient: this.isLeftToRight() ? {'TR': 'TL', 'TL': 'TR'} : {'TL': 'TR', 'TR': 'TL'},
|
||||
submenu: true,
|
||||
onCancel: function(){
|
||||
// called when the child menu is canceled
|
||||
dijit.popup.close();
|
||||
self._focusedItem._focus(); // put focus back on my node
|
||||
self.currentPopup = null;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
this.currentPopup = popup;
|
||||
|
||||
if(popup.focus){
|
||||
popup.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
dojo.declare(
|
||||
"dijit.MenuItem",
|
||||
[dijit._Widget, dijit._Templated, dijit._Contained],
|
||||
{
|
||||
// summary
|
||||
// A line item in a Menu2
|
||||
|
||||
// Make 3 columns
|
||||
// icon, label, and expand arrow (BiDi-dependent) indicating sub-menu
|
||||
templateString:
|
||||
'<tr class="dijitReset dijitMenuItem"'
|
||||
+'dojoAttachEvent="onmouseover:_onHover,onmouseout:_onUnhover,ondijitclick:_onClick">'
|
||||
+'<td class="dijitReset"><div class="dijitMenuItemIcon ${iconClass}"></div></td>'
|
||||
+'<td tabIndex="-1" class="dijitReset dijitMenuItemLabel" dojoAttachPoint="containerNode" waiRole="menuitem"></td>'
|
||||
+'<td class="dijitReset" dojoAttachPoint="arrowCell">'
|
||||
+'<div class="dijitMenuExpand" dojoAttachPoint="expand" style="display:none">'
|
||||
+'<span class="dijit_a11y dijitInline dijitArrowNode dijitMenuExpandInner">+</span>'
|
||||
+'</div>'
|
||||
+'</td>'
|
||||
+'</tr>',
|
||||
|
||||
// iconSrc: String
|
||||
// path to icon to display to the left of the menu text
|
||||
iconSrc: '',
|
||||
|
||||
// label: String
|
||||
// menu text
|
||||
label: '',
|
||||
|
||||
// iconClass: String
|
||||
// class to apply to div in button to make it display an icon
|
||||
iconClass: "",
|
||||
|
||||
// disabled: Boolean
|
||||
// if true, the menu item is disabled
|
||||
// if false, the menu item is enabled
|
||||
disabled: false,
|
||||
|
||||
postCreate: function(){
|
||||
dojo.setSelectable(this.domNode, false);
|
||||
this.setDisabled(this.disabled);
|
||||
if(this.label){
|
||||
this.containerNode.innerHTML=this.label;
|
||||
}
|
||||
},
|
||||
|
||||
_onHover: function(){
|
||||
// summary: callback when mouse is moved onto menu item
|
||||
this.getParent().onItemHover(this);
|
||||
},
|
||||
|
||||
_onUnhover: function(){
|
||||
// summary: callback when mouse is moved off of menu item
|
||||
// if we are unhovering the currently selected item
|
||||
// then unselect it
|
||||
this.getParent().onItemUnhover(this);
|
||||
},
|
||||
|
||||
_onClick: function(evt){
|
||||
this.getParent().onItemClick(this);
|
||||
dojo.stopEvent(evt);
|
||||
},
|
||||
|
||||
onClick: function() {
|
||||
// summary
|
||||
// User defined function to handle clicks
|
||||
},
|
||||
|
||||
_focus: function(){
|
||||
dojo.addClass(this.domNode, 'dijitMenuItemHover');
|
||||
try{
|
||||
dijit.focus(this.containerNode);
|
||||
}catch(e){
|
||||
// this throws on IE (at least) in some scenarios
|
||||
}
|
||||
},
|
||||
|
||||
_blur: function(){
|
||||
dojo.removeClass(this.domNode, 'dijitMenuItemHover');
|
||||
},
|
||||
|
||||
setDisabled: function(/*Boolean*/ value){
|
||||
// summary: enable or disable this menu item
|
||||
this.disabled = value;
|
||||
dojo[value ? "addClass" : "removeClass"](this.domNode, 'dijitMenuItemDisabled');
|
||||
dijit.wai.setAttr(this.containerNode, 'waiState', 'disabled', value ? 'true' : 'false');
|
||||
}
|
||||
});
|
||||
|
||||
dojo.declare(
|
||||
"dijit.PopupMenuItem",
|
||||
dijit.MenuItem,
|
||||
{
|
||||
_fillContent: function(){
|
||||
// my inner HTML contains both the menu item text and a popup widget, like
|
||||
// <div dojoType="dijit.PopupMenuItem">
|
||||
// <span>pick me</span>
|
||||
// <popup> ... </popup>
|
||||
// </div>
|
||||
// the first part holds the menu item text and the second part is the popup
|
||||
if(this.srcNodeRef){
|
||||
var nodes = dojo.query("*", this.srcNodeRef);
|
||||
dijit.PopupMenuItem.superclass._fillContent.call(this, nodes[0]);
|
||||
|
||||
// save pointer to srcNode so we can grab the drop down widget after it's instantiated
|
||||
this.dropDownContainer = this.srcNodeRef;
|
||||
}
|
||||
},
|
||||
|
||||
startup: function(){
|
||||
// we didn't copy the dropdown widget from the this.srcNodeRef, so it's in no-man's
|
||||
// land now. move it to document.body.
|
||||
if(!this.popup){
|
||||
var node = dojo.query("[widgetId]", this.dropDownContainer)[0];
|
||||
this.popup = dijit.byNode(node);
|
||||
}
|
||||
dojo.body().appendChild(this.popup.domNode);
|
||||
|
||||
this.popup.domNode.style.display="none";
|
||||
dojo.addClass(this.expand, "dijitMenuExpandEnabled");
|
||||
dojo.style(this.expand, "display", "");
|
||||
dijit.wai.setAttr(this.containerNode, "waiState", "haspopup", "true");
|
||||
}
|
||||
});
|
||||
|
||||
dojo.declare(
|
||||
"dijit.MenuSeparator",
|
||||
[dijit._Widget, dijit._Templated, dijit._Contained],
|
||||
{
|
||||
// summary
|
||||
// A line between two menu items
|
||||
|
||||
templateString: '<tr class="dijitMenuSeparator"><td colspan=3>'
|
||||
+'<div class="dijitMenuSeparatorTop"></div>'
|
||||
+'<div class="dijitMenuSeparatorBottom"></div>'
|
||||
+'</td></tr>',
|
||||
|
||||
postCreate: function(){
|
||||
dojo.setSelectable(this.domNode, false);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
90
spring-faces/src/main/java/META-INF/dijit/ProgressBar.js
Normal file
90
spring-faces/src/main/java/META-INF/dijit/ProgressBar.js
Normal file
@@ -0,0 +1,90 @@
|
||||
if(!dojo._hasResource["dijit.ProgressBar"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.ProgressBar"] = true;
|
||||
dojo.provide("dijit.ProgressBar");
|
||||
|
||||
dojo.require("dojo.fx");
|
||||
dojo.require("dojo.number");
|
||||
|
||||
dojo.require("dijit._Widget");
|
||||
dojo.require("dijit._Templated");
|
||||
|
||||
dojo.declare("dijit.ProgressBar", [dijit._Widget, dijit._Templated], {
|
||||
// summary:
|
||||
// a progress widget
|
||||
//
|
||||
// usage:
|
||||
// <div dojoType="ProgressBar"
|
||||
// places="0"
|
||||
// progress="..." maximum="..."></div>
|
||||
|
||||
// progress: String (Percentage or Number)
|
||||
// initial progress value.
|
||||
// with "%": percentage value, 0% <= progress <= 100%
|
||||
// or without "%": absolute value, 0 <= progress <= maximum
|
||||
progress: "0",
|
||||
|
||||
// maximum: Float
|
||||
// max sample number
|
||||
maximum: 100,
|
||||
|
||||
// places: Number
|
||||
// number of places to show in values; 0 by default
|
||||
places: 0,
|
||||
|
||||
// indeterminate: Boolean
|
||||
// false: show progress
|
||||
// true: show that a process is underway but that the progress is unknown
|
||||
indeterminate: false,
|
||||
|
||||
templateString:"<div class=\"dijitProgressBar dijitProgressBarEmpty\"\n\t><div waiRole=\"progressbar\" tabindex=\"0\" dojoAttachPoint=\"internalProgress\" class=\"dijitProgressBarFull\"\n\t\t><div class=\"dijitProgressBarTile\"></div\n\t\t><span style=\"visibility:hidden\"> </span\n\t></div\n\t><div dojoAttachPoint=\"label\" class=\"dijitProgressBarLabel\"> </div\n\t><img dojoAttachPoint=\"inteterminateHighContrastImage\" class=\"dijitProgressBarIndeterminateHighContrastImage\"\n\t></img\n></div>\n",
|
||||
|
||||
_indeterminateHighContrastImagePath:
|
||||
dojo.moduleUrl("dijit", "themes/a11y/indeterminate_progress.gif"),
|
||||
|
||||
// public functions
|
||||
postCreate: function(){
|
||||
dijit.ProgressBar.superclass.postCreate.apply(this, arguments);
|
||||
|
||||
this.inteterminateHighContrastImage.setAttribute("src",
|
||||
this._indeterminateHighContrastImagePath);
|
||||
|
||||
this.update();
|
||||
},
|
||||
|
||||
update: function(/*Object?*/attributes){
|
||||
// summary: update progress information
|
||||
//
|
||||
// attributes: may provide progress and/or maximum properties on this parameter,
|
||||
// see attribute specs for details.
|
||||
dojo.mixin(this, attributes||{});
|
||||
var percent = 1, classFunc;
|
||||
if(this.indeterminate){
|
||||
classFunc = "addClass";
|
||||
dijit.wai.removeAttr(this.internalProgress, "waiState", "valuenow");
|
||||
}else{
|
||||
classFunc = "removeClass";
|
||||
if(String(this.progress).indexOf("%") != -1){
|
||||
percent = Math.min(parseFloat(this.progress)/100, 1);
|
||||
this.progress = percent * this.maximum;
|
||||
}else{
|
||||
this.progress = Math.min(this.progress, this.maximum);
|
||||
percent = this.progress / this.maximum;
|
||||
}
|
||||
var text = this.report(percent);
|
||||
this.label.firstChild.nodeValue = text;
|
||||
dijit.wai.setAttr(this.internalProgress, "waiState", "valuenow", text);
|
||||
}
|
||||
dojo[classFunc](this.domNode, "dijitProgressBarIndeterminate");
|
||||
this.internalProgress.style.width = (percent * 100) + "%";
|
||||
this.onChange();
|
||||
},
|
||||
|
||||
report: function(/*float*/percent){
|
||||
// Generates message to show; may be overridden by user
|
||||
return dojo.number.format(percent, {type: "percent", places: this.places, locale: this.lang});
|
||||
},
|
||||
|
||||
onChange: function(){}
|
||||
});
|
||||
|
||||
}
|
||||
129
spring-faces/src/main/java/META-INF/dijit/TitlePane.js
Normal file
129
spring-faces/src/main/java/META-INF/dijit/TitlePane.js
Normal file
@@ -0,0 +1,129 @@
|
||||
if(!dojo._hasResource["dijit.TitlePane"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.TitlePane"] = true;
|
||||
dojo.provide("dijit.TitlePane");
|
||||
|
||||
dojo.require("dojo.fx");
|
||||
|
||||
dojo.require("dijit._Templated");
|
||||
dojo.require("dijit.layout.ContentPane");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.TitlePane",
|
||||
[dijit.layout.ContentPane, dijit._Templated],
|
||||
{
|
||||
// summary
|
||||
// A pane with a title on top, that can be opened or collapsed.
|
||||
|
||||
// title: String
|
||||
// Title of the pane
|
||||
title: "",
|
||||
|
||||
// open: Boolean
|
||||
// Whether pane is opened or closed.
|
||||
open: true,
|
||||
|
||||
// duration: Integer
|
||||
// milliseconds to fade in/fade out
|
||||
duration: 250,
|
||||
|
||||
templateString:"<div class=\"dijitTitlePane\">\n\t<div dojoAttachEvent=\"onclick:toggle,onkeypress: _onTitleKey\" tabindex=\"0\"\n\t\t\twaiRole=\"button\" class=\"dijitTitlePaneTitle\" dojoAttachPoint=\"focusNode\">\n\t\t<span dojoAttachPoint=\"arrowNode\" class=\"dijitInline dijitArrowNode\"><span dojoAttachPoint=\"arrowNodeInner\" class=\"dijit_a11y dijitArrowNodeInner\"></span></span>\n\t\t<span dojoAttachPoint=\"titleNode\" class=\"dijitInlineBox dijitTitleNode\"></span>\n\t</div>\n\t<div class=\"dijitTitlePaneContentOuter\" dojoAttachPoint=\"hideNode\">\n\t\t<div class=\"dijitReset\" dojoAttachPoint=\"wipeNode\">\n\t\t\t<div class=\"dijitTitlePaneContentInner\" dojoAttachPoint=\"containerNode\" waiRole=\"region\" tabindex=\"-1\">\n\t\t\t\t<!-- nested divs because wipeIn()/wipeOut() doesn't work right on node w/padding etc. Put padding on inner div. -->\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</div>\n",
|
||||
|
||||
postCreate: function(){
|
||||
this.setTitle(this.title);
|
||||
if(!this.open){
|
||||
this.hideNode.style.display = this.wipeNode.style.display = "none";
|
||||
}
|
||||
this._setCss();
|
||||
dojo.setSelectable(this.titleNode, false);
|
||||
dijit.TitlePane.superclass.postCreate.apply(this, arguments);
|
||||
dijit.wai.setAttr(this.containerNode, "waiState", "titleledby", this.titleNode.id);
|
||||
dijit.wai.setAttr(this.focusNode, "waiState", "haspopup", "true");
|
||||
|
||||
// setup open/close animations
|
||||
var hideNode = this.hideNode, wipeNode = this.wipeNode;
|
||||
this._wipeIn = dojo.fx.wipeIn({
|
||||
node: this.wipeNode,
|
||||
duration: this.duration,
|
||||
beforeBegin: function(){
|
||||
hideNode.style.display="";
|
||||
}
|
||||
});
|
||||
this._wipeOut = dojo.fx.wipeOut({
|
||||
node: this.wipeNode,
|
||||
duration: this.duration,
|
||||
onEnd: function(){
|
||||
hideNode.style.display="none";
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
setContent: function(content){
|
||||
// summary
|
||||
// Typically called when an href is loaded. Our job is to make the animation smooth
|
||||
if(this._wipeOut.status() == "playing"){
|
||||
// we are currently *closing* the pane, so just let that continue
|
||||
dijit.layout.ContentPane.prototype.setContent.apply(this, content);
|
||||
}else{
|
||||
if(this._wipeIn.status() == "playing"){
|
||||
this._wipeIn.stop();
|
||||
}
|
||||
|
||||
// freeze container at current height so that adding new content doesn't make it jump
|
||||
dojo.marginBox(this.wipeNode, {h: dojo.marginBox(this.wipeNode).h});
|
||||
|
||||
// add the new content (erasing the old content, if any)
|
||||
dijit.layout.ContentPane.prototype.setContent.apply(this, arguments);
|
||||
|
||||
// call _wipeIn.play() to animate from current height to new height
|
||||
this._wipeIn.play();
|
||||
}
|
||||
},
|
||||
|
||||
toggle: function(){
|
||||
// summary: switches between opened and closed state
|
||||
dojo.forEach([this._wipeIn, this._wipeOut], function(animation){
|
||||
if(animation.status() == "playing"){
|
||||
animation.stop();
|
||||
}
|
||||
});
|
||||
|
||||
this[this.open ? "_wipeOut" : "_wipeIn"].play();
|
||||
this.open =! this.open;
|
||||
|
||||
// load content (if this is the first time we are opening the TitlePane
|
||||
// and content is specified as an href, or we have setHref when hidden)
|
||||
this._loadCheck();
|
||||
|
||||
this._setCss();
|
||||
},
|
||||
|
||||
_setCss: function(){
|
||||
var classes = ["dijitClosed", "dijitOpen"];
|
||||
var boolIndex = this.open;
|
||||
dojo.removeClass(this.focusNode, classes[!boolIndex+0]);
|
||||
this.focusNode.className += " " + classes[boolIndex+0];
|
||||
|
||||
// provide a character based indicator for images-off mode
|
||||
this.arrowNodeInner.innerHTML = this.open ? "-" : "+";
|
||||
},
|
||||
|
||||
_onTitleKey: function(/*Event*/ e){
|
||||
// summary: callback when user hits a key
|
||||
if(e.keyCode == dojo.keys.ENTER || e.charCode == dojo.keys.SPACE){
|
||||
this._onTitleClick();
|
||||
}
|
||||
else if(e.keyCode == dojo.keys.DOWN_ARROW){
|
||||
if(this.open){
|
||||
this.containerNode.focus();
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
setTitle: function(/*String*/ title){
|
||||
// summary: sets the text of the title
|
||||
this.titleNode.innerHTML=title;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
33
spring-faces/src/main/java/META-INF/dijit/Toolbar.js
Normal file
33
spring-faces/src/main/java/META-INF/dijit/Toolbar.js
Normal file
@@ -0,0 +1,33 @@
|
||||
if(!dojo._hasResource["dijit.Toolbar"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.Toolbar"] = true;
|
||||
dojo.provide("dijit.Toolbar");
|
||||
|
||||
dojo.require("dijit._Widget");
|
||||
dojo.require("dijit._Container");
|
||||
dojo.require("dijit._Templated");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.Toolbar",
|
||||
[dijit._Widget, dijit._Templated, dijit._Container],
|
||||
{
|
||||
templateString:
|
||||
'<div class="dijit dijitToolbar" waiRole="toolbar" tabIndex="-1" dojoAttachPoint="containerNode">' +
|
||||
// '<table style="table-layout: fixed" class="dijitReset dijitToolbarTable">' + // factor out style
|
||||
// '<tr class="dijitReset" dojoAttachPoint="containerNode"></tr>'+
|
||||
// '</table>' +
|
||||
'</div>'
|
||||
}
|
||||
);
|
||||
|
||||
// Combine with dijit.MenuSeparator??
|
||||
dojo.declare(
|
||||
"dijit.ToolbarSeparator",
|
||||
[ dijit._Widget, dijit._Templated ],
|
||||
{
|
||||
// summary
|
||||
// A line between two menu items
|
||||
templateString: '<div class="dijitToolbarSeparator dijitInline"></div>',
|
||||
postCreate: function(){ dojo.setSelectable(this.domNode, false); }
|
||||
});
|
||||
|
||||
}
|
||||
188
spring-faces/src/main/java/META-INF/dijit/Tooltip.js
Normal file
188
spring-faces/src/main/java/META-INF/dijit/Tooltip.js
Normal file
@@ -0,0 +1,188 @@
|
||||
if(!dojo._hasResource["dijit.Tooltip"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.Tooltip"] = true;
|
||||
dojo.provide("dijit.Tooltip");
|
||||
|
||||
dojo.require("dijit._Widget");
|
||||
dojo.require("dijit._Templated");
|
||||
|
||||
dojo.declare(
|
||||
"dijit._MasterTooltip",
|
||||
[dijit._Widget, dijit._Templated],
|
||||
{
|
||||
// summary
|
||||
// Internal widget that holds the actual tooltip markup,
|
||||
// which occurs once per page.
|
||||
// Called by Tooltip widgets which are just containers to hold
|
||||
// the markup
|
||||
|
||||
// duration: Integer
|
||||
// Milliseconds to fade in/fade out
|
||||
duration: 200,
|
||||
|
||||
templateString:"<div class=\"dijitTooltip dijitTooltipLeft\" id=\"dojoTooltip\">\n\t<div class=\"dijitTooltipContainer dijitTooltipContents\" dojoAttachPoint=\"containerNode\" waiRole='alert'></div>\n\t<div class=\"dijitTooltipConnector\"></div>\n</div>\n",
|
||||
|
||||
postCreate: function(){
|
||||
dojo.body().appendChild(this.domNode);
|
||||
|
||||
this.bgIframe = new dijit.BackgroundIframe(this.domNode);
|
||||
|
||||
// Setup fade-in and fade-out functions.
|
||||
this.fadeIn = dojo.fadeIn({ node: this.domNode, duration: this.duration, onEnd: dojo.hitch(this, "_onShow") }),
|
||||
this.fadeOut = dojo.fadeOut({ node: this.domNode, duration: this.duration, onEnd: dojo.hitch(this, "_onHide") });
|
||||
|
||||
},
|
||||
|
||||
show: function(/*String*/ innerHTML, /*DomNode*/ aroundNode){
|
||||
// summary:
|
||||
// Display tooltip w/specified contents to right specified node
|
||||
// (To left if there's no space on the right, or if LTR==right)
|
||||
|
||||
if(this.fadeOut.status() == "playing"){
|
||||
// previous tooltip is being hidden; wait until the hide completes then show new one
|
||||
this._onDeck=arguments;
|
||||
return;
|
||||
}
|
||||
this.containerNode.innerHTML=innerHTML;
|
||||
|
||||
// Firefox bug. when innerHTML changes to be shorter than previous
|
||||
// one, the node size will not be updated until it moves.
|
||||
this.domNode.style.top = (this.domNode.offsetTop + 1) + "px";
|
||||
|
||||
// position the element and change CSS according to position
|
||||
var align = this.isLeftToRight() ? {'BR': 'BL', 'BL': 'BR'} : {'BL': 'BR', 'BR': 'BL'};
|
||||
var pos = dijit.placeOnScreenAroundElement(this.domNode, aroundNode, align);
|
||||
this.domNode.className="dijitTooltip dijitTooltip" + (pos.corner=='BL' ? "Right" : "Left");
|
||||
|
||||
// show it
|
||||
dojo.style(this.domNode, "opacity", 0);
|
||||
this.fadeIn.play();
|
||||
this.isShowingNow = true;
|
||||
},
|
||||
|
||||
_onShow: function(){
|
||||
if(dojo.isIE){
|
||||
// the arrow won't show up on a node w/an opacity filter
|
||||
this.domNode.style.filter="";
|
||||
}
|
||||
},
|
||||
|
||||
hide: function(){
|
||||
// summary: hide the tooltip
|
||||
if(this._onDeck){
|
||||
// this hide request is for a show() that hasn't even started yet;
|
||||
// just cancel the pending show()
|
||||
this._onDeck=null;
|
||||
return;
|
||||
}
|
||||
this.fadeIn.stop();
|
||||
this.isShowingNow = false;
|
||||
this.fadeOut.play();
|
||||
},
|
||||
|
||||
_onHide: function(){
|
||||
this.domNode.style.cssText=""; // to position offscreen again
|
||||
if(this._onDeck){
|
||||
// a show request has been queued up; do it now
|
||||
this.show.apply(this, this._onDeck);
|
||||
this._onDeck=null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
// Make a single tooltip markup on the page that is reused as appropriate
|
||||
dojo.addOnLoad(function(){
|
||||
dijit.MasterTooltip = new dijit._MasterTooltip();
|
||||
});
|
||||
|
||||
dojo.declare(
|
||||
"dijit.Tooltip",
|
||||
dijit._Widget,
|
||||
{
|
||||
// summary
|
||||
// Pops up a tooltip (a help message) when you hover over a node.
|
||||
|
||||
// label: String
|
||||
// Text to display in the tooltip.
|
||||
// Specified as innerHTML when creating the widget from markup.
|
||||
label: "",
|
||||
|
||||
// showDelay: Integer
|
||||
// Number of milliseconds to wait after hovering over/focusing on the object, before
|
||||
// the tooltip is displayed.
|
||||
showDelay: 400,
|
||||
|
||||
// connectId: String
|
||||
// Id of domNode to attach the tooltip to.
|
||||
// (When user hovers over specified dom node, the tooltip will appear.)
|
||||
connectId: "",
|
||||
|
||||
postCreate: function(){
|
||||
this.srcNodeRef.style.display="none";
|
||||
|
||||
this._connectNode = dojo.byId(this.connectId);
|
||||
|
||||
dojo.forEach(["onMouseOver", "onHover", "onMouseOut", "onUnHover"], function(event){
|
||||
this.connect(this._connectNode, event.toLowerCase(), "_"+event);
|
||||
}, this);
|
||||
},
|
||||
|
||||
_onMouseOver: function(/*Event*/ e){
|
||||
this._onHover(e);
|
||||
},
|
||||
|
||||
_onMouseOut: function(/*Event*/ e){
|
||||
if(dojo.isDescendant(e.relatedTarget, this._connectNode)){
|
||||
// false event; just moved from target to target child; ignore.
|
||||
return;
|
||||
}
|
||||
this._onUnHover(e);
|
||||
},
|
||||
|
||||
_onHover: function(/*Event*/ e){
|
||||
if(this._hover){ return; }
|
||||
this._hover=true;
|
||||
// If tooltip not showing yet then set a timer to show it shortly
|
||||
if(!this.isShowingNow && !this._showTimer){
|
||||
this._showTimer = setTimeout(dojo.hitch(this, "open"), this.showDelay);
|
||||
}
|
||||
},
|
||||
|
||||
_onUnHover: function(/*Event*/ e){
|
||||
if(!this._hover){ return; }
|
||||
this._hover=false;
|
||||
|
||||
if(this._showTimer){
|
||||
clearTimeout(this._showTimer);
|
||||
delete this._showTimer;
|
||||
}else{
|
||||
this.close();
|
||||
}
|
||||
},
|
||||
|
||||
open: function(){
|
||||
// summary: display the tooltip; usually not called directly.
|
||||
if(this.isShowingNow){ return; }
|
||||
if(this._showTimer){
|
||||
clearTimeout(this._showTimer);
|
||||
delete this._showTimer;
|
||||
}
|
||||
dijit.MasterTooltip.show(this.label || this.domNode.innerHTML, this._connectNode);
|
||||
this.isShowingNow = true;
|
||||
},
|
||||
|
||||
close: function(){
|
||||
// summary: hide the tooltip; usually not called directly.
|
||||
if(!this.isShowingNow){ return; }
|
||||
dijit.MasterTooltip.hide();
|
||||
this.isShowingNow = false;
|
||||
},
|
||||
|
||||
uninitialize: function(){
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
500
spring-faces/src/main/java/META-INF/dijit/Tree.js
Normal file
500
spring-faces/src/main/java/META-INF/dijit/Tree.js
Normal file
@@ -0,0 +1,500 @@
|
||||
if(!dojo._hasResource["dijit.Tree"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.Tree"] = true;
|
||||
dojo.provide("dijit.Tree");
|
||||
|
||||
dojo.require("dojo.fx");
|
||||
|
||||
dojo.require("dijit._Widget");
|
||||
dojo.require("dijit._Templated");
|
||||
dojo.require("dijit._Container");
|
||||
dojo.require("dijit._tree.Controller");
|
||||
|
||||
dojo.declare(
|
||||
"dijit._TreeBase",
|
||||
[dijit._Widget, dijit._Templated, dijit._Container, dijit._Contained],
|
||||
{
|
||||
// summary:
|
||||
// Base class for Tree and _TreeNode
|
||||
|
||||
// state: String
|
||||
// dynamic loading-related stuff.
|
||||
// When an empty folder node appears, it is "UNCHECKED" first,
|
||||
// then after dojo.data query it becomes "LOADING" and, finally "LOADED"
|
||||
state: "UNCHECKED",
|
||||
locked: false,
|
||||
|
||||
lock: function(){
|
||||
// summary: lock this node (and it's descendants) while a delete is taking place?
|
||||
this.locked = true;
|
||||
},
|
||||
unlock: function(){
|
||||
if(!this.locked){
|
||||
//dojo.debug((new Error()).stack);
|
||||
throw new Error(this.declaredClass+" unlock: not locked");
|
||||
}
|
||||
this.locked = false;
|
||||
},
|
||||
|
||||
isLocked: function(){
|
||||
// summary: can this node be modified?
|
||||
// returns: false if this node or any of it's ancestors are locked
|
||||
var node = this;
|
||||
while(true){
|
||||
if(node.lockLevel){
|
||||
return true;
|
||||
}
|
||||
if(!node.getParent() || node.isTree){
|
||||
break;
|
||||
}
|
||||
node = node.getParent();
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
setChildren: function(/* Object[] */ childrenArray){
|
||||
// summary:
|
||||
// Sets the children of this node.
|
||||
// Sets this.isFolder based on whether or not there are children
|
||||
// Takes array of objects like: {label: ...} (_TreeNode options basically)
|
||||
// See parameters of _TreeNode for details.
|
||||
|
||||
this.destroyDescendants();
|
||||
|
||||
this.state = "LOADED";
|
||||
var nodeMap= {};
|
||||
if(childrenArray && childrenArray.length > 0){
|
||||
this.isFolder = true;
|
||||
if(!this.containerNode){ // maybe this node was unfolderized and still has container
|
||||
this.containerNode = this.tree.containerNodeTemplate.cloneNode(true);
|
||||
this.domNode.appendChild(this.containerNode);
|
||||
}
|
||||
|
||||
// Create _TreeNode widget for each specified tree node
|
||||
dojo.forEach(childrenArray, function(childParams){
|
||||
var child = new dijit._TreeNode(dojo.mixin({
|
||||
tree: this.tree,
|
||||
label: this.tree.store.getLabel(childParams.item)
|
||||
}, childParams));
|
||||
this.addChild(child);
|
||||
nodeMap[this.tree.store.getIdentity(childParams.item)] = child;
|
||||
}, this);
|
||||
|
||||
// note that updateLayout() needs to be called on each child after
|
||||
// _all_ the children exist
|
||||
dojo.forEach(this.getChildren(), function(child, idx){
|
||||
child._updateLayout();
|
||||
});
|
||||
|
||||
}else{
|
||||
this.isFolder=false;
|
||||
}
|
||||
|
||||
if(this.isTree){
|
||||
// put first child in tab index if one exists.
|
||||
var fc = this.getChildren()[0];
|
||||
var tabnode = fc ? fc.labelNode : this.domNode;
|
||||
tabnode.setAttribute("tabIndex", "0");
|
||||
}
|
||||
|
||||
return nodeMap;
|
||||
},
|
||||
|
||||
addChildren: function(/* object[] */ childrenArray){
|
||||
// summary:
|
||||
// adds the children to this node.
|
||||
// Takes array of objects like: {label: ...} (_TreeNode options basically)
|
||||
|
||||
// See parameters of _TreeNode for details.
|
||||
var nodeMap = {};
|
||||
if (childrenArray && childrenArray.length > 0){
|
||||
dojo.forEach(childrenArray, function(childParams){
|
||||
var child = new dijit._TreeNode(
|
||||
dojo.mixin({
|
||||
tree: this.tree,
|
||||
label: this.tree.store.getLabel(childParams.item)
|
||||
}, childParams)
|
||||
);
|
||||
this.addChild(child);
|
||||
nodeMap[this.tree.store.getIdentity(childParams.item)] = child;
|
||||
}, this);
|
||||
|
||||
dojo.forEach(this.getChildren(), function(child, idx){
|
||||
child._updateLayout();
|
||||
});
|
||||
}
|
||||
|
||||
return nodeMap;
|
||||
},
|
||||
|
||||
deleteNode: function(/* treeNode */ node) {
|
||||
node.destroy();
|
||||
|
||||
dojo.forEach(this.getChildren(), function(child, idx){
|
||||
child._updateLayout();
|
||||
});
|
||||
},
|
||||
|
||||
makeFolder: function() {
|
||||
//summary: if this node wasn't already a folder, turn it into one and call _setExpando()
|
||||
this.isFolder=true;
|
||||
this._setExpando(false);
|
||||
}
|
||||
});
|
||||
|
||||
dojo.declare(
|
||||
"dijit.Tree",
|
||||
dijit._TreeBase,
|
||||
{
|
||||
// summary
|
||||
// Tree view does all the drawing, visual node management etc.
|
||||
// Throws events about clicks on it, so someone may catch them and process
|
||||
// Events:
|
||||
// afterTreeCreate,
|
||||
// beforeTreeDestroy,
|
||||
// execute : for clicking the label, or hitting the enter key when focused on the label,
|
||||
// toggleOpen : for clicking the expando key (toggles hide/collapse),
|
||||
// previous : go to previous visible node,
|
||||
// next : go to next visible node,
|
||||
// zoomIn : go to child nodes,
|
||||
// zoomOut : go to parent node
|
||||
|
||||
// store: String||dojo.data.Store
|
||||
// The store to get data to display in the tree
|
||||
store: null,
|
||||
|
||||
// query: String
|
||||
// query to get top level node(s) of tree (ex: {type:'continent'})
|
||||
query: null,
|
||||
|
||||
// childrenAttr: String
|
||||
// name of attribute that holds children of a tree node
|
||||
childrenAttr: "children",
|
||||
|
||||
templateString:"<div class=\"dijitTreeContainer\" style=\"\" waiRole=\"tree\"\n\tdojoAttachEvent=\"onclick:_onClick,onkeypress:_onKeyPress\"\n></div>\n",
|
||||
|
||||
isExpanded: true, // consider this "root node" to be always expanded
|
||||
|
||||
isTree: true,
|
||||
|
||||
_publish: function(/*String*/ topicName, /*Object*/ message){
|
||||
// summary:
|
||||
// Publish a message for this widget/topic
|
||||
dojo.publish(this.id, [dojo.mixin({tree: this, event: topicName}, message||{})]);
|
||||
},
|
||||
|
||||
postMixInProperties: function(){
|
||||
this.tree = this;
|
||||
|
||||
// setup table mapping keys to events
|
||||
var keyTopicMap = {};
|
||||
keyTopicMap[dojo.keys.ENTER]="execute";
|
||||
keyTopicMap[dojo.keys.LEFT_ARROW]="zoomOut";
|
||||
keyTopicMap[dojo.keys.RIGHT_ARROW]="zoomIn";
|
||||
keyTopicMap[dojo.keys.UP_ARROW]="previous";
|
||||
keyTopicMap[dojo.keys.DOWN_ARROW]="next";
|
||||
keyTopicMap[dojo.keys.HOME]="first";
|
||||
keyTopicMap[dojo.keys.END]="last";
|
||||
this._keyTopicMap = keyTopicMap;
|
||||
},
|
||||
|
||||
postCreate: function(){
|
||||
this.containerNode = this.domNode;
|
||||
|
||||
// make template for container node (we will clone this and insert it into
|
||||
// any nodes that have children)
|
||||
var div = document.createElement('div');
|
||||
div.style.display = 'none';
|
||||
div.className = "dijitTreeContainer";
|
||||
dijit.wai.setAttr(div, "waiRole", "role", "presentation");
|
||||
this.containerNodeTemplate = div;
|
||||
|
||||
|
||||
// start the controller, passing in the store
|
||||
this._controller = new dijit._tree.DataController(
|
||||
{
|
||||
store: this.store,
|
||||
treeId: this.id,
|
||||
query: this.query,
|
||||
childrenAttr: this.childrenAttr
|
||||
}
|
||||
);
|
||||
|
||||
this._publish("afterTreeCreate");
|
||||
},
|
||||
|
||||
destroy: function(){
|
||||
// publish destruction event so that any listeners should stop listening
|
||||
this._publish("beforeTreeDestroy");
|
||||
return dijit._Widget.prototype.destroy.apply(this, arguments);
|
||||
},
|
||||
|
||||
toString: function(){
|
||||
return "["+this.declaredClass+" ID:"+this.id+"]";
|
||||
},
|
||||
|
||||
getIconClass: function(/*dojo.data.Item*/ item){
|
||||
// summary: user overridable class to return CSS class name to display icon
|
||||
},
|
||||
|
||||
_domElement2TreeNode: function(/*DomNode*/ domElement){
|
||||
var ret;
|
||||
do{
|
||||
ret=dijit.byNode(domElement);
|
||||
}while(!ret && (domElement = domElement.parentNode));
|
||||
return ret;
|
||||
},
|
||||
|
||||
_onClick: function(/*Event*/ e){
|
||||
// summary: translates click events into commands for the controller to process
|
||||
var domElement = e.target;
|
||||
|
||||
// find node
|
||||
var nodeWidget = this._domElement2TreeNode(domElement);
|
||||
if(!nodeWidget || !nodeWidget.isTreeNode){
|
||||
return;
|
||||
}
|
||||
|
||||
if(domElement == nodeWidget.expandoNode ||
|
||||
domElement == nodeWidget.expandoNodeText){
|
||||
// expando node was clicked
|
||||
if(nodeWidget.isFolder){
|
||||
this._publish("toggleOpen", {node:nodeWidget});
|
||||
}
|
||||
}else{
|
||||
this._publish("execute", { item: nodeWidget.item, node: nodeWidget} );
|
||||
this.onClick(nodeWidget.item, nodeWidget);
|
||||
}
|
||||
dojo.stopEvent(e);
|
||||
},
|
||||
|
||||
onClick: function(/* dojo.data */ item){
|
||||
// summary: user overridable function
|
||||
console.log("default onclick handler", item);
|
||||
},
|
||||
|
||||
_onKeyPress: function(/*Event*/ e){
|
||||
// summary: translates keypress events into commands for the controller
|
||||
if(e.altKey){ return; }
|
||||
var treeNode = this._domElement2TreeNode(e.target);
|
||||
if(!treeNode){ return; }
|
||||
|
||||
// Note: On IE e.keyCode is not 0 for printables so check e.charCode.
|
||||
// In dojo charCode is universally 0 for non-printables.
|
||||
if(e.charCode){ // handle printables (letter navigation)
|
||||
// Check for key navigation.
|
||||
var navKey = e.charCode;
|
||||
if(!e.altKey && !e.ctrlKey && !e.shiftKey && !e.metaKey){
|
||||
navKey = (String.fromCharCode(navKey)).toLowerCase();
|
||||
this._publish("letterKeyNav", { node: treeNode, key: navKey } );
|
||||
dojo.stopEvent(e);
|
||||
}
|
||||
}else{ // handle non-printables (arrow keys)
|
||||
if(this._keyTopicMap[e.keyCode]){
|
||||
this._publish(this._keyTopicMap[e.keyCode], { node: treeNode, item: treeNode.item } );
|
||||
dojo.stopEvent(e);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
blurNode: function(){
|
||||
// summary
|
||||
// Removes focus from the currently focused node (which must be visible).
|
||||
// Usually not called directly (just call focusNode() on another node instead)
|
||||
var node = this.lastFocused;
|
||||
if(!node){ return; }
|
||||
var labelNode = node.labelNode;
|
||||
dojo.removeClass(labelNode, "dijitTreeLabelFocused");
|
||||
labelNode.setAttribute("tabIndex", "-1");
|
||||
this.lastFocused = null;
|
||||
},
|
||||
|
||||
focusNode: function(/* _tree.Node */ node){
|
||||
// summary
|
||||
// Focus on the specified node (which must be visible)
|
||||
|
||||
this.blurNode();
|
||||
|
||||
// set tabIndex so that the tab key can find this node
|
||||
var labelNode = node.labelNode;
|
||||
labelNode.setAttribute("tabIndex", "0");
|
||||
|
||||
this.lastFocused = node;
|
||||
dojo.addClass(labelNode, "dijitTreeLabelFocused");
|
||||
|
||||
// set focus so that the label wil be voiced using screen readers
|
||||
labelNode.focus();
|
||||
},
|
||||
|
||||
_onBlur: function(){
|
||||
// summary:
|
||||
// We've moved away from the whole tree. The currently "focused" node
|
||||
// (see focusNode above) should remain as the lastFocused node so we can
|
||||
// tab back into the tree. Just change CSS to get rid of the dotted border
|
||||
// until that time
|
||||
if(this.lastFocused){
|
||||
var labelNode = this.lastFocused.labelNode;
|
||||
dojo.removeClass(labelNode, "dijitTreeLabelFocused");
|
||||
}
|
||||
},
|
||||
|
||||
_onFocus: function(){
|
||||
// summary:
|
||||
// If we were previously on the tree, there's a currently "focused" node
|
||||
// already. Just need to set the CSS back so it looks focused.
|
||||
if(this.lastFocused){
|
||||
var labelNode = this.lastFocused.labelNode;
|
||||
dojo.addClass(labelNode, "dijitTreeLabelFocused");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
dojo.declare(
|
||||
"dijit._TreeNode",
|
||||
dijit._TreeBase,
|
||||
{
|
||||
// summary
|
||||
// Single node within a tree
|
||||
|
||||
templateString:"<div class=\"dijitTreeNode dijitTreeExpandLeaf dijitTreeChildrenNo\" waiRole=\"presentation\"\n\t><span dojoAttachPoint=\"expandoNode\" class=\"dijitTreeExpando\" waiRole=\"presentation\"\n\t></span\n\t><span dojoAttachPoint=\"expandoNodeText\" class=\"dijitExpandoText\" waiRole=\"presentation\"\n\t></span\n\t>\n\t<div dojoAttachPoint=\"contentNode\" class=\"dijitTreeContent\" waiRole=\"presentation\">\n\t\t<div dojoAttachPoint=\"iconNode\" class=\"dijitInline dijitTreeIcon\" waiRole=\"presentation\"></div>\n\t\t<span dojoAttachPoint=labelNode class=\"dijitTreeLabel\" wairole=\"treeitem\" expanded=\"true\" tabindex=\"-1\"></span>\n\t</div>\n</div>\n",
|
||||
|
||||
// item: dojo.data.Item
|
||||
// the dojo.data entry this tree represents
|
||||
item: null,
|
||||
|
||||
isTreeNode: true,
|
||||
|
||||
// label: String
|
||||
// Text of this tree node
|
||||
label: "",
|
||||
|
||||
isFolder: null, // set by widget depending on children/args
|
||||
|
||||
isExpanded: false,
|
||||
|
||||
postCreate: function(){
|
||||
// set label, escaping special characters
|
||||
this.labelNode.innerHTML = "";
|
||||
this.labelNode.appendChild(document.createTextNode(this.label));
|
||||
|
||||
// set expand icon for leaf
|
||||
this._setExpando();
|
||||
|
||||
// set icon based on item
|
||||
dojo.addClass(this.iconNode, this.tree.getIconClass(this.item));
|
||||
},
|
||||
|
||||
markProcessing: function(){
|
||||
// summary: visually denote that tree is loading data, etc.
|
||||
this.state = "LOADING";
|
||||
this._setExpando(true);
|
||||
},
|
||||
|
||||
unmarkProcessing: function(){
|
||||
// summary: clear markup from markProcessing() call
|
||||
this._setExpando(false);
|
||||
},
|
||||
|
||||
_updateLayout: function(){
|
||||
// summary: set appropriate CSS classes for this.domNode
|
||||
|
||||
dojo.removeClass(this.domNode, "dijitTreeIsRoot");
|
||||
if(this.getParent()["isTree"]){
|
||||
dojo.addClass(this.domNode, "dijitTreeIsRoot");
|
||||
}
|
||||
|
||||
dojo.removeClass(this.domNode, "dijitTreeIsLast");
|
||||
if(!this.getNextSibling()){
|
||||
dojo.addClass(this.domNode, "dijitTreeIsLast");
|
||||
}
|
||||
},
|
||||
|
||||
_setExpando: function(/*Boolean*/ processing){
|
||||
// summary: set the right image for the expando node
|
||||
|
||||
// apply the appropriate class to the expando node
|
||||
var styles = ["dijitTreeExpandoLoading", "dijitTreeExpandoOpened",
|
||||
"dijitTreeExpandoClosed", "dijitTreeExpandoLeaf"];
|
||||
var idx = processing ? 0 : (this.isFolder ? (this.isExpanded ? 1 : 2) : 3);
|
||||
dojo.forEach(styles,
|
||||
function(s){
|
||||
dojo.removeClass(this.expandoNode, s);
|
||||
}, this
|
||||
);
|
||||
dojo.addClass(this.expandoNode, styles[idx]);
|
||||
|
||||
// provide a non-image based indicator for images-off mode
|
||||
this.expandoNodeText.innerHTML =
|
||||
processing ? "*" :
|
||||
(this.isFolder ?
|
||||
(this.isExpanded ? "-" : "+") : "*");
|
||||
},
|
||||
|
||||
setChildren: function(items){
|
||||
var ret = dijit.Tree.superclass.setChildren.apply(this, arguments);
|
||||
|
||||
// create animations for showing/hiding the children
|
||||
this._wipeIn = dojo.fx.wipeIn({node: this.containerNode, duration: 250});
|
||||
dojo.connect(this.wipeIn, "onEnd", dojo.hitch(this, "_afterExpand"));
|
||||
this._wipeOut = dojo.fx.wipeOut({node: this.containerNode, duration: 250});
|
||||
dojo.connect(this.wipeOut, "onEnd", dojo.hitch(this, "_afterCollapse"));
|
||||
|
||||
return ret;
|
||||
},
|
||||
|
||||
expand: function(){
|
||||
// summary: show my children
|
||||
if(this.isExpanded){ return; }
|
||||
|
||||
// cancel in progress collapse operation
|
||||
if(this._wipeOut.status() == "playing"){
|
||||
this._wipeOut.stop();
|
||||
}
|
||||
|
||||
this.isExpanded = true;
|
||||
dijit.wai.setAttr(this.labelNode, "waiState", "expanded", "true");
|
||||
dijit.wai.setAttr(this.containerNode, "waiRole", "role", "group");
|
||||
|
||||
this._setExpando();
|
||||
|
||||
// TODO: use animation that's constant speed of movement, not constant time regardless of height
|
||||
this._wipeIn.play();
|
||||
},
|
||||
|
||||
_afterExpand: function(){
|
||||
this.onShow();
|
||||
this._publish("afterExpand", {node: this});
|
||||
},
|
||||
|
||||
collapse: function(){
|
||||
if(!this.isExpanded){ return; }
|
||||
|
||||
// cancel in progress expand operation
|
||||
if(this._wipeIn.status() == "playing"){
|
||||
this._wipeIn.stop();
|
||||
}
|
||||
|
||||
this.isExpanded = false;
|
||||
dijit.wai.setAttr(this.labelNode, "waiState", "expanded", "false");
|
||||
this._setExpando();
|
||||
|
||||
this._wipeOut.play();
|
||||
},
|
||||
|
||||
_afterCollapse: function(){
|
||||
this.onHide();
|
||||
this._publish("afterCollapse", {node: this});
|
||||
},
|
||||
|
||||
|
||||
setLabelNode: function(label) {
|
||||
this.labelNode.innerHTML="";
|
||||
this.labelNode.appendChild(document.createTextNode(label));
|
||||
},
|
||||
|
||||
|
||||
toString: function(){
|
||||
return '['+this.declaredClass+', '+this.label+']';
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
226
spring-faces/src/main/java/META-INF/dijit/_Calendar.js
Normal file
226
spring-faces/src/main/java/META-INF/dijit/_Calendar.js
Normal file
@@ -0,0 +1,226 @@
|
||||
if(!dojo._hasResource["dijit._Calendar"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._Calendar"] = true;
|
||||
dojo.provide("dijit._Calendar");
|
||||
|
||||
dojo.require("dojo.cldr.supplemental");
|
||||
dojo.require("dojo.date");
|
||||
dojo.require("dojo.date.locale");
|
||||
|
||||
dojo.require("dijit._Widget");
|
||||
dojo.require("dijit._Templated");
|
||||
|
||||
dojo.declare(
|
||||
"dijit._Calendar",
|
||||
[dijit._Widget, dijit._Templated],
|
||||
{
|
||||
/*
|
||||
summary:
|
||||
A simple GUI for choosing a date in the context of a monthly calendar.
|
||||
|
||||
description:
|
||||
This widget is used internally by other widgets and is not accessible
|
||||
as a standalone widget.
|
||||
This widget can't be used in a form because it doesn't serialize the date to an
|
||||
<input> field. For a form element, use DateTextBox instead.
|
||||
|
||||
Note that the parser takes all dates attributes passed in the `RFC 3339` format:
|
||||
http://www.faqs.org/rfcs/rfc3339.html (2005-06-30T08:05:00-07:00)
|
||||
so that they are serializable and locale-independent.
|
||||
|
||||
usage:
|
||||
var calendar = new dijit._Calendar({}, dojo.byId("calendarNode"));
|
||||
-or-
|
||||
<div dojoType="dijit._Calendar"></div>
|
||||
*/
|
||||
templateString:"<table cellspacing=\"0\" cellpadding=\"0\" class=\"dijitCalendarContainer\">\n\t<thead>\n\t\t<tr class=\"dijitReset dijitCalendarMonthContainer\" valign=\"top\">\n\t\t\t<th class='dijitReset' dojoAttachEvent=\"onclick: _onDecrementMonth\">\n\t\t\t\t<span class=\"dijitInline dijitCalendarIncrementControl dijitCalendarDecrease\"><span dojoAttachPoint=\"decreaseArrowNode\" class=\"dijitA11ySideArrow dijitCalendarIncrementControl dijitCalendarDecreaseInner\">-</span></span>\n\t\t\t</th>\n\t\t\t<th class='dijitReset' colspan=\"5\">\n\t\t\t\t<div dojoAttachPoint=\"monthLabelSpacer\" class=\"dijitCalendarMonthLabelSpacer\"></div>\n\t\t\t\t<div dojoAttachPoint=\"monthLabelNode\" class=\"dijitCalendarMonth\"></div>\n\t\t\t</th>\n\t\t\t<th class='dijitReset' dojoAttachEvent=\"onclick: _onIncrementMonth\">\n\t\t\t\t<div class=\"dijitInline dijitCalendarIncrementControl dijitCalendarIncrease\"><span dojoAttachPoint=\"increaseArrowNode\" class=\"dijitA11ySideArrow dijitCalendarIncrementControl dijitCalendarIncreaseInner\">+</span></div>\n\t\t\t</th>\n\t\t</tr>\n\t\t<tr>\n\t\t\t<th class=\"dijitReset dijitCalendarDayLabelTemplate\"><span class=\"dijitCalendarDayLabel\"></span></th>\n\t\t</tr>\n\t</thead>\n\t<tbody dojoAttachEvent=\"onclick: _onDayClick\" class=\"dijitReset dijitCalendarBodyContainer\">\n\t\t<tr class=\"dijitReset dijitCalendarWeekTemplate\">\n\t\t\t<td class=\"dijitReset dijitCalendarDateTemplate\"><span class=\"dijitCalendarDateLabel\"></span></td>\n\t\t</tr>\n\t</tbody>\n\t<tfoot class=\"dijitReset dijitCalendarYearContainer\">\n\t\t<tr>\n\t\t\t<td class='dijitReset' valign=\"top\" colspan=\"7\">\n\t\t\t\t<h3 class=\"dijitCalendarYearLabel\">\n\t\t\t\t\t<span dojoAttachPoint=\"previousYearLabelNode\"\n\t\t\t\t\t\tdojoAttachEvent=\"onclick: _onDecrementYear\" class=\"dijitInline dijitCalendarPreviousYear\"></span>\n\t\t\t\t\t<span dojoAttachPoint=\"currentYearLabelNode\" class=\"dijitInline dijitCalendarSelectedYear\"></span>\n\t\t\t\t\t<span dojoAttachPoint=\"nextYearLabelNode\"\n\t\t\t\t\t\tdojoAttachEvent=\"onclick: _onIncrementYear\" class=\"dijitInline dijitCalendarNextYear\"></span>\n\t\t\t\t</h3>\n\t\t\t</td>\n\t\t</tr>\n\t</tfoot>\n</table>\t\n",
|
||||
|
||||
// value: Date
|
||||
// the currently selected Date
|
||||
value: new Date(),
|
||||
|
||||
// dayWidth: String
|
||||
// How to represent the days of the week in the calendar header. See dojo.date.locale
|
||||
dayWidth: "narrow",
|
||||
|
||||
setValue: function(/*Date*/ value){
|
||||
// summary: set the current date and update the UI. If the date is disabled, the selection will
|
||||
// not change, but the display will change to the corresponding month.
|
||||
if(!this.value || dojo.date.compare(value, this.value)){
|
||||
value = new Date(value);
|
||||
this.displayMonth = new Date(value);
|
||||
if(!this.isDisabledDate(value, this.lang)){
|
||||
this.value = value;
|
||||
this.value.setHours(0,0,0,0);
|
||||
this.onChange(this.value);
|
||||
}
|
||||
this._populateGrid();
|
||||
}
|
||||
},
|
||||
|
||||
_setText: function(node, text){
|
||||
while(node.firstChild){
|
||||
node.removeChild(node.firstChild);
|
||||
}
|
||||
node.appendChild(document.createTextNode(text));
|
||||
},
|
||||
|
||||
_populateGrid: function(){
|
||||
var month = this.displayMonth;
|
||||
month.setDate(1);
|
||||
var firstDay = month.getDay();
|
||||
var daysInMonth = dojo.date.getDaysInMonth(month);
|
||||
var daysInPreviousMonth = dojo.date.getDaysInMonth(dojo.date.add(month, "month", -1));
|
||||
var today = new Date();
|
||||
var selected = this.value;
|
||||
|
||||
var dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
|
||||
if(dayOffset > firstDay){ dayOffset -= 7; }
|
||||
|
||||
// Iterate through dates in the calendar and fill in date numbers and style info
|
||||
dojo.query(".dijitCalendarDateTemplate", this.domNode).forEach(function(template, i){
|
||||
i += dayOffset;
|
||||
var date = new Date(month);
|
||||
var number, clazz = "dijitCalendar", adj = 0;
|
||||
|
||||
if(i < firstDay){
|
||||
number = daysInPreviousMonth - firstDay + i + 1;
|
||||
adj = -1;
|
||||
clazz += "Previous";
|
||||
}else if(i >= (firstDay + daysInMonth)){
|
||||
number = i - firstDay - daysInMonth + 1;
|
||||
adj = 1;
|
||||
clazz += "Next";
|
||||
}else{
|
||||
number = i - firstDay + 1;
|
||||
clazz += "Current";
|
||||
}
|
||||
|
||||
if(adj){
|
||||
date = dojo.date.add(date, "month", adj);
|
||||
}
|
||||
date.setDate(number);
|
||||
|
||||
if(!dojo.date.compare(date, today, "date")){
|
||||
clazz = "dijitCalendarCurrentDate " + clazz;
|
||||
}
|
||||
|
||||
if(!dojo.date.compare(date, selected, "date")){
|
||||
clazz = "dijitCalendarSelectedDate " + clazz;
|
||||
}
|
||||
|
||||
if(this.isDisabledDate(date, this.lang)){
|
||||
clazz = "dijitCalendarDisabledDate " + clazz;
|
||||
}
|
||||
|
||||
template.className = clazz + "Month dijitCalendarDateTemplate";
|
||||
template.dijitDateValue = date.valueOf();
|
||||
var label = dojo.query(".dijitCalendarDateLabel", template)[0];
|
||||
this._setText(label, date.getDate());
|
||||
}, this);
|
||||
|
||||
// Fill in localized month name
|
||||
var monthNames = dojo.date.locale.getNames('months', 'wide', 'standAlone', this.lang);
|
||||
this._setText(this.monthLabelNode, monthNames[month.getMonth()]);
|
||||
|
||||
// Fill in localized prev/current/next years
|
||||
var y = month.getFullYear() - 1;
|
||||
dojo.forEach(["previous", "current", "next"], function(name){
|
||||
this._setText(this[name+"YearLabelNode"],
|
||||
dojo.date.locale.format(new Date(y++, 0), {selector:'year', locale:this.lang}));
|
||||
}, this);
|
||||
},
|
||||
|
||||
postCreate: function(){
|
||||
dijit._Calendar.superclass.postCreate.apply(this);
|
||||
|
||||
var cloneClass = dojo.hitch(this, function(clazz, n){
|
||||
var template = dojo.query(clazz, this.domNode)[0];
|
||||
for(var i=0; i<n; i++){
|
||||
template.parentNode.appendChild(template.cloneNode(true));
|
||||
}
|
||||
});
|
||||
|
||||
// clone the day label and calendar day templates 6 times to make 7 columns
|
||||
cloneClass(".dijitCalendarDayLabelTemplate", 6);
|
||||
cloneClass(".dijitCalendarDateTemplate", 6);
|
||||
|
||||
// now make 6 week rows
|
||||
cloneClass(".dijitCalendarWeekTemplate", 5);
|
||||
|
||||
// insert localized day names in the header
|
||||
var dayNames = dojo.date.locale.getNames('days', this.dayWidth, 'standAlone', this.lang);
|
||||
var dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
|
||||
dojo.query(".dijitCalendarDayLabel", this.domNode).forEach(function(label, i){
|
||||
this._setText(label, dayNames[(i + dayOffset) % 7]);
|
||||
}, this);
|
||||
|
||||
// Fill in spacer element with all the month names (invisible) so that the maximum width will affect layout
|
||||
var monthNames = dojo.date.locale.getNames('months', 'wide', 'standAlone', this.lang);
|
||||
dojo.forEach(monthNames, function(name){
|
||||
var monthSpacer = dojo.doc.createElement("div");
|
||||
this._setText(monthSpacer, name);
|
||||
this.monthLabelSpacer.appendChild(monthSpacer);
|
||||
}, this);
|
||||
|
||||
this.value = null;
|
||||
this.setValue(new Date());
|
||||
},
|
||||
|
||||
_adjustDate: function(/*String*/part, /*int*/amount){
|
||||
this.displayMonth = dojo.date.add(this.displayMonth, part, amount);
|
||||
this._populateGrid();
|
||||
},
|
||||
|
||||
_onIncrementMonth: function(/*Event*/evt){
|
||||
// summary: handler for increment month event
|
||||
evt.stopPropagation();
|
||||
this._adjustDate("month", 1);
|
||||
},
|
||||
|
||||
_onDecrementMonth: function(/*Event*/evt){
|
||||
// summary: handler for increment month event
|
||||
evt.stopPropagation();
|
||||
this._adjustDate("month", -1);
|
||||
},
|
||||
|
||||
_onIncrementYear: function(/*Event*/evt){
|
||||
// summary: handler for increment year event
|
||||
evt.stopPropagation();
|
||||
this._adjustDate("year", 1);
|
||||
},
|
||||
|
||||
_onDecrementYear: function(/*Event*/evt){
|
||||
// summary: handler for increment year event
|
||||
evt.stopPropagation();
|
||||
this._adjustDate("year", -1);
|
||||
},
|
||||
|
||||
_onDayClick: function(/*Event*/evt){
|
||||
var node = evt.target;
|
||||
dojo.stopEvent(evt);
|
||||
while(!node.dijitDateValue){
|
||||
node = node.parentNode;
|
||||
}
|
||||
if(!dojo.hasClass(node, "dijitCalendarDisabledDate")){
|
||||
this.setValue(node.dijitDateValue);
|
||||
this.onValueSelected(this.value);
|
||||
}
|
||||
},
|
||||
|
||||
onValueSelected: function(/*Date*/date){
|
||||
//summary: a date cell was selected. It may be the same as the previous value.
|
||||
},
|
||||
|
||||
onChange: function(/*Date*/date){
|
||||
//summary: called only when the selected date has changed
|
||||
},
|
||||
|
||||
isDisabledDate: function(/*Date*/dateObject, /*String?*/locale){
|
||||
// summary:
|
||||
// May be overridden to disable certain dates in the calendar e.g. isDisabledDate=dojo.date.locale.isWeekend
|
||||
return false; // Boolean
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
118
spring-faces/src/main/java/META-INF/dijit/_Container.js
Normal file
118
spring-faces/src/main/java/META-INF/dijit/_Container.js
Normal file
@@ -0,0 +1,118 @@
|
||||
if(!dojo._hasResource["dijit._Container"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._Container"] = true;
|
||||
dojo.provide("dijit._Container");
|
||||
|
||||
dojo.declare("dijit._Contained",
|
||||
null,
|
||||
{
|
||||
// summary
|
||||
// Mixin for widgets that are children of a container widget
|
||||
|
||||
getParent: function(){
|
||||
// summary:
|
||||
// returns the parent widget of this widget, assuming the parent
|
||||
// implements dijit._Container
|
||||
for(var p=this.domNode.parentNode; p; p=p.parentNode){
|
||||
var id = p.getAttribute && p.getAttribute("widgetId");
|
||||
if(id){
|
||||
var parent = dijit.byId(id);
|
||||
return parent.isContainer ? parent : null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
_getSibling: function(which){
|
||||
var node = this.domNode;
|
||||
do{
|
||||
node = node[which+"Sibling"];
|
||||
}while(node && node.nodeType != 1);
|
||||
if(!node){ return null; } // null
|
||||
var id = node.getAttribute("widgetId");
|
||||
return dijit.byId(id);
|
||||
},
|
||||
|
||||
getPreviousSibling: function(){
|
||||
// summary:
|
||||
// returns null if this is the first child of the parent,
|
||||
// otherwise returns the next element sibling to the "left".
|
||||
|
||||
return this._getSibling("previous");
|
||||
},
|
||||
|
||||
getNextSibling: function(){
|
||||
// summary:
|
||||
// returns null if this is the last child of the parent,
|
||||
// otherwise returns the next element sibling to the "right".
|
||||
|
||||
return this._getSibling("next");
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
dojo.declare("dijit._Container",
|
||||
null,
|
||||
{
|
||||
// summary
|
||||
// Mixin for widgets that contain a list of children like SplitContainer
|
||||
|
||||
isContainer: true,
|
||||
|
||||
addChild: function(/*Widget*/ widget, /*int?*/ insertIndex){
|
||||
// summary:
|
||||
// Process the given child widget, inserting it's dom node as
|
||||
// a child of our dom node
|
||||
|
||||
if(typeof insertIndex == "undefined"){
|
||||
insertIndex = "last";
|
||||
}
|
||||
dojo.place(widget.domNode, this.containerNode || this.domNode, insertIndex);
|
||||
|
||||
// If I've been started but the child widget hasn't been started,
|
||||
// start it now. Make sure to do this after widget has been
|
||||
// inserted into the DOM tree, so it can see that it's being controlled by me,
|
||||
// so it doesn't try to size itself.
|
||||
if(this._started && !widget._started){
|
||||
widget.startup();
|
||||
}
|
||||
},
|
||||
|
||||
removeChild: function(/*Widget*/ widget){
|
||||
// summary:
|
||||
// removes the passed widget instance from this widget but does
|
||||
// not destroy it
|
||||
var node = widget.domNode;
|
||||
node.parentNode.removeChild(node); // detach but don't destroy
|
||||
},
|
||||
|
||||
_nextElement: function(node){
|
||||
do{
|
||||
node = node.nextSibling;
|
||||
}while(node && node.nodeType != 1);
|
||||
return node;
|
||||
},
|
||||
|
||||
_firstElement: function(node){
|
||||
node = node.firstChild;
|
||||
if(node && node.nodeType != 1){
|
||||
node = this._nextElement(node);
|
||||
}
|
||||
return node;
|
||||
},
|
||||
|
||||
getChildren: function(){
|
||||
// summary:
|
||||
// returns array of children widgets
|
||||
return dojo.query("> [widgetId]", this.containerNode || this.domNode).map(dijit.byNode); // Array
|
||||
},
|
||||
|
||||
hasChildren: function(){
|
||||
// summary:
|
||||
// returns true if widget has children
|
||||
var cn = this.containerNode || this.domNode;
|
||||
return !!this._firstElement(cn); // Boolean
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
329
spring-faces/src/main/java/META-INF/dijit/_Templated.js
Normal file
329
spring-faces/src/main/java/META-INF/dijit/_Templated.js
Normal file
@@ -0,0 +1,329 @@
|
||||
if(!dojo._hasResource["dijit._Templated"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._Templated"] = true;
|
||||
dojo.provide("dijit._Templated");
|
||||
|
||||
dojo.require("dijit._Widget");
|
||||
|
||||
dojo.require("dojo.string");
|
||||
dojo.require("dojo.parser");
|
||||
|
||||
dojo.declare("dijit._Templated",
|
||||
null,
|
||||
{
|
||||
// summary:
|
||||
// mixin for widgets that are instantiated from a template
|
||||
|
||||
// templateNode: DomNode
|
||||
// a node that represents the widget template. Pre-empts both templateString and templatePath.
|
||||
templateNode: null,
|
||||
|
||||
// templateString String:
|
||||
// a string that represents the widget template. Pre-empts the
|
||||
// templatePath. In builds that have their strings "interned", the
|
||||
// templatePath is converted to an inline templateString, thereby
|
||||
// preventing a synchronous network call.
|
||||
templateString: null,
|
||||
|
||||
// templatePath: String
|
||||
// Path to template (HTML file) for this widget
|
||||
templatePath: null,
|
||||
|
||||
// widgetsInTemplate Boolean:
|
||||
// should we parse the template to find widgets that might be
|
||||
// declared in markup inside it? false by default.
|
||||
widgetsInTemplate: false,
|
||||
|
||||
// containerNode DomNode:
|
||||
// holds child elements. "containerNode" is generally set via a
|
||||
// dojoAttachPoint assignment and it designates where children of
|
||||
// the src dom node will be placed
|
||||
containerNode: null,
|
||||
|
||||
// method over-ride
|
||||
buildRendering: function(){
|
||||
// summary:
|
||||
// Construct the UI for this widget from a template.
|
||||
// description:
|
||||
// Lookup cached version of template, and download to cache if it
|
||||
// isn't there already. Returns either a DomNode or a string, depending on
|
||||
// whether or not the template contains ${foo} replacement parameters.
|
||||
|
||||
var cached = dijit._Templated.getCachedTemplate(this.templatePath, this.templateString);
|
||||
|
||||
var node;
|
||||
if(dojo.isString(cached)){
|
||||
var className = this.declaredClass, _this = this;
|
||||
// Cache contains a string because we need to do property replacement
|
||||
// do the property replacement
|
||||
var tstr = dojo.string.substitute(cached, this, function(value, key){
|
||||
if(key.charAt(0) == '!'){ value = _this[key.substr(1)]; }
|
||||
if(typeof value == "undefined"){ throw new Error(className+" template:"+key); } // a debugging aide
|
||||
|
||||
// Substitution keys beginning with ! will skip the transform step,
|
||||
// in case a user wishes to insert unescaped markup, e.g. ${!foo}
|
||||
return key.charAt(0) == "!" ? value :
|
||||
// Safer substitution, see heading "Attribute values" in
|
||||
// http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2
|
||||
value.toString().replace(/"/g,"""); //TODO: add &? use encodeXML method?
|
||||
}, this);
|
||||
|
||||
node = dijit._Templated._createNodesFromText(tstr)[0];
|
||||
}else{
|
||||
// if it's a node, all we have to do is clone it
|
||||
node = cached.cloneNode(true);
|
||||
}
|
||||
|
||||
// recurse through the node, looking for, and attaching to, our
|
||||
// attachment points which should be defined on the template node.
|
||||
this._attachTemplateNodes(node);
|
||||
if(this.srcNodeRef){
|
||||
dojo.style(this.styleNode || node, "cssText", this.srcNodeRef.style.cssText);
|
||||
if(this.srcNodeRef.className){
|
||||
node.className += " " + this.srcNodeRef.className;
|
||||
}
|
||||
}
|
||||
|
||||
this.domNode = node;
|
||||
if(this.srcNodeRef && this.srcNodeRef.parentNode){
|
||||
this.srcNodeRef.parentNode.replaceChild(this.domNode, this.srcNodeRef);
|
||||
}
|
||||
if(this.widgetsInTemplate){
|
||||
var childWidgets = dojo.parser.parse(this.domNode);
|
||||
this._attachTemplateNodes(childWidgets, function(n,p){
|
||||
return n[p];
|
||||
});
|
||||
}
|
||||
|
||||
this._fillContent(this.srcNodeRef);
|
||||
},
|
||||
|
||||
_fillContent: function(/*DomNode*/ source){
|
||||
// summary:
|
||||
// relocate source contents to templated container node
|
||||
// this.containerNode must be able to receive children, or exceptions will be thrown
|
||||
var dest = this.containerNode;
|
||||
if(source && dest){
|
||||
while(source.hasChildNodes()){
|
||||
dest.appendChild(source.firstChild);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_attachTemplateNodes: function(rootNode, getAttrFunc){
|
||||
// summary:
|
||||
// map widget properties and functions to the handlers specified in
|
||||
// the dom node and it's descendants. This function iterates over all
|
||||
// nodes and looks for these properties:
|
||||
// * dojoAttachPoint
|
||||
// * dojoAttachEvent
|
||||
// * waiRole
|
||||
// * waiState
|
||||
// rootNode: DomNode|Array[Widgets]
|
||||
// the node to search for properties. All children will be searched.
|
||||
// getAttrFunc: function?
|
||||
// a function which will be used to obtain property for a given
|
||||
// DomNode/Widget
|
||||
|
||||
getAttrFunc = getAttrFunc || function(n,p){ return n.getAttribute(p); };
|
||||
|
||||
var nodes = dojo.isArray(rootNode) ? rootNode : (rootNode.all || rootNode.getElementsByTagName("*"));
|
||||
var x=dojo.isArray(rootNode)?0:-1;
|
||||
for(; x<nodes.length; x++){
|
||||
var baseNode = (x == -1) ? rootNode : nodes[x];
|
||||
if(this.widgetsInTemplate && getAttrFunc(baseNode,'dojoType')){
|
||||
continue;
|
||||
}
|
||||
// Process dojoAttachPoint
|
||||
var attachPoint = getAttrFunc(baseNode, "dojoAttachPoint");
|
||||
if(attachPoint){
|
||||
var point, points = attachPoint.split(/\s*,\s*/);
|
||||
while(point=points.shift()){
|
||||
if(dojo.isArray(this[point])){
|
||||
this[point].push(baseNode);
|
||||
}else{
|
||||
this[point]=baseNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process dojoAttachEvent
|
||||
var attachEvent = getAttrFunc(baseNode, "dojoAttachEvent");
|
||||
if(attachEvent){
|
||||
// NOTE: we want to support attributes that have the form
|
||||
// "domEvent: nativeEvent; ..."
|
||||
var event, events = attachEvent.split(/\s*,\s*/);
|
||||
var trim = dojo.trim;
|
||||
while(event=events.shift()){
|
||||
if(event){
|
||||
var thisFunc = null;
|
||||
if(event.indexOf(":") != -1){
|
||||
// oh, if only JS had tuple assignment
|
||||
var funcNameArr = event.split(":");
|
||||
event = trim(funcNameArr[0]);
|
||||
thisFunc = trim(funcNameArr[1]);
|
||||
}else{
|
||||
event = trim(event);
|
||||
}
|
||||
if(!thisFunc){
|
||||
thisFunc = event;
|
||||
}
|
||||
this.connect(baseNode, event, thisFunc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// waiRole, waiState
|
||||
var name, names = ["waiRole", "waiState"];
|
||||
while(name=names.shift()){
|
||||
var wai = dijit.wai[name];
|
||||
var values = getAttrFunc(baseNode, wai.name);
|
||||
if(values){
|
||||
var role = "role";
|
||||
var val;
|
||||
values = values.split(/\s*,\s*/);
|
||||
while(val=values.shift()){
|
||||
if(val.indexOf('-') != -1){
|
||||
// this is a state-value pair
|
||||
var statePair = val.split('-');
|
||||
role = statePair[0];
|
||||
val = statePair[1];
|
||||
}
|
||||
dijit.wai.setAttr(baseNode, wai.name, role, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// key is either templatePath or templateString; object is either string or DOM tree
|
||||
dijit._Templated._templateCache = {};
|
||||
|
||||
dijit._Templated.getCachedTemplate = function(templatePath, templateString){
|
||||
// summary:
|
||||
// static method to get a template based on the templatePath or
|
||||
// templateString key
|
||||
// templatePath: String
|
||||
// the URL to get the template from. dojo.uri.Uri is often passed as well.
|
||||
// templateString: String?
|
||||
// a string to use in lieu of fetching the template from a URL
|
||||
// Returns:
|
||||
// Either string (if there are ${} variables that need to be replaced) or just
|
||||
// a DOM tree (if the node can be cloned directly)
|
||||
|
||||
// is it already cached?
|
||||
var tmplts = dijit._Templated._templateCache;
|
||||
var key = templateString || templatePath;
|
||||
var cached = tmplts[key];
|
||||
if(cached){
|
||||
return cached;
|
||||
}
|
||||
|
||||
// If necessary, load template string from template path
|
||||
if(!templateString){
|
||||
templateString = dijit._Templated._sanitizeTemplateString(dojo._getText(templatePath));
|
||||
}
|
||||
|
||||
templateString = dojo.string.trim(templateString);
|
||||
|
||||
if(templateString.match(/\$\{([^\}]+)\}/g)){
|
||||
// there are variables in the template so all we can do is cache the string
|
||||
return (tmplts[key] = templateString); //String
|
||||
}else{
|
||||
// there are no variables in the template so we can cache the DOM tree
|
||||
return (tmplts[key] = dijit._Templated._createNodesFromText(templateString)[0]); //Node
|
||||
}
|
||||
};
|
||||
|
||||
dijit._Templated._sanitizeTemplateString = function(/*String*/tString){
|
||||
//summary: Strips <?xml ...?> declarations so that external SVG and XML
|
||||
//documents can be added to a document without worry. Also, if the string
|
||||
//is an HTML document, only the part inside the body tag is returned.
|
||||
if(tString){
|
||||
tString = tString.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, "");
|
||||
var matches = tString.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
|
||||
if(matches){
|
||||
tString = matches[1];
|
||||
}
|
||||
}else{
|
||||
tString = "";
|
||||
}
|
||||
return tString; //String
|
||||
};
|
||||
|
||||
|
||||
if(dojo.isIE){
|
||||
dojo.addOnUnload(function(){
|
||||
var cache = dijit._Templated._templateCache;
|
||||
for(var key in cache){
|
||||
var value = cache[key];
|
||||
if(!isNaN(value.nodeType)){ // isNode equivalent
|
||||
dojo._destroyElement(value);
|
||||
}
|
||||
cache[key] = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
(function(){
|
||||
var tagMap = {
|
||||
cell: {re: /^<t[dh][\s\r\n>]/i, pre: "<table><tbody><tr>", post: "</tr></tbody></table>"},
|
||||
row: {re: /^<tr[\s\r\n>]/i, pre: "<table><tbody>", post: "</tbody></table>"},
|
||||
section: {re: /^<(thead|tbody|tfoot)[\s\r\n>]/i, pre: "<table>", post: "</table>"}
|
||||
};
|
||||
|
||||
// dummy container node used temporarily to hold nodes being created
|
||||
var tn;
|
||||
|
||||
dijit._Templated._createNodesFromText = function(/*String*/text){
|
||||
// summary
|
||||
// Attempts to create a set of nodes based on the structure of the passed text.
|
||||
|
||||
if(!tn){
|
||||
tn = dojo.doc.createElement("div");
|
||||
tn.style.display="none";
|
||||
}
|
||||
var tableType = "none";
|
||||
var rtext = text.replace(/^\s+/, "");
|
||||
for(var type in tagMap){
|
||||
var map = tagMap[type];
|
||||
if(map.re.test(rtext)){
|
||||
tableType = type;
|
||||
text = map.pre + text + map.post;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tn.innerHTML = text;
|
||||
dojo.body().appendChild(tn);
|
||||
if(tn.normalize){
|
||||
tn.normalize();
|
||||
}
|
||||
|
||||
var tag = { cell: "tr", row: "tbody", section: "table" }[tableType];
|
||||
var _parent = (typeof tag != "undefined") ?
|
||||
tn.getElementsByTagName(tag)[0] :
|
||||
tn;
|
||||
|
||||
var nodes = [];
|
||||
while(_parent.firstChild){
|
||||
nodes.push(_parent.removeChild(_parent.firstChild));
|
||||
}
|
||||
tn.innerHTML="";
|
||||
return nodes; // Array
|
||||
}
|
||||
})();
|
||||
|
||||
// These arguments can be specified for widgets which are used in templates.
|
||||
// Since any widget can be specified as sub widgets in template, mix it
|
||||
// into the base widget class. (This is a hack, but it's effective.)
|
||||
dojo.extend(dijit._Widget,{
|
||||
dojoAttachEvent: "",
|
||||
dojoAttachPoint: "",
|
||||
waiRole: "",
|
||||
waiState:""
|
||||
})
|
||||
|
||||
}
|
||||
294
spring-faces/src/main/java/META-INF/dijit/_Widget.js
Normal file
294
spring-faces/src/main/java/META-INF/dijit/_Widget.js
Normal file
@@ -0,0 +1,294 @@
|
||||
if(!dojo._hasResource["dijit._Widget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._Widget"] = true;
|
||||
dojo.provide("dijit._Widget");
|
||||
|
||||
dojo.require("dijit._base");
|
||||
|
||||
dojo.declare("dijit._Widget", null, {
|
||||
constructor: function(params, srcNodeRef){
|
||||
this.create(params, srcNodeRef);
|
||||
},
|
||||
// id: String
|
||||
// a unique, opaque ID string that can be assigned by users or by the
|
||||
// system. If the developer passes an ID which is known not to be
|
||||
// unique, the specified ID is ignored and the system-generated ID is
|
||||
// used instead.
|
||||
id: "",
|
||||
|
||||
// lang: String
|
||||
// Language to display this widget in (like en-us).
|
||||
// Defaults to brower's specified preferred language (typically the language of the OS)
|
||||
lang: "",
|
||||
|
||||
// dir: String
|
||||
// Bi-directional support, as defined by the HTML DIR attribute. Either left-to-right "ltr" or right-to-left "rtl".
|
||||
dir: "",
|
||||
|
||||
// srcNodeRef: DomNode
|
||||
// pointer to original dom node
|
||||
srcNodeRef: null,
|
||||
|
||||
// domNode DomNode:
|
||||
// this is our visible representation of the widget! Other DOM
|
||||
// Nodes may by assigned to other properties, usually through the
|
||||
// template system's dojoAttachPonit syntax, but the domNode
|
||||
// property is the canonical "top level" node in widget UI.
|
||||
domNode: null,
|
||||
|
||||
//////////// INITIALIZATION METHODS ///////////////////////////////////////
|
||||
|
||||
create: function(params, srcNodeRef) {
|
||||
// summary:
|
||||
// To understand the process by which widgets are instantiated, it
|
||||
// is critical to understand what other methods create calls and
|
||||
// which of them you'll want to override. Of course, adventurous
|
||||
// developers could override create entirely, but this should
|
||||
// only be done as a last resort.
|
||||
//
|
||||
// Below is a list of the methods that are called, in the order
|
||||
// they are fired, along with notes about what they do and if/when
|
||||
// you should over-ride them in your widget:
|
||||
//
|
||||
// postMixInProperties:
|
||||
// a stub function that you can over-ride to modify
|
||||
// variables that may have been naively assigned by
|
||||
// mixInProperties
|
||||
// # widget is added to manager object here
|
||||
// buildRendering
|
||||
// Subclasses use this method to handle all UI initialization
|
||||
// Sets this.domNode. Templated widgets do this automatically
|
||||
// and otherwise it just uses the source dom node.
|
||||
// postCreate
|
||||
// a stub function that you can over-ride to modify take
|
||||
// actions once the widget has been placed in the UI
|
||||
|
||||
// store pointer to original dom tree
|
||||
this.srcNodeRef = dojo.byId(srcNodeRef);
|
||||
|
||||
// For garbage collection. An array of handles returned by Widget.connect()
|
||||
// Each handle returned from Widget.connect() is an array of handles from dojo.connect()
|
||||
this._connects=[];
|
||||
|
||||
// _attaches: String[]
|
||||
// names of all our dojoAttachPoint variables
|
||||
this._attaches=[];
|
||||
|
||||
//mixin our passed parameters
|
||||
if(this.srcNodeRef && (typeof this.srcNodeRef.id == "string")){ this.id = this.srcNodeRef.id; }
|
||||
if(params){
|
||||
dojo.mixin(this,params);
|
||||
}
|
||||
this.postMixInProperties();
|
||||
|
||||
// generate an id for the widget if one wasn't specified
|
||||
// (be sure to do this before buildRendering() because that function might
|
||||
// expect the id to be there.
|
||||
if(!this.id){
|
||||
this.id=dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
|
||||
}
|
||||
dijit.registry.add(this);
|
||||
|
||||
this.buildRendering();
|
||||
if(this.domNode){
|
||||
this.domNode.setAttribute("widgetId", this.id);
|
||||
if(this.srcNodeRef && this.srcNodeRef.dir){
|
||||
this.domNode.dir = this.srcNodeRef.dir;
|
||||
}
|
||||
}
|
||||
this.postCreate();
|
||||
|
||||
// If srcNodeRef has been processed and removed from the DOM (e.g. TemplatedWidget) then delete it to allow GC.
|
||||
if(this.srcNodeRef && !this.srcNodeRef.parentNode){
|
||||
delete this.srcNodeRef;
|
||||
}
|
||||
},
|
||||
|
||||
postMixInProperties: function(){
|
||||
// summary
|
||||
// Called after the parameters to the widget have been read-in,
|
||||
// but before the widget template is instantiated.
|
||||
// Especially useful to set properties that are referenced in the widget template.
|
||||
},
|
||||
|
||||
buildRendering: function(){
|
||||
// summary:
|
||||
// Construct the UI for this widget, setting this.domNode.
|
||||
// Most widgets will mixin TemplatedWidget, which overrides this method.
|
||||
this.domNode = this.srcNodeRef;
|
||||
},
|
||||
|
||||
postCreate: function(){
|
||||
// summary:
|
||||
// Called after a widget's dom has been setup
|
||||
},
|
||||
|
||||
startup: function(){
|
||||
// summary:
|
||||
// Called after a widget's children, and other widgets on the page, have been created.
|
||||
// Provides an opportunity to manipulate any children before they are displayed
|
||||
// This is useful for composite widgets that need to control or layout sub-widgets
|
||||
// Many layout widgets can use this as a wiring phase
|
||||
},
|
||||
|
||||
//////////// DESTROY FUNCTIONS ////////////////////////////////
|
||||
|
||||
destroyRecursive: function(/*Boolean*/ finalize){
|
||||
// summary:
|
||||
// Destroy this widget and it's descendants. This is the generic
|
||||
// "destructor" function that all widget users should call to
|
||||
// cleanly discard with a widget. Once a widget is destroyed, it's
|
||||
// removed from the manager object.
|
||||
// finalize: Boolean
|
||||
// is this function being called part of global environment
|
||||
// tear-down?
|
||||
|
||||
this.destroyDescendants();
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
destroy: function(/*Boolean*/ finalize){
|
||||
// summary:
|
||||
// Destroy this widget, but not its descendants
|
||||
// finalize: Boolean
|
||||
// is this function being called part of global environment
|
||||
// tear-down?
|
||||
this.uninitialize();
|
||||
dojo.forEach(this._connects, function(array){
|
||||
dojo.forEach(array, dojo.disconnect);
|
||||
});
|
||||
this.destroyRendering(finalize);
|
||||
dijit.registry.remove(this.id);
|
||||
},
|
||||
|
||||
destroyRendering: function(/*Boolean*/ finalize){
|
||||
// summary:
|
||||
// Destroys the DOM nodes associated with this widget
|
||||
// finalize: Boolean
|
||||
// is this function being called part of global environment
|
||||
// tear-down?
|
||||
|
||||
if(this.bgIframe){
|
||||
this.bgIframe.destroy();
|
||||
delete this.bgIframe;
|
||||
}
|
||||
|
||||
if(this.domNode){
|
||||
dojo._destroyElement(this.domNode);
|
||||
delete this.domNode;
|
||||
}
|
||||
|
||||
if(this.srcNodeRef){
|
||||
dojo._destroyElement(this.srcNodeRef);
|
||||
delete this.srcNodeRef;
|
||||
}
|
||||
},
|
||||
|
||||
destroyDescendants: function(){
|
||||
// summary:
|
||||
// Recursively destroy the children of this widget and their
|
||||
// descendants.
|
||||
|
||||
// TODO: should I destroy in the reverse order, to go bottom up?
|
||||
dojo.forEach(this.getDescendants(), function(widget){ widget.destroy(); });
|
||||
},
|
||||
|
||||
uninitialize: function(){
|
||||
// summary:
|
||||
// stub function. Over-ride to implement custom widget tear-down
|
||||
// behavior.
|
||||
return false;
|
||||
},
|
||||
|
||||
////////////////// MISCELLANEOUS METHODS ///////////////////
|
||||
|
||||
toString: function(){
|
||||
// summary:
|
||||
// returns a string that represents the widget. When a widget is
|
||||
// cast to a string, this method will be used to generate the
|
||||
// output. Currently, it does not implement any sort of reversable
|
||||
// serialization.
|
||||
return '[Widget ' + this.declaredClass + ', ' + (this.id || 'NO ID') + ']'; // String
|
||||
},
|
||||
|
||||
getDescendants: function(){
|
||||
// summary:
|
||||
// return all the descendant widgets
|
||||
var list = dojo.query('[widgetId]', this.domNode);
|
||||
return list.map(dijit.byNode); // Array
|
||||
},
|
||||
|
||||
nodesWithKeyClick : ["input", "button"],
|
||||
|
||||
connect: function(
|
||||
/*Object|null*/ obj,
|
||||
/*String*/ event,
|
||||
/*String|Function*/ method){
|
||||
|
||||
// summary:
|
||||
// Connects specified obj/event to specified method of this object
|
||||
// and registers for disconnect() on widget destroy.
|
||||
// Special event: "ondijitclick" triggers on a click or enter-down or space-up
|
||||
// Similar to dojo.connect() but takes three arguments rather than four.
|
||||
var handles =[];
|
||||
if(event == "ondijitclick"){
|
||||
var w = this;
|
||||
// add key based click activation for unsupported nodes.
|
||||
if(!this.nodesWithKeyClick[obj.nodeName]){
|
||||
handles.push(dojo.connect(obj, "onkeydown", this,
|
||||
function(e){
|
||||
if(e.keyCode == dojo.keys.ENTER){
|
||||
return (dojo.isString(method))?
|
||||
w[method](e) : method.call(w, e);
|
||||
}else if(e.keyCode == dojo.keys.SPACE){
|
||||
// stop space down as it causes IE to scroll
|
||||
// the browser window
|
||||
dojo.stopEvent(e);
|
||||
}
|
||||
}));
|
||||
handles.push(dojo.connect(obj, "onkeyup", this,
|
||||
function(e){
|
||||
if(e.keyCode == dojo.keys.SPACE){
|
||||
return dojo.isString(method) ?
|
||||
w[method](e) : method.call(w, e);
|
||||
}
|
||||
}));
|
||||
}
|
||||
event = "onclick";
|
||||
}
|
||||
handles.push(dojo.connect(obj, event, this, method));
|
||||
|
||||
// return handles for FormElement and ComboBox
|
||||
this._connects.push(handles);
|
||||
return handles;
|
||||
},
|
||||
|
||||
disconnect: function(/*Object*/ handles){
|
||||
// summary:
|
||||
// Disconnects handle created by this.connect.
|
||||
// Also removes handle from this widget's list of connects
|
||||
for(var i=0; i<this._connects.length; i++){
|
||||
if(this._connects[i]==handles){
|
||||
dojo.forEach(handles, dojo.disconnect);
|
||||
this._connects.splice(i, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
isLeftToRight: function(){
|
||||
// summary:
|
||||
// Checks the DOM to for the text direction for bi-directional support
|
||||
// description:
|
||||
// This method cannot be used during widget construction because the widget
|
||||
// must first be connected to the DOM tree. Parent nodes are searched for the
|
||||
// 'dir' attribute until one is found, otherwise left to right mode is assumed.
|
||||
// See HTML spec, DIR attribute for more information.
|
||||
|
||||
if(typeof this._ltr == "undefined"){
|
||||
this._ltr = (this.dir || dojo.getComputedStyle(this.domNode).direction) != "rtl";
|
||||
}
|
||||
return this._ltr; //Boolean
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
16
spring-faces/src/main/java/META-INF/dijit/_base.js
Normal file
16
spring-faces/src/main/java/META-INF/dijit/_base.js
Normal file
@@ -0,0 +1,16 @@
|
||||
if(!dojo._hasResource["dijit._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._base"] = true;
|
||||
dojo.provide("dijit._base");
|
||||
|
||||
dojo.require("dijit._base.focus");
|
||||
dojo.require("dijit._base.manager");
|
||||
dojo.require("dijit._base.place");
|
||||
dojo.require("dijit._base.popup");
|
||||
dojo.require("dijit._base.scroll");
|
||||
dojo.require("dijit._base.sniff");
|
||||
dojo.require("dijit._base.bidi");
|
||||
dojo.require("dijit._base.typematic");
|
||||
dojo.require("dijit._base.wai");
|
||||
dojo.require("dijit._base.window");
|
||||
|
||||
}
|
||||
13
spring-faces/src/main/java/META-INF/dijit/_base/bidi.js
Normal file
13
spring-faces/src/main/java/META-INF/dijit/_base/bidi.js
Normal file
@@ -0,0 +1,13 @@
|
||||
if(!dojo._hasResource["dijit._base.bidi"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._base.bidi"] = true;
|
||||
dojo.provide("dijit._base.bidi");
|
||||
|
||||
// summary: applies a class to the top of the document for right-to-left stylesheet rules
|
||||
|
||||
dojo.addOnLoad(function(){
|
||||
if(!dojo._isBodyLtr()){
|
||||
dojo.addClass(dojo.body(), "dijitRtl");
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
327
spring-faces/src/main/java/META-INF/dijit/_base/focus.js
Normal file
327
spring-faces/src/main/java/META-INF/dijit/_base/focus.js
Normal file
@@ -0,0 +1,327 @@
|
||||
if(!dojo._hasResource["dijit._base.focus"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._base.focus"] = true;
|
||||
dojo.provide("dijit._base.focus");
|
||||
|
||||
// summary:
|
||||
// These functions are used to query or set the focus and selection.
|
||||
//
|
||||
// Also, they trace when widgets become actived/deactivated,
|
||||
// so that the widget can fire _onFocus/_onBlur events.
|
||||
// "Active" here means something similar to "focused", but
|
||||
// "focus" isn't quite the right word because we keep track of
|
||||
// a whole stack of "active" widgets. Example: Combobutton --> Menu -->
|
||||
// MenuItem. The onBlur event for Combobutton doesn't fire due to focusing
|
||||
// on the Menu or a MenuItem, since they are considered part of the
|
||||
// Combobutton widget. It only happens when focus is shifted
|
||||
// somewhere completely different.
|
||||
|
||||
dojo.mixin(dijit,
|
||||
{
|
||||
// _curFocus: DomNode
|
||||
// Currently focused item on screen
|
||||
_curFocus: null,
|
||||
|
||||
// _prevFocus: DomNode
|
||||
// Previously focused item on screen
|
||||
_prevFocus: null,
|
||||
|
||||
isCollapsed: function(){
|
||||
// summary: tests whether the current selection is empty
|
||||
var _window = dojo.global;
|
||||
var _document = dojo.doc;
|
||||
if(_document.selection){ // IE
|
||||
return !_document.selection.createRange().text; // Boolean
|
||||
}else if(_window.getSelection){
|
||||
var selection = _window.getSelection();
|
||||
if(dojo.isString(selection)){ // Safari
|
||||
return !selection; // Boolean
|
||||
}else{ // Mozilla/W3
|
||||
return selection.isCollapsed || !selection.toString(); // Boolean
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getBookmark: function(){
|
||||
// summary: Retrieves a bookmark that can be used with moveToBookmark to return to the same range
|
||||
var bookmark, selection = dojo.doc.selection;
|
||||
if(selection){ // IE
|
||||
var range = selection.createRange();
|
||||
if(selection.type.toUpperCase()=='CONTROL'){
|
||||
bookmark = range.length ? dojo._toArray(range) : null;
|
||||
}else{
|
||||
bookmark = range.getBookmark();
|
||||
}
|
||||
}else{
|
||||
if(dojo.global.getSelection){
|
||||
selection = dojo.global.getSelection();
|
||||
if(selection){
|
||||
var range = selection.getRangeAt(0);
|
||||
bookmark = range.cloneRange();
|
||||
}
|
||||
}else{
|
||||
console.debug("No idea how to store the current selection for this browser!");
|
||||
}
|
||||
}
|
||||
return bookmark; // Array
|
||||
},
|
||||
|
||||
moveToBookmark: function(/*Object*/bookmark){
|
||||
// summary: Moves current selection to a bookmark
|
||||
// bookmark: this should be a returned object from dojo.html.selection.getBookmark()
|
||||
var _document = dojo.doc;
|
||||
if(_document.selection){ // IE
|
||||
var range;
|
||||
if(dojo.isArray(bookmark)){
|
||||
range = _document.body.createControlRange();
|
||||
dojo.forEach(bookmark, range.addElement);
|
||||
}else{
|
||||
range = _document.selection.createRange();
|
||||
range.moveToBookmark(bookmark);
|
||||
}
|
||||
range.select();
|
||||
}else{ //Moz/W3C
|
||||
var selection = dojo.global.getSelection && dojo.global.getSelection();
|
||||
if(selection && selection.removeAllRanges){
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(bookmark);
|
||||
}else{
|
||||
console.debug("No idea how to restore selection for this browser!");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getFocus: function(/*Widget*/menu, /*Window*/ openedForWindow){
|
||||
// summary:
|
||||
// Returns the current focus and selection.
|
||||
// Called when a popup appears (either a top level menu or a dialog),
|
||||
// or when a toolbar/menubar receives focus
|
||||
//
|
||||
// menu:
|
||||
// the menu that's being opened
|
||||
//
|
||||
// openedForWindow:
|
||||
// iframe in which menu was opened
|
||||
//
|
||||
// returns:
|
||||
// a handle to restore focus/selection
|
||||
|
||||
return {
|
||||
// Node to return focus to
|
||||
node: menu && dojo.isDescendant(dijit._curFocus, menu.domNode) ? dijit._prevFocus : dijit._curFocus,
|
||||
|
||||
// Previously selected text
|
||||
bookmark:
|
||||
!dojo.withGlobal(openedForWindow||dojo.global, dijit.isCollapsed) ?
|
||||
dojo.withGlobal(openedForWindow||dojo.global, dijit.getBookmark) :
|
||||
null,
|
||||
|
||||
openedForWindow: openedForWindow
|
||||
}; // Object
|
||||
},
|
||||
|
||||
focus: function(/*Object || DomNode */ handle){
|
||||
// summary:
|
||||
// Sets the focused node and the selection according to argument.
|
||||
// To set focus to an iframe's content, pass in the iframe itself.
|
||||
// handle:
|
||||
// object returned by get(), or a DomNode
|
||||
|
||||
if(!handle){ return; }
|
||||
|
||||
var node = "node" in handle ? handle.node : handle, // because handle is either DomNode or a composite object
|
||||
bookmark = handle.bookmark,
|
||||
openedForWindow = handle.openedForWindow;
|
||||
|
||||
// Set the focus
|
||||
// Note that for iframe's we need to use the <iframe> to follow the parentNode chain,
|
||||
// but we need to set focus to iframe.contentWindow
|
||||
if(node){
|
||||
var focusNode = (node.tagName.toLowerCase()=="iframe") ? node.contentWindow : node;
|
||||
if(focusNode && focusNode.focus){
|
||||
try{
|
||||
// Gecko throws sometimes if setting focus is impossible,
|
||||
// node not displayed or something like that
|
||||
focusNode.focus();
|
||||
}catch(e){/*quiet*/}
|
||||
}
|
||||
dijit._onFocusNode(node);
|
||||
}
|
||||
|
||||
// set the selection
|
||||
// do not need to restore if current selection is not empty
|
||||
// (use keyboard to select a menu item)
|
||||
if(bookmark && dojo.withGlobal(openedForWindow||dojo.global, dijit.isCollapsed)){
|
||||
if(openedForWindow){
|
||||
openedForWindow.focus();
|
||||
}
|
||||
try{
|
||||
dojo.withGlobal(openedForWindow||dojo.global, moveToBookmark, null, [bookmark]);
|
||||
}catch(e){
|
||||
/*squelch IE internal error, see http://trac.dojotoolkit.org/ticket/1984 */
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// List of currently active widgets (focused widget and it's ancestors)
|
||||
_activeStack: [],
|
||||
|
||||
registerWin: function(/*Window?*/targetWindow){
|
||||
// summary:
|
||||
// Registers listeners on the specified window (either the main
|
||||
// window or an iframe) to detect when the user has clicked somewhere.
|
||||
// Anyone that creates an iframe should call this function.
|
||||
|
||||
if(!targetWindow){
|
||||
targetWindow = window;
|
||||
}
|
||||
|
||||
dojo.connect(targetWindow.document, "onmousedown", null, function(evt){
|
||||
// this mouse down event will probably be immediately followed by a blur event; ignore it
|
||||
dijit._ignoreNextBlurEvent = true;
|
||||
setTimeout(function(){ dijit._ignoreNextBlurEvent = false; }, 0);
|
||||
dijit._onTouchNode(evt.target||evt.srcElement);
|
||||
});
|
||||
//dojo.connect(targetWindow, "onscroll", ???);
|
||||
|
||||
// Listen for blur and focus events on targetWindow's body
|
||||
var body = targetWindow.document.body || targetWindow.document.getElementsByTagName("body")[0];
|
||||
if(body){
|
||||
if(dojo.isIE){
|
||||
body.attachEvent('onactivate', function(evt){
|
||||
if(evt.srcElement.tagName.toLowerCase() != "body"){
|
||||
dijit._onFocusNode(evt.srcElement);
|
||||
}
|
||||
});
|
||||
body.attachEvent('ondeactivate', function(evt){ dijit._onBlurNode(); });
|
||||
}else{
|
||||
body.addEventListener('focus', function(evt){ dijit._onFocusNode(evt.target); }, true);
|
||||
body.addEventListener('blur', function(evt){ dijit._onBlurNode(); }, true);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_onBlurNode: function(){
|
||||
// summary:
|
||||
// Called when focus leaves a node.
|
||||
// Usually ignored, _unless_ it *isn't* follwed by touching another node,
|
||||
// which indicates that we tabbed off the last field on the page,
|
||||
// in which case everything is blurred
|
||||
if(dijit._ignoreNextBlurEvent){
|
||||
dijit._ignoreNextBlurEvent = false;
|
||||
return;
|
||||
}
|
||||
dijit._prevFocus = dijit._curFocus;
|
||||
dijit._curFocus = null;
|
||||
if(dijit._blurAllTimer){
|
||||
clearTimeout(dijit._blurAllTimer);
|
||||
}
|
||||
dijit._blurAllTimer = setTimeout(function(){
|
||||
delete dijit._blurAllTimer; dijit._setStack([]); }, 100);
|
||||
},
|
||||
|
||||
_onTouchNode: function(/*DomNode*/ node){
|
||||
// summary
|
||||
// Callback when node is focused or mouse-downed
|
||||
|
||||
// ignore the recent blurNode event
|
||||
if(dijit._blurAllTimer){
|
||||
clearTimeout(dijit._blurAllTimer);
|
||||
delete dijit._blurAllTimer;
|
||||
}
|
||||
|
||||
// compute stack of active widgets (ex: ComboButton --> Menu --> MenuItem)
|
||||
var newStack=[];
|
||||
try{
|
||||
while(node){
|
||||
if(node.dijitPopupParent){
|
||||
node=dijit.byId(node.dijitPopupParent).domNode;
|
||||
}else if(node.tagName && node.tagName.toLowerCase()=="body"){
|
||||
// is this the root of the document or just the root of an iframe?
|
||||
if(node===dojo.body()){
|
||||
// node is the root of the main document
|
||||
break;
|
||||
}
|
||||
// otherwise, find the iframe this node refers to (can't access it via parentNode,
|
||||
// need to do this trick instead) and continue tracing up the document
|
||||
node=dojo.query("iframe").filter(function(iframe){ return iframe.contentDocument.body===node; })[0];
|
||||
}else{
|
||||
var id = node.getAttribute && node.getAttribute("widgetId");
|
||||
if(id){
|
||||
newStack.unshift(id);
|
||||
}
|
||||
node=node.parentNode;
|
||||
}
|
||||
}
|
||||
}catch(e){ /* squelch */ }
|
||||
|
||||
dijit._setStack(newStack);
|
||||
},
|
||||
|
||||
_onFocusNode: function(/*DomNode*/ node){
|
||||
// summary
|
||||
// Callback when node is focused
|
||||
if(node && node.tagName && node.tagName.toLowerCase() == "body"){
|
||||
return;
|
||||
}
|
||||
dijit._onTouchNode(node);
|
||||
if(node==dijit._curFocus){ return; }
|
||||
dijit._prevFocus = dijit._curFocus;
|
||||
dijit._curFocus = node;
|
||||
dojo.publish("focusNode", [node]);
|
||||
|
||||
// handle focus/blur styling
|
||||
var w = dijit.byId(node.id);
|
||||
if (w && w._setStateClass){
|
||||
w._focused = true;
|
||||
w._setStateClass();
|
||||
// watch for a blur on the node that received focus
|
||||
var blurConnector = dojo.connect(node, "onblur", function(){
|
||||
w._focused = false;
|
||||
w._setStateClass();
|
||||
dojo.disconnect(blurConnector);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_setStack: function(newStack){
|
||||
// summary
|
||||
// The stack of active widgets has changed. Send out appropriate events and record new stack
|
||||
|
||||
var oldStack = dijit._activeStack;
|
||||
dijit._activeStack = newStack;
|
||||
|
||||
// compare old stack to new stack to see how many elements they have in common
|
||||
for(var nCommon=0; nCommon<Math.min(oldStack.length, newStack.length); nCommon++){
|
||||
if(oldStack[nCommon] != newStack[nCommon]){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// for all elements that have gone out of focus, send blur event
|
||||
for(var i=oldStack.length-1; i>=nCommon; i--){
|
||||
var widget = dijit.byId(oldStack[i]);
|
||||
if(widget){
|
||||
dojo.publish("widgetBlur", [widget]);
|
||||
if(widget._onBlur){
|
||||
widget._onBlur();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for all element that have come into focus, send focus event
|
||||
for(var i=nCommon; i<newStack.length; i++){
|
||||
var widget = dijit.byId(newStack[i]);
|
||||
if(widget){
|
||||
dojo.publish("widgetFocus", [widget]);
|
||||
if(widget._onFocus){
|
||||
widget._onFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// register top window and all the iframes it contains
|
||||
dojo.addOnLoad(dijit.registerWin);
|
||||
|
||||
}
|
||||
82
spring-faces/src/main/java/META-INF/dijit/_base/manager.js
Normal file
82
spring-faces/src/main/java/META-INF/dijit/_base/manager.js
Normal file
@@ -0,0 +1,82 @@
|
||||
if(!dojo._hasResource["dijit._base.manager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._base.manager"] = true;
|
||||
dojo.provide("dijit._base.manager");
|
||||
|
||||
dojo.declare("dijit.WidgetSet", null, {
|
||||
constructor: function(){
|
||||
// summary:
|
||||
// A set of widgets indexed by id
|
||||
this._hash={};
|
||||
},
|
||||
|
||||
add: function(/*Widget*/ widget){
|
||||
this._hash[widget.id]=widget;
|
||||
},
|
||||
|
||||
remove: function(/*String*/ id){
|
||||
delete this._hash[id];
|
||||
},
|
||||
|
||||
forEach: function(/*Function*/ func){
|
||||
for(var id in this._hash){
|
||||
func(this._hash[id]);
|
||||
}
|
||||
},
|
||||
|
||||
filter: function(/*Function*/ filter){
|
||||
var res = new dijit.WidgetSet();
|
||||
this.forEach(function(widget){
|
||||
if(filter(widget)){ res.add(widget); }
|
||||
});
|
||||
return res; // dijit.WidgetSet
|
||||
},
|
||||
|
||||
byId: function(/*String*/ id){
|
||||
return this._hash[id];
|
||||
},
|
||||
|
||||
byClass: function(/*String*/ cls){
|
||||
return this.filter(function(widget){ return widget.declaredClass==cls; }); // dijit.WidgetSet
|
||||
}
|
||||
});
|
||||
|
||||
// registry: list of all widgets on page
|
||||
dijit.registry = new dijit.WidgetSet();
|
||||
|
||||
dijit._widgetTypeCtr = {};
|
||||
|
||||
dijit.getUniqueId = function(/*String*/widgetType){
|
||||
// summary
|
||||
// Generates a unique id for a given widgetType
|
||||
|
||||
var id;
|
||||
do{
|
||||
id = widgetType + "_" +
|
||||
(dijit._widgetTypeCtr[widgetType] !== undefined ?
|
||||
++dijit._widgetTypeCtr[widgetType] : dijit._widgetTypeCtr[widgetType] = 0);
|
||||
}while(dijit.byId(id));
|
||||
return id; // String
|
||||
};
|
||||
|
||||
|
||||
if(dojo.isIE){
|
||||
// Only run this for IE because we think it's only necessary in that case,
|
||||
// and because it causes problems on FF. See bug #3531 for details.
|
||||
dojo.addOnUnload(function(){
|
||||
dijit.registry.forEach(function(widget){ widget.destroy(); });
|
||||
});
|
||||
}
|
||||
|
||||
dijit.byId = function(/*String|Widget*/id){
|
||||
// summary:
|
||||
// Returns a widget by its id, or if passed a widget, no-op (like dojo.byId())
|
||||
return (dojo.isString(id)) ? dijit.registry.byId(id) : id; // Widget
|
||||
};
|
||||
|
||||
dijit.byNode = function(/* DOMNode */ node){
|
||||
// summary:
|
||||
// Returns the widget as referenced by node
|
||||
return dijit.registry.byId(node.getAttribute("widgetId")); // Widget
|
||||
};
|
||||
|
||||
}
|
||||
188
spring-faces/src/main/java/META-INF/dijit/_base/place.js
Normal file
188
spring-faces/src/main/java/META-INF/dijit/_base/place.js
Normal file
@@ -0,0 +1,188 @@
|
||||
if(!dojo._hasResource["dijit._base.place"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._base.place"] = true;
|
||||
dojo.provide("dijit._base.place");
|
||||
|
||||
// ported from dojo.html.util
|
||||
|
||||
dijit.getViewport = function(){
|
||||
// summary
|
||||
// Returns the dimensions and scroll position of the viewable area of a browser window
|
||||
|
||||
var _window = dojo.global;
|
||||
var _document = dojo.doc;
|
||||
|
||||
// get viewport size
|
||||
var w = 0, h = 0;
|
||||
if(dojo.isMozilla){
|
||||
// mozilla
|
||||
w = _document.documentElement.clientWidth;
|
||||
h = _window.innerHeight;
|
||||
}else if(!dojo.isOpera && _window.innerWidth){
|
||||
//in opera9, dojo.body().clientWidth should be used, instead
|
||||
//of window.innerWidth/document.documentElement.clientWidth
|
||||
//so we have to check whether it is opera
|
||||
w = _window.innerWidth;
|
||||
h = _window.innerHeight;
|
||||
}else if(dojo.isIE && _document.documentElement && _document.documentElement.clientHeight){
|
||||
w = _document.documentElement.clientWidth;
|
||||
h = _document.documentElement.clientHeight;
|
||||
}else if(dojo.body().clientWidth){
|
||||
// IE5, Opera
|
||||
w = dojo.body().clientWidth;
|
||||
h = dojo.body().clientHeight;
|
||||
}
|
||||
|
||||
// get scroll position
|
||||
var scroll = dojo._docScroll();
|
||||
|
||||
return { w: w, h: h, l: scroll.x, t: scroll.y }; // object
|
||||
};
|
||||
|
||||
dijit.placeOnScreen = function(
|
||||
/* HTMLElement */ node,
|
||||
/* Object */ pos,
|
||||
/* Object */ corners,
|
||||
/* boolean? */ tryOnly){
|
||||
// summary:
|
||||
// Keeps 'node' in the visible area of the screen while trying to
|
||||
// place closest to pos.x, pos.y. The input coordinates are
|
||||
// expected to be the desired document position.
|
||||
//
|
||||
// Set which corner(s) you want to bind to, such as
|
||||
//
|
||||
// placeOnScreen(node, {x: 10, y: 20}, ["TR", "BL"])
|
||||
//
|
||||
// The desired x/y will be treated as the topleft(TL)/topright(TR) or
|
||||
// BottomLeft(BL)/BottomRight(BR) corner of the node. Each corner is tested
|
||||
// and if a perfect match is found, it will be used. Otherwise, it goes through
|
||||
// all of the specified corners, and choose the most appropriate one.
|
||||
//
|
||||
// NOTE: node is assumed to be absolutely or relatively positioned.
|
||||
|
||||
var choices = dojo.map(corners, function(corner){ return { corner: corner, pos: pos }; });
|
||||
|
||||
return dijit._place(node, choices);
|
||||
}
|
||||
|
||||
dijit._place = function(/*HtmlElement*/ node, /* Array */ choices, /* Function */ layoutNode){
|
||||
// summary:
|
||||
// Given a list of spots to put node, put it at the first spot where it fits,
|
||||
// of if it doesn't fit anywhere then the place with the least overflow
|
||||
// choices: Array
|
||||
// Array of elements like: {corner: 'TL', pos: {x: 10, y: 20} }
|
||||
// Above example says to put the top-left corner of the node at (10,20)
|
||||
// layoutNode: Function(node, orient)
|
||||
// for things like tooltip, they are displayed differently (and have different dimensions)
|
||||
// based on their orientation relative to the parent. This adjusts the popup based on orientation.
|
||||
|
||||
// get {x: 10, y: 10, w: 100, h:100} type obj representing position of
|
||||
// viewport over document
|
||||
var view = dijit.getViewport();
|
||||
|
||||
// This won't work if the node is inside a <div style="position: relative">,
|
||||
// so reattach it to document.body. (Otherwise, the positioning will be wrong
|
||||
// and also it might get cutoff)
|
||||
if(!node.parentNode || String(node.parentNode.tagName).toLowerCase() != "body"){
|
||||
dojo.body().appendChild(node);
|
||||
}
|
||||
|
||||
var best=null;
|
||||
for(var i=0; i<choices.length; i++){
|
||||
var corner = choices[i].corner;
|
||||
var pos = choices[i].pos;
|
||||
|
||||
// configure node to be displayed in given position relative to button
|
||||
// (need to do this in order to get an accurate size for the node, because
|
||||
// a tooltips size changes based on position, due to triangle)
|
||||
if(layoutNode){
|
||||
layoutNode(corner);
|
||||
}
|
||||
|
||||
// get node's size
|
||||
var oldDisplay = node.style.display;
|
||||
var oldVis = node.style.visibility;
|
||||
node.style.visibility = "hidden";
|
||||
node.style.display = "";
|
||||
var mb = dojo.marginBox(node);
|
||||
node.style.display = oldDisplay;
|
||||
node.style.visibility = oldVis;
|
||||
|
||||
// coordinates and size of node with specified corner placed at pos,
|
||||
// and clipped by viewport
|
||||
var startX = (corner.charAt(1)=='L' ? pos.x : Math.max(view.l, pos.x - mb.w)),
|
||||
startY = (corner.charAt(0)=='T' ? pos.y : Math.max(view.t, pos.y - mb.h)),
|
||||
endX = (corner.charAt(1)=='L' ? Math.min(view.l+view.w, startX+mb.w) : pos.x),
|
||||
endY = (corner.charAt(0)=='T' ? Math.min(view.t+view.h, startY+mb.h) : pos.y),
|
||||
width = endX-startX,
|
||||
height = endY-startY,
|
||||
overflow = (mb.w-width) + (mb.h-height);
|
||||
|
||||
if(best==null || overflow<best.overflow){
|
||||
best = {
|
||||
corner: corner,
|
||||
aroundCorner: choices[i].aroundCorner,
|
||||
x: startX,
|
||||
y: startY,
|
||||
w: width,
|
||||
h: height,
|
||||
overflow: overflow
|
||||
};
|
||||
}
|
||||
if(overflow==0){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
node.style.left = best.x + "px";
|
||||
node.style.top = best.y + "px";
|
||||
return best;
|
||||
}
|
||||
|
||||
dijit.placeOnScreenAroundElement = function(
|
||||
/* HTMLElement */ node,
|
||||
/* HTMLElement */ aroundNode,
|
||||
/* Object */ aroundCorners,
|
||||
/* Function */ layoutNode){
|
||||
|
||||
// summary
|
||||
// Like placeOnScreen, except it accepts aroundNode instead of x,y
|
||||
// and attempts to place node around it. Uses margin box dimensions.
|
||||
//
|
||||
// aroundCorners
|
||||
// specify Which corner of aroundNode should be
|
||||
// used to place the node => which corner(s) of node to use (see the
|
||||
// corners parameter in dijit.placeOnScreen)
|
||||
// e.g. {'TL': 'BL', 'BL': 'TL'}
|
||||
//
|
||||
// layoutNode: Function(node, orient)
|
||||
// for things like tooltip, they are displayed differently (and have different dimensions)
|
||||
// based on their orientation relative to the parent. This adjusts the popup based on orientation.
|
||||
|
||||
|
||||
// get coordinates of aroundNode
|
||||
aroundNode = dojo.byId(aroundNode);
|
||||
var oldDisplay = aroundNode.style.display;
|
||||
aroundNode.style.display="";
|
||||
// #3172: use the slightly tighter border box instead of marginBox
|
||||
var aroundNodeW = aroundNode.offsetWidth; //mb.w;
|
||||
var aroundNodeH = aroundNode.offsetHeight; //mb.h;
|
||||
var aroundNodePos = dojo.coords(aroundNode, true);
|
||||
aroundNode.style.display=oldDisplay;
|
||||
|
||||
// Generate list of possible positions for node
|
||||
var choices = [];
|
||||
for(var nodeCorner in aroundCorners){
|
||||
choices.push( {
|
||||
aroundCorner: nodeCorner,
|
||||
corner: aroundCorners[nodeCorner],
|
||||
pos: {
|
||||
x: aroundNodePos.x + (nodeCorner.charAt(1)=='L' ? 0 : aroundNodeW),
|
||||
y: aroundNodePos.y + (nodeCorner.charAt(0)=='T' ? 0 : aroundNodeH)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return dijit._place(node, choices, layoutNode);
|
||||
}
|
||||
|
||||
}
|
||||
249
spring-faces/src/main/java/META-INF/dijit/_base/popup.js
Normal file
249
spring-faces/src/main/java/META-INF/dijit/_base/popup.js
Normal file
@@ -0,0 +1,249 @@
|
||||
if(!dojo._hasResource["dijit._base.popup"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._base.popup"] = true;
|
||||
dojo.provide("dijit._base.popup");
|
||||
|
||||
dojo.require("dijit._base.focus");
|
||||
dojo.require("dijit._base.place");
|
||||
dojo.require("dijit._base.window");
|
||||
|
||||
dijit.popup = new function(){
|
||||
// summary:
|
||||
// This class is used to show/hide widgets as popups.
|
||||
//
|
||||
|
||||
var stack = [],
|
||||
beginZIndex=1000,
|
||||
idGen = 1;
|
||||
|
||||
this.open = function(/*Object*/ args){
|
||||
// summary:
|
||||
// Popup the widget at the specified position
|
||||
//
|
||||
// args: Object
|
||||
// popup: Widget
|
||||
// widget to display,
|
||||
// parent: Widget
|
||||
// the button etc. that is displaying this popup
|
||||
// around: DomNode
|
||||
// DOM node (typically a button); place popup relative to this node
|
||||
// orient: Object
|
||||
// structure specifying possible positions of popup relative to "around" node
|
||||
// onCancel: Function
|
||||
// callback when user has canceled the popup by
|
||||
// 1. hitting ESC or
|
||||
// 2. by using the popup widget's proprietary cancel mechanism (like a cancel button in a dialog);
|
||||
// ie: whenever popupWidget.onCancel() is called, args.onCancel is called
|
||||
// onClose: Function
|
||||
// callback whenever this popup is closed (via close(), closeAll(), or closeTo())
|
||||
// submenu: Boolean
|
||||
// Is this a submenu off of the existing popup?
|
||||
// onExecute: Function
|
||||
// callback when user "executed" on the popup/sub-popup by selecting a menu choice, etc. (top menu only)
|
||||
//
|
||||
// examples:
|
||||
// 1. opening at the mouse position
|
||||
// dijit.popup.open({popup: menuWidget, x: evt.pageX, y: evt.pageY});
|
||||
// 2. opening the widget as a dropdown
|
||||
// dijit.popup.open({parent: this, popup: menuWidget, around: this.domNode, onClose: function(){...} });
|
||||
//
|
||||
// Note that whatever widget called dijit.popup.open() should also listen to it's own _onBlur callback
|
||||
// (fired from _base/focus.js) to know that focus has moved somewhere else and thus the popup should be closed.
|
||||
|
||||
var widget = args.popup,
|
||||
orient = args.orient || {'BL':'TL', 'TL':'BL'},
|
||||
around = args.around,
|
||||
id = (args.around && args.around.id) ? (args.around.id+"_dropdown") : ("popup_"+idGen++);
|
||||
|
||||
if(!args.submenu){
|
||||
this.closeAll();
|
||||
}
|
||||
|
||||
// make wrapper div to hold widget and possibly hold iframe behind it.
|
||||
// we can't attach the iframe as a child of the widget.domNode because
|
||||
// widget.domNode might be a <table>, <ul>, etc.
|
||||
var wrapper = dojo.doc.createElement("div");
|
||||
wrapper.id = id;
|
||||
wrapper.className="dijitPopup";
|
||||
wrapper.style.zIndex = beginZIndex + stack.length;
|
||||
if(args.parent){
|
||||
wrapper.dijitPopupParent=args.parent.id;
|
||||
}
|
||||
dojo.body().appendChild(wrapper);
|
||||
|
||||
widget.domNode.style.display="";
|
||||
wrapper.appendChild(widget.domNode);
|
||||
|
||||
var iframe = new dijit.BackgroundIframe(wrapper);
|
||||
|
||||
// position the wrapper node
|
||||
var best = around ?
|
||||
dijit.placeOnScreenAroundElement(wrapper, around, orient, widget.orient ? dojo.hitch(widget, "orient") : null) :
|
||||
dijit.placeOnScreen(wrapper, args, orient == 'R' ? ['TR','BR','TL','BL'] : ['TL','BL','TR','BR']);
|
||||
|
||||
// TODO: use effects to fade in wrapper
|
||||
|
||||
var handlers = [];
|
||||
|
||||
// provide default escape key handling
|
||||
handlers.push(dojo.connect(wrapper, "onkeypress", this, function(evt){
|
||||
if (evt.keyCode == dojo.keys.ESCAPE){
|
||||
args.onCancel();
|
||||
}
|
||||
}));
|
||||
|
||||
// watch for cancel/execute events on the popup and notify the caller
|
||||
// (for a menu, "execute" means clicking an item)
|
||||
if(widget.onCancel){
|
||||
handlers.push(dojo.connect(widget, "onCancel", null, args.onCancel));
|
||||
}
|
||||
|
||||
handlers.push(dojo.connect(widget, widget.onExecute ? "onExecute" : "onChange", null, function(){
|
||||
if(stack[0] && stack[0].onExecute){
|
||||
stack[0].onExecute();
|
||||
}
|
||||
}));
|
||||
|
||||
stack.push({
|
||||
wrapper: wrapper,
|
||||
iframe: iframe,
|
||||
widget: widget,
|
||||
onExecute: args.onExecute,
|
||||
onCancel: args.onCancel,
|
||||
onClose: args.onClose,
|
||||
handlers: handlers
|
||||
});
|
||||
|
||||
if(widget.onOpen){
|
||||
widget.onOpen(best);
|
||||
}
|
||||
|
||||
return best;
|
||||
};
|
||||
|
||||
this.close = function(){
|
||||
// summary:
|
||||
// Close popup on the top of the stack (the highest z-index popup)
|
||||
|
||||
// this needs to happen before the stack is popped, because menu's
|
||||
// onClose calls closeTo(this)
|
||||
var widget = stack[stack.length-1].widget;
|
||||
if(widget.onClose){
|
||||
widget.onClose();
|
||||
}
|
||||
|
||||
if(!stack.length){
|
||||
return;
|
||||
}
|
||||
var top = stack.pop();
|
||||
var wrapper = top.wrapper,
|
||||
iframe = top.iframe,
|
||||
widget = top.widget,
|
||||
onClose = top.onClose;
|
||||
|
||||
dojo.forEach(top.handlers, dojo.disconnect);
|
||||
|
||||
// #2685: check if the widget still has a domNode so ContentPane can change its URL without getting an error
|
||||
if(!widget||!widget.domNode){ return; }
|
||||
dojo.style(widget.domNode, "display", "none");
|
||||
dojo.body().appendChild(widget.domNode);
|
||||
iframe.destroy();
|
||||
dojo._destroyElement(wrapper);
|
||||
|
||||
if(onClose){
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
|
||||
this.closeAll = function(){
|
||||
// summary: close every popup, from top of stack down to the first one
|
||||
while(stack.length){
|
||||
this.close();
|
||||
}
|
||||
};
|
||||
|
||||
this.closeTo = function(/*Widget*/ widget){
|
||||
// summary: closes every popup above specified widget
|
||||
while(stack.length && stack[stack.length-1].widget.id != widget.id){
|
||||
this.close();
|
||||
}
|
||||
};
|
||||
|
||||
}();
|
||||
|
||||
dijit._frames = new function(){
|
||||
// summary: cache of iframes
|
||||
var queue = [];
|
||||
|
||||
this.pop = function(){
|
||||
var iframe;
|
||||
if(queue.length){
|
||||
iframe = queue.pop();
|
||||
iframe.style.display="";
|
||||
}else{
|
||||
if(dojo.isIE){
|
||||
var html="<iframe src='javascript:\"\"'"
|
||||
+ " style='position: absolute; left: 0px; top: 0px;"
|
||||
+ "z-index: -1; filter:Alpha(Opacity=\"0\");'>";
|
||||
iframe = dojo.doc.createElement(html);
|
||||
}else{
|
||||
var iframe = dojo.doc.createElement("iframe");
|
||||
iframe.src = 'javascript:""';
|
||||
iframe.className = "dijitBackgroundIframe";
|
||||
}
|
||||
iframe.tabIndex = -1; // Magic to prevent iframe from getting focus on tab keypress - as style didnt work.
|
||||
dojo.body().appendChild(iframe);
|
||||
}
|
||||
return iframe;
|
||||
};
|
||||
|
||||
this.push = function(iframe){
|
||||
iframe.style.display="";
|
||||
if(dojo.isIE){
|
||||
iframe.style.removeExpression("width");
|
||||
iframe.style.removeExpression("height");
|
||||
}
|
||||
queue.push(iframe);
|
||||
}
|
||||
}();
|
||||
|
||||
// fill the queue
|
||||
if(dojo.isIE && dojo.isIE < 7){
|
||||
dojo.addOnLoad(function(){
|
||||
var f = dijit._frames;
|
||||
dojo.forEach([f.pop()], f.push);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
dijit.BackgroundIframe = function(/* HTMLElement */node){
|
||||
// summary:
|
||||
// For IE z-index schenanigans. id attribute is required.
|
||||
//
|
||||
// description:
|
||||
// new dijit.BackgroundIframe(node)
|
||||
// Makes a background iframe as a child of node, that fills
|
||||
// area (and position) of node
|
||||
|
||||
if(!node.id){ throw new Error("no id"); }
|
||||
if((dojo.isIE && dojo.isIE < 7) || (dojo.isFF && dojo.isFF < 3 && dojo.hasClass(dojo.body(), "dijit_a11y"))){
|
||||
var iframe = dijit._frames.pop();
|
||||
node.appendChild(iframe);
|
||||
if(dojo.isIE){
|
||||
iframe.style.setExpression("width", "document.getElementById('" + node.id + "').offsetWidth");
|
||||
iframe.style.setExpression("height", "document.getElementById('" + node.id + "').offsetHeight");
|
||||
}
|
||||
this.iframe = iframe;
|
||||
}
|
||||
};
|
||||
|
||||
dojo.extend(dijit.BackgroundIframe, {
|
||||
destroy: function(){
|
||||
// summary: destroy the iframe
|
||||
if(this.iframe){
|
||||
dijit._frames.push(this.iframe);
|
||||
delete this.iframe;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
33
spring-faces/src/main/java/META-INF/dijit/_base/scroll.js
Normal file
33
spring-faces/src/main/java/META-INF/dijit/_base/scroll.js
Normal file
@@ -0,0 +1,33 @@
|
||||
if(!dojo._hasResource["dijit._base.scroll"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._base.scroll"] = true;
|
||||
dojo.provide("dijit._base.scroll");
|
||||
|
||||
dijit.scrollIntoView = function(/* HTMLElement */node){
|
||||
// summary
|
||||
// Scroll the passed node into view, if it is not.
|
||||
|
||||
// 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.isIE){
|
||||
//only call scrollIntoView if there is a scrollbar for this menu,
|
||||
//otherwise, scrollIntoView will scroll the window scrollbar
|
||||
if(dojo.marginBox(node.parentNode).h <= node.parentNode.scrollHeight){ //PORT was getBorderBox
|
||||
node.scrollIntoView(false);
|
||||
}
|
||||
}else if(dojo.isMozilla){
|
||||
node.scrollIntoView(false);
|
||||
}else{
|
||||
var parent = node.parentNode;
|
||||
var parentBottom = parent.scrollTop + dojo.marginBox(parent).h; //PORT was getBorderBox
|
||||
var nodeBottom = node.offsetTop + dojo.marginBox(node).h;
|
||||
if(parentBottom < nodeBottom){
|
||||
parent.scrollTop += (nodeBottom - parentBottom);
|
||||
}else if(parent.scrollTop > node.offsetTop){
|
||||
parent.scrollTop -= (parent.scrollTop - node.offsetTop);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
43
spring-faces/src/main/java/META-INF/dijit/_base/sniff.js
Normal file
43
spring-faces/src/main/java/META-INF/dijit/_base/sniff.js
Normal file
@@ -0,0 +1,43 @@
|
||||
if(!dojo._hasResource["dijit._base.sniff"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._base.sniff"] = true;
|
||||
dojo.provide("dijit._base.sniff");
|
||||
|
||||
// ported from dojo.html.applyBrowserClass (style.js)
|
||||
|
||||
// summary:
|
||||
// Applies pre-set class names based on browser & version to the
|
||||
// top-level HTML node. Simply doing a require on this module will
|
||||
// establish this CSS. Modified version of Morris' CSS hack.
|
||||
(function(){
|
||||
var d = dojo;
|
||||
var ie = d.isIE;
|
||||
var opera = d.isOpera;
|
||||
var maj = Math.floor;
|
||||
var classes = {
|
||||
dj_ie: ie,
|
||||
// dj_ie55: ie == 5.5,
|
||||
dj_ie6: maj(ie) == 6,
|
||||
dj_ie7: maj(ie) == 7,
|
||||
dj_iequirks: ie && d.isQuirks,
|
||||
// NOTE: Opera not supported by dijit
|
||||
dj_opera: opera,
|
||||
dj_opera8: maj(opera) == 8,
|
||||
dj_opera9: maj(opera) == 9,
|
||||
dj_khtml: d.isKhtml,
|
||||
dj_safari: d.isSafari,
|
||||
dj_gecko: d.isMozilla
|
||||
}; // no dojo unsupported browsers
|
||||
|
||||
for(var p in classes){
|
||||
if(classes[p]){
|
||||
var html = dojo.doc.documentElement; //TODO browser-specific DOM magic needed?
|
||||
if(html.className){
|
||||
html.className += " " + p;
|
||||
}else{
|
||||
html.className = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
}
|
||||
132
spring-faces/src/main/java/META-INF/dijit/_base/typematic.js
Normal file
132
spring-faces/src/main/java/META-INF/dijit/_base/typematic.js
Normal file
@@ -0,0 +1,132 @@
|
||||
if(!dojo._hasResource["dijit._base.typematic"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._base.typematic"] = true;
|
||||
dojo.provide("dijit._base.typematic");
|
||||
|
||||
dijit.typematic = {
|
||||
// summary:
|
||||
// These functions are used to repetitively call a user specified callback
|
||||
// method when a specific key or mouse click over a specific DOM node is
|
||||
// held down for a specific amount of time.
|
||||
// Only 1 such event is allowed to occur on the browser page at 1 time.
|
||||
|
||||
_fireEventAndReload: function(){
|
||||
this._timer = null;
|
||||
this._callback(++this._count, this._node, this._evt);
|
||||
this._currentTimeout = (this._currentTimeout < 0) ? this._initialDelay : ((this._subsequentDelay > 1) ? this._subsequentDelay : Math.round(this._currentTimeout * this._subsequentDelay));
|
||||
this._timer = setTimeout(dojo.hitch(this, "_fireEventAndReload"), this._currentTimeout);
|
||||
},
|
||||
|
||||
trigger: function(/*Event*/ evt, /* Object */ _this, /*DOMNode*/ node, /* Function */ callback, /* Object */ obj, /* Number */ subsequentDelay, /* Number */ initialDelay){
|
||||
// summary:
|
||||
// Start a timed, repeating callback sequence.
|
||||
// If already started, the function call is ignored.
|
||||
// This method is not normally called by the user but can be
|
||||
// when the normal listener code is insufficient.
|
||||
// _this: pointer to the user's widget space.
|
||||
// callback: function name to call until the sequence is stopped.
|
||||
// obj: any user space object to pass to the callback.
|
||||
// subsequentDelay: if > 1, the number of milliseconds until the 3->n events occur
|
||||
// or else the fractional time multiplier for the next event.
|
||||
// initialDelay: the number of milliseconds until the 2nd event occurs.
|
||||
if (obj != this._obj){
|
||||
this.stop();
|
||||
this._initialDelay = initialDelay ? initialDelay : 500;
|
||||
this._subsequentDelay = subsequentDelay ? subsequentDelay : 0.90;
|
||||
this._obj = obj;
|
||||
this._evt = evt;
|
||||
this._node = node;
|
||||
this._currentTimeout = -1;
|
||||
this._count = -1;
|
||||
this._callback = dojo.hitch(_this, callback);
|
||||
this._fireEventAndReload();
|
||||
}
|
||||
},
|
||||
|
||||
stop: function(){
|
||||
// summary:
|
||||
// Stop an ongoing timed, repeating callback sequence.
|
||||
if(this._timer){
|
||||
clearTimeout(this._timer);
|
||||
this._timer = null;
|
||||
}
|
||||
if(this._obj){
|
||||
this._callback(-1, this._node, this._evt);
|
||||
this._obj = null;
|
||||
}
|
||||
},
|
||||
|
||||
addKeyListener: function(/*DOMNode*/ node, /*Object*/ keyObject, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay){
|
||||
// summary: Start listening for a specific typematic key.
|
||||
// node: the DOM node object to listen on for key events.
|
||||
// keyObject: an object defining the key to listen for.
|
||||
// key: (mandatory) the keyCode (number) or character (string) to listen for.
|
||||
// ctrlKey: desired ctrl key state to initiate the calback sequence:
|
||||
// pressed (true)
|
||||
// released (false)
|
||||
// either (unspecified)
|
||||
// altKey: same as ctrlKey but for the alt key
|
||||
// shiftKey: same as ctrlKey but for the shift key
|
||||
// See the trigger method for other parameters.
|
||||
var ary = [];
|
||||
ary.push(dojo.connect(node, "onkeypress", this, function(evt){
|
||||
if(evt.keyCode == keyObject.keyCode && (!keyObject.charCode || keyObject.charCode == evt.charCode)
|
||||
&& ((typeof keyObject.ctrlKey == "undefined") || keyObject.ctrlKey == evt.ctrlKey)
|
||||
&& ((typeof keyObject.altKey == "undefined") || keyObject.altKey == evt.ctrlKey)
|
||||
&& ((typeof keyObject.shiftKey == "undefined") || keyObject.shiftKey == evt.ctrlKey)){
|
||||
dojo.stopEvent(evt);
|
||||
dijit.typematic.trigger(keyObject, _this, node, callback, keyObject, subsequentDelay, initialDelay);
|
||||
}else if (dijit.typematic._obj == keyObject){
|
||||
dijit.typematic.stop();
|
||||
}
|
||||
}));
|
||||
ary.push(dojo.connect(node, "onkeyup", this, function(evt){
|
||||
if(dijit.typematic._obj == keyObject){
|
||||
dijit.typematic.stop();
|
||||
}
|
||||
}));
|
||||
return ary;
|
||||
},
|
||||
|
||||
addMouseListener: function(/*DOMNode*/ node, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay){
|
||||
// summary: Start listening for a typematic mouse click.
|
||||
// node: the DOM node object to listen on for mouse events.
|
||||
// See the trigger method for other parameters.
|
||||
var ary = [];
|
||||
ary.push(dojo.connect(node, "mousedown", this, function(evt){
|
||||
dojo.stopEvent(evt);
|
||||
dijit.typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay);
|
||||
}));
|
||||
ary.push(dojo.connect(node, "mouseup", this, function(evt){
|
||||
dojo.stopEvent(evt);
|
||||
dijit.typematic.stop();
|
||||
}));
|
||||
ary.push(dojo.connect(node, "mouseout", this, function(evt){
|
||||
dojo.stopEvent(evt);
|
||||
dijit.typematic.stop();
|
||||
}));
|
||||
ary.push(dojo.connect(node, "mousemove", this, function(evt){
|
||||
dojo.stopEvent(evt);
|
||||
}));
|
||||
ary.push(dojo.connect(node, "dblclick", this, function(evt){
|
||||
dojo.stopEvent(evt);
|
||||
if(dojo.isIE){
|
||||
dijit.typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay);
|
||||
setTimeout("dijit.typematic.stop()",50);
|
||||
}
|
||||
}));
|
||||
return ary;
|
||||
},
|
||||
|
||||
addListener: function(/*Node*/ mouseNode, /*Node*/ keyNode, /*Object*/ keyObject, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay){
|
||||
// summary: Start listening for a specific typematic key and mouseclick.
|
||||
// This is a thin wrapper to addKeyListener and addMouseListener.
|
||||
// mouseNode: the DOM node object to listen on for mouse events.
|
||||
// keyNode: the DOM node object to listen on for key events.
|
||||
// The mouseNode is used as the callback obj parameter.
|
||||
// See the trigger method for other parameters.
|
||||
return this.addKeyListener(keyNode, keyObject, _this, callback, subsequentDelay, initialDelay).concat(
|
||||
this.addMouseListener(mouseNode, _this, callback, subsequentDelay, initialDelay));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
121
spring-faces/src/main/java/META-INF/dijit/_base/wai.js
Normal file
121
spring-faces/src/main/java/META-INF/dijit/_base/wai.js
Normal file
@@ -0,0 +1,121 @@
|
||||
if(!dojo._hasResource["dijit._base.wai"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._base.wai"] = true;
|
||||
dojo.provide("dijit._base.wai");
|
||||
|
||||
dijit.waiNames = ["waiRole", "waiState"];
|
||||
|
||||
dijit.wai = {
|
||||
// summary: Contains functions to set accessibility roles and states
|
||||
// onto widget elements
|
||||
waiRole: {
|
||||
// name: String:
|
||||
// information for mapping accessibility role
|
||||
name: "waiRole",
|
||||
// namespace: String:
|
||||
// URI of the namespace for the set of roles
|
||||
"namespace": "http://www.w3.org/TR/xhtml2",
|
||||
// alias: String:
|
||||
// The alias to assign the namespace
|
||||
alias: "x2",
|
||||
// prefix: String:
|
||||
// The prefix to assign to the role value
|
||||
prefix: "wairole:"
|
||||
},
|
||||
waiState: {
|
||||
// name: String:
|
||||
// information for mapping accessibility state
|
||||
name: "waiState",
|
||||
// namespace: String:
|
||||
// URI of the namespace for the set of states
|
||||
"namespace": "http://www.w3.org/2005/07/aaa",
|
||||
// alias: String:
|
||||
// The alias to assign the namespace
|
||||
alias: "aaa",
|
||||
// prefix: String:
|
||||
// empty string - state value does not require prefix
|
||||
prefix: ""
|
||||
},
|
||||
setAttr: function(/*DomNode*/node, /*String*/ ns, /*String*/ attr, /*String|Boolean*/value){
|
||||
// summary: Use appropriate API to set the role or state attribute onto the element.
|
||||
// description: In IE use the generic setAttribute() api. Append a namespace
|
||||
// alias to the attribute name and appropriate prefix to the value.
|
||||
// Otherwise, use the setAttribueNS api to set the namespaced attribute. Also
|
||||
// add the appropriate prefix to the attribute value.
|
||||
if(dojo.isIE){
|
||||
node.setAttribute(this[ns].alias+":"+ attr, this[ns].prefix+value);
|
||||
}else{
|
||||
node.setAttributeNS(this[ns]["namespace"], attr, this[ns].prefix+value);
|
||||
}
|
||||
},
|
||||
|
||||
getAttr: function(/*DomNode*/ node, /*String*/ ns, /*String|Boolena*/ attr){
|
||||
// Summary: Use the appropriate API to retrieve the role or state value
|
||||
// Description: In IE use the generic getAttribute() api. An alias value
|
||||
// was added to the attribute name to simulate a namespace when the attribute
|
||||
// was set. Otherwise use the getAttributeNS() api to retrieve the state value
|
||||
if(dojo.isIE){
|
||||
return node.getAttribute(this[ns].alias+":"+attr);
|
||||
}else{
|
||||
return node.getAttributeNS(this[ns]["namespace"], attr);
|
||||
}
|
||||
},
|
||||
removeAttr: function(/*DomNode*/ node, /*String*/ ns, /*String|Boolena*/ attr){
|
||||
// summary: Use the appropriate API to remove the role or state value
|
||||
// description: In IE use the generic removeAttribute() api. An alias value
|
||||
// was added to the attribute name to simulate a namespace when the attribute
|
||||
// was set. Otherwise use the removeAttributeNS() api to remove the state value
|
||||
var success = true; //only IE returns a value
|
||||
if(dojo.isIE){
|
||||
success = node.removeAttribute(this[ns].alias+":"+attr);
|
||||
}else{
|
||||
node.removeAttributeNS(this[ns]["namespace"], attr);
|
||||
}
|
||||
return success;
|
||||
},
|
||||
|
||||
onload: function(){
|
||||
// summary:
|
||||
// Function that detects if we are in high-contrast mode or not,
|
||||
// and sets up a timer to periodically confirm the value.
|
||||
// figure out the background-image style property
|
||||
// and apply that to the image.src property.
|
||||
// description:
|
||||
// This must be a named function and not an anonymous
|
||||
// function, so that the widget parsing code can make sure it
|
||||
// registers its onload function after this function.
|
||||
// DO NOT USE "this" within this function.
|
||||
|
||||
// create div for testing if high contrast mode is on or images are turned off
|
||||
var div = document.createElement("div");
|
||||
div.id = "a11yTestNode";
|
||||
div.style.cssText = 'border: 1px solid;'
|
||||
+ 'border-color:red green;'
|
||||
+ 'position: absolute;'
|
||||
+ 'left: -999px;'
|
||||
+ 'top: -999px;'
|
||||
+ 'background-image: url("' + dojo.moduleUrl("dijit", "form/templates/blank.gif") + '");';
|
||||
dojo.body().appendChild(div);
|
||||
|
||||
// test it
|
||||
function check(){
|
||||
var cs = dojo.getComputedStyle(div);
|
||||
if(cs){
|
||||
var bkImg = cs.backgroundImage;
|
||||
var needsA11y = (cs.borderTopColor==cs.borderRightColor) || (bkImg != null && (bkImg == "none" || bkImg == "url(invalid-url:)" ));
|
||||
dojo[needsA11y ? "addClass" : "removeClass"](dojo.body(), "dijit_a11y");
|
||||
}
|
||||
}
|
||||
check();
|
||||
if(dojo.isIE){
|
||||
setInterval(check, 4000);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Test if computer is in high contrast mode.
|
||||
// Make sure the a11y test runs first, before widgets are instantiated.
|
||||
if(dojo.isIE || dojo.isMoz){ // NOTE: checking in Safari messes things up
|
||||
dojo._loaders.unshift(dijit.wai.onload);
|
||||
}
|
||||
|
||||
}
|
||||
44
spring-faces/src/main/java/META-INF/dijit/_base/window.js
Normal file
44
spring-faces/src/main/java/META-INF/dijit/_base/window.js
Normal file
@@ -0,0 +1,44 @@
|
||||
if(!dojo._hasResource["dijit._base.window"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._base.window"] = true;
|
||||
dojo.provide("dijit._base.window");
|
||||
|
||||
dijit.getDocumentWindow = function(doc){
|
||||
// summary
|
||||
// Get window object associated with document doc
|
||||
|
||||
// With Safari, there is not way to retrieve the window from the document, so we must fix it.
|
||||
if(dojo.isSafari && !doc._parentWindow){
|
||||
/*
|
||||
This is a Safari specific function that fix the reference to the parent
|
||||
window from the document object.
|
||||
*/
|
||||
var fix=function(win){
|
||||
win.document._parentWindow=win;
|
||||
for(var i=0; i<win.frames.length; i++){
|
||||
fix(win.frames[i]);
|
||||
}
|
||||
}
|
||||
fix(window.top);
|
||||
}
|
||||
|
||||
//In some IE versions (at least 6.0), document.parentWindow does not return a
|
||||
//reference to the real window object (maybe a copy), so we must fix it as well
|
||||
//We use IE specific execScript to attach the real window reference to
|
||||
//document._parentWindow for later use
|
||||
if(dojo.isIE && window !== document.parentWindow && !doc._parentWindow){
|
||||
/*
|
||||
In IE 6, only the variable "window" can be used to connect events (others
|
||||
may be only copies).
|
||||
*/
|
||||
doc.parentWindow.execScript("document._parentWindow = window;", "Javascript");
|
||||
//to prevent memory leak, unset it after use
|
||||
//another possibility is to add an onUnload handler which seems overkill to me (liucougar)
|
||||
var win = doc._parentWindow;
|
||||
doc._parentWindow = null;
|
||||
return win; // Window
|
||||
}
|
||||
|
||||
return doc._parentWindow || doc.parentWindow || doc.defaultView; // Window
|
||||
}
|
||||
|
||||
}
|
||||
1416
spring-faces/src/main/java/META-INF/dijit/_editor/RichText.js
Normal file
1416
spring-faces/src/main/java/META-INF/dijit/_editor/RichText.js
Normal file
File diff suppressed because it is too large
Load Diff
91
spring-faces/src/main/java/META-INF/dijit/_editor/_Plugin.js
Normal file
91
spring-faces/src/main/java/META-INF/dijit/_editor/_Plugin.js
Normal file
@@ -0,0 +1,91 @@
|
||||
if(!dojo._hasResource["dijit._editor._Plugin"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._editor._Plugin"] = true;
|
||||
dojo.provide("dijit._editor._Plugin");
|
||||
dojo.require("dijit._Widget");
|
||||
dojo.require("dijit.Editor");
|
||||
dojo.require("dijit.form.Button");
|
||||
|
||||
dojo.declare("dijit._editor._Plugin", null, {
|
||||
// summary
|
||||
// This represents a "plugin" to the editor, which is basically
|
||||
// a single button on the Toolbar and some associated code
|
||||
constructor: function(/*Object?*/args, /*DomNode?*/node){
|
||||
if(args){
|
||||
dojo.mixin(this, args);
|
||||
}
|
||||
},
|
||||
|
||||
editor: null,
|
||||
iconClassPrefix: "dijitEditorIcon",
|
||||
button: null,
|
||||
queryCommand: null,
|
||||
command: "",
|
||||
commandArg: null,
|
||||
useDefaultCommand: true,
|
||||
buttonClass: dijit.form.Button,
|
||||
updateInterval: 200, // only allow updates every two tenths of a second
|
||||
_initButton: function(){
|
||||
if(this.command.length){
|
||||
var label = this.editor.commands[this.command];
|
||||
var className = "dijitEditorIcon "+this.iconClassPrefix + this.command.charAt(0).toUpperCase() + this.command.substr(1);
|
||||
if(!this.button){
|
||||
var props = {
|
||||
label: label,
|
||||
showLabel: false,
|
||||
iconClass: className,
|
||||
dropDown: this.dropDown
|
||||
};
|
||||
this.button = new this.buttonClass(props);
|
||||
}
|
||||
}
|
||||
},
|
||||
updateState: function(){
|
||||
var _e = this.editor;
|
||||
var _c = this.command;
|
||||
if(!_e){ return; }
|
||||
if(!_e.isLoaded){ return; }
|
||||
if(!_c.length){ return; }
|
||||
if(this.button){
|
||||
try{
|
||||
var enabled = _e.queryCommandEnabled(_c);
|
||||
this.button.setDisabled(!enabled);
|
||||
if(this.button.setChecked){
|
||||
this.button.setChecked(_e.queryCommandState(_c));
|
||||
}
|
||||
}catch(e){
|
||||
console.debug(e);
|
||||
}
|
||||
}
|
||||
},
|
||||
setEditor: function(/*Widget*/editor){
|
||||
// FIXME: detatch from previous editor!!
|
||||
this.editor = editor;
|
||||
|
||||
// FIXME: prevent creating this if we don't need to (i.e., editor can't handle our command)
|
||||
this._initButton();
|
||||
|
||||
// FIXME: wire up editor to button here!
|
||||
if( (this.command.length) &&
|
||||
(!this.editor.queryCommandAvailable(this.command))
|
||||
){
|
||||
// console.debug("hiding:", this.command);
|
||||
if(this.button){
|
||||
this.button.domNode.style.display = "none";
|
||||
}
|
||||
}
|
||||
if(this.button && this.useDefaultCommand){
|
||||
dojo.connect(this.button, "onClick",
|
||||
dojo.hitch(this.editor, "execCommand", this.command, this.commandArg)
|
||||
);
|
||||
}
|
||||
dojo.connect(this.editor, "onNormalizedDisplayChanged", this, "updateState");
|
||||
},
|
||||
setToolbar: function(/*Widget*/toolbar){
|
||||
if(this.button){
|
||||
toolbar.addChild(this.button);
|
||||
}
|
||||
// console.debug("adding", this.button, "to:", toolbar);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
({"set": "Set", "text": "Text:", "title": "Link URL", "url": "URL:", "urlInvalidMessage": "Invalid URL. Enter a full URL like 'http://www.dojotoolkit.org'"})
|
||||
@@ -0,0 +1 @@
|
||||
({"removeFormat": "Remove Format", "copy": "Copy", "paste": "Paste", "selectAll": "Select All", "insertOrderedList": "Numbered List", "insertTable": "Insert/Edit Table", "underline": "Underline", "foreColor": "Foreground Color", "htmlToggle": "HTML Source", "formatBlock": "Paragraph Style", "insertHorizontalRule": "Horizontal Rule", "delete": "Delete", "insertUnorderedList": "Bullet List", "tableProp": "Table Property", "insertImage": "Insert Image", "superscript": "Superscript", "subscript": "Subscript", "createLink": "Create Link", "pasteErrorFF": "Paste action is only available in Firefox via keyboard shortcut due to its design decision: please use ctrl+v.", "undo": "Undo", "italic": "Italic", "justifyLeft": "Align Left", "fontName": "Font Name", "unlink": "Remove Link", "toggleTableBorder": "Toggle Table Border", "fontSize": "Font Size", "indent": "Indent", "redo": "Redo", "strikethrough": "Strikethrough", "justifyFull": "Justify", "justifyCenter": "Align Center", "hiliteColor": "Background Color", "outdent": "Outdent", "cut": "Cut", "deleteTable": "Delete Table", "plainFormatBlock": "Paragraph Style", "bold": "Bold", "copyErrorFF": "Copy action is only available in Firefox via keyboard shortcut due to its design decision: please use ctrl+c.", "cutErrorFF": "Cut action is only available in Firefox via keyboard shortcut due to its design decision: please use ctrl+x.", "justifyRight": "Align Right"})
|
||||
@@ -0,0 +1 @@
|
||||
({"undo": "Rückgängig", "formatBlock": "Paragraph Stil", "selectAll": "Alles auswählen", "plainFormatBlock": "Paragraph Stil", "subscript": "Tiefgestellt", "delete": "Löschen", "justifyRight": "Rechtsbündig", "superscript": "Hochgestellt", "copy": "Kopieren", "createLink": "Link erstellen", "bold": "Fett", "removeFormat": "Formatierung löschen", "unlink": "Link löschen", "fontName": "Schriftart", "outdent": "Ausrücken", "paste": "Einfügen", "redo": "Wiederholen", "indent": "Einrücken", "justifyFull": "Blocksatz", "foreColor": "Textfarbe", "underline": "Unterstrichen", "justifyCenter": "Zentiert", "justifyLeft": "Linksbündig", "italic": "Kursiv", "insertUnorderedList": "Auflistung", "insertOrderedList": "Nummerierung", "insertHorizontalRule": "Horizontale Linie", "strikethrough": "Durchgestrichen", "insertImage": "Bild einfügen", "cut": "Ausschneiden", "hiliteColor": "Hintergrundfarbe", "fontSize": "Schriftgröße", "insertTable": "Insert/Edit Table", "htmlToggle": "HTML Source", "tableProp": "Table Property", "pasteErrorFF": "Paste action is only available in Firefox via keyboard shortcut due to its design decision: please use ctrl+v.", "toggleTableBorder": "Toggle Table Border", "deleteTable": "Delete Table", "copyErrorFF": "Copy action is only available in Firefox via keyboard shortcut due to its design decision: please use ctrl+c.", "cutErrorFF": "Cut action is only available in Firefox via keyboard shortcut due to its design decision: please use ctrl+x."})
|
||||
@@ -0,0 +1 @@
|
||||
({"undo": "Annulla", "formatBlock": "Stile Paragrafo", "selectAll": "Seleziona Tutto", "htmlToggle": "Sorgente HTML", "plainFormatBlock": "Stile Paragrafo", "subscript": "Pedice", "delete": "Elimina", "justifyRight": "Allinea a Destra", "superscript": "Apice", "copy": "Copia", "createLink": "Crea collegamento", "bold": "Grassetto", "removeFormat": "Rimuovi Formato", "unlink": "Rimuovi Collegamento", "fontName": "Nome Font", "redo": "Ripeti", "paste": "Incolla", "outdent": "Riduci Rientro", "indent": "Aumenta Rientro", "justifyFull": "Giustifica", "foreColor": "Colore Primo Piano", "underline": "Sottolineato", "justifyCenter": "Allinea al Centro", "justifyLeft": "Allinea a Sinistra", "italic": "Corsivo", "insertUnorderedList": "Lista Puntata", "insertOrderedList": "Lista Numerata", "insertHorizontalRule": "Righello Orizzontale", "strikethrough": "Barrato", "insertImage": "Inserisci Immagine", "cut": "Taglia", "hiliteColor": "Colore Sfondo", "fontSize": "Dimensioni Font", "insertTable": "Insert/Edit Table", "tableProp": "Table Property", "pasteErrorFF": "Paste action is only available in Firefox via keyboard shortcut due to its design decision: please use ctrl+v.", "toggleTableBorder": "Toggle Table Border", "deleteTable": "Delete Table", "copyErrorFF": "Copy action is only available in Firefox via keyboard shortcut due to its design decision: please use ctrl+c.", "cutErrorFF": "Cut action is only available in Firefox via keyboard shortcut due to its design decision: please use ctrl+x."})
|
||||
@@ -0,0 +1,147 @@
|
||||
if(!dojo._hasResource["dijit._editor.plugins.AlwaysShowToolbar"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._editor.plugins.AlwaysShowToolbar"] = true;
|
||||
dojo.provide("dijit._editor.plugins.AlwaysShowToolbar");
|
||||
|
||||
dojo.declare("dijit._editor.plugins.AlwaysShowToolbar", null,
|
||||
{
|
||||
_handleScroll: true,
|
||||
setEditor: function(e){
|
||||
this.editor=e;
|
||||
// setTimeout(dojo.hitch(this,this.enable),10000);
|
||||
e.onLoadDeferred.addCallback(dojo.hitch(this,this.enable));
|
||||
// this.scrollInterval = setInterval(dojo.hitch(this, "globalOnScrollHandler"), 100);
|
||||
},
|
||||
enable: function(d){
|
||||
this._updateHeight();
|
||||
this._connects=[dojo.connect(window,'onscroll',this,"globalOnScrollHandler"),
|
||||
dojo.connect(this.editor,'onNormalizedDisplayChanged',this,"_updateHeight")];
|
||||
return d;
|
||||
},
|
||||
_updateHeight: function(){
|
||||
// summary:
|
||||
// Updates the height of the editor area to fit the contents.
|
||||
var e=this.editor;
|
||||
if(!e.isLoaded){ return; }
|
||||
if(e.height){ return; }
|
||||
|
||||
var height = dojo.marginBox(e.editNode).h;
|
||||
if(dojo.isOpera){
|
||||
height = e.editNode.scrollHeight;
|
||||
}
|
||||
// console.debug('height',height);
|
||||
// alert(this.editNode);
|
||||
|
||||
//height maybe zero in some cases even though the content is not empty,
|
||||
//we try the height of body instead
|
||||
if(!height){
|
||||
height = dojo.marginBox(e.document.body).h;
|
||||
}
|
||||
|
||||
if(height == 0){
|
||||
console.debug("Can not figure out the height of the editing area!");
|
||||
return; //prevent setting height to 0
|
||||
}
|
||||
if(height != this._lastHeight){
|
||||
this._lastHeight = height;
|
||||
// this.editorObject.style.height = this._lastHeight + "px";
|
||||
dojo.marginBox(e.iframe, { h: this._lastHeight });
|
||||
// this.iframe.height=this._lastHeight+10+'px';
|
||||
// this.iframe.style.height=this._lastHeight+'px';
|
||||
}
|
||||
},
|
||||
_lastHeight: 0,
|
||||
globalOnScrollHandler: function(){
|
||||
var isIE = dojo.isIE && dojo.isIE<7;
|
||||
if(!this._handleScroll){ return; }
|
||||
var tdn = this.editor.toolbar.domNode;
|
||||
var db = dojo.body;
|
||||
|
||||
if(!this._scrollSetUp){
|
||||
this._scrollSetUp = true;
|
||||
this._scrollThreshold = dojo._abs(tdn, true).y;
|
||||
// console.log("threshold:", this._scrollThreshold);
|
||||
//what's this for?? comment out for now
|
||||
// if((isIE)&&(db)&&(dojo.style(db, "backgroundIimage")=="none")){
|
||||
// db.style.backgroundImage = "url(" + dojo.uri.moduleUri("dijit", "templates/blank.gif") + ")";
|
||||
// db.style.backgroundAttachment = "fixed";
|
||||
// }
|
||||
}
|
||||
|
||||
var scrollPos = dojo._docScroll().y;
|
||||
|
||||
if(scrollPos > this._scrollThreshold && scrollPos < this._scrollThreshold+this._lastHeight){
|
||||
// dojo.debug(scrollPos);
|
||||
if(!this._fixEnabled){
|
||||
var tdnbox = dojo.marginBox(tdn);
|
||||
this.editor.iframe.style.marginTop = tdnbox.h+"px";
|
||||
|
||||
if(isIE){
|
||||
tdn.style.left = dojo._abs(tdn).x;
|
||||
if(tdn.previousSibling){
|
||||
this._IEOriginalPos = ['after',tdn.previousSibling];
|
||||
}else if(tdn.nextSibling){
|
||||
this._IEOriginalPos = ['before',tdn.nextSibling];
|
||||
}else{
|
||||
this._IEOriginalPos = ['last',tdn.parentNode];
|
||||
}
|
||||
dojo.body().appendChild(tdn);
|
||||
dojo.addClass(tdn,'IEFixedToolbar');
|
||||
}else{
|
||||
with(tdn.style){
|
||||
position = "fixed";
|
||||
top = "0px";
|
||||
}
|
||||
}
|
||||
|
||||
dojo.marginBox(tdn, { w: tdnbox.w });
|
||||
tdn.style.zIndex = 2000;
|
||||
this._fixEnabled = true;
|
||||
}
|
||||
// if we're showing the floating toolbar, make sure that if
|
||||
// we've scrolled past the bottom of the editor that we hide
|
||||
// the toolbar for this instance of the editor.
|
||||
|
||||
// TODO: when we get multiple editor toolbar support working
|
||||
// correctly, ensure that we check this against the scroll
|
||||
// position of the bottom-most editor instance.
|
||||
var eHeight = (this.height) ? parseInt(this.editor.height) : this.editor._lastHeight;
|
||||
if(scrollPos > (this._scrollThreshold+eHeight)){
|
||||
tdn.style.display = "none";
|
||||
}else{
|
||||
tdn.style.display = "";
|
||||
}
|
||||
}else if(this._fixEnabled){
|
||||
this.editor.iframe.style.marginTop = '';
|
||||
with(tdn.style){
|
||||
position = "";
|
||||
top = "";
|
||||
zIndex = "";
|
||||
display = "";
|
||||
}
|
||||
if(isIE){
|
||||
tdn.style.left = "";
|
||||
dojo.removeClass(tdn,'IEFixedToolbar');
|
||||
if(this._IEOriginalPos){
|
||||
dojo.place(tdn, this._IEOriginalPos[1], this._IEOriginalPos[0]);
|
||||
this._IEOriginalPos = null;
|
||||
}else{
|
||||
dojo.place(tdn, this.editor.iframe,'before');
|
||||
}
|
||||
}
|
||||
tdn.style.width = "";
|
||||
this._fixEnabled = false;
|
||||
}
|
||||
},
|
||||
destroy: function(){
|
||||
this._IEOriginalPos = null;
|
||||
this._handleScroll = false;
|
||||
dojo.forEach(this._connects,dojo.disconnect);
|
||||
// clearInterval(this.scrollInterval);
|
||||
|
||||
if(dojo.isIE && dojo.isIE<7){
|
||||
dojo.removeClass(this.editor.toolbar.domNode,'IEFixedToolbar');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
@@ -0,0 +1,422 @@
|
||||
if(!dojo._hasResource["dijit._editor.plugins.EnterKeyHandling"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._editor.plugins.EnterKeyHandling"] = true;
|
||||
dojo.provide("dijit._editor.plugins.EnterKeyHandling");
|
||||
|
||||
|
||||
dojo.declare("dijit._editor.plugins.EnterKeyHandling",null,{
|
||||
// blockNodeForEnter: String
|
||||
// this property decides the behavior of Enter key. It can be either P,
|
||||
// DIV, BR, or empty (which means disable this feature). Anything else
|
||||
// will trigger errors.
|
||||
blockNodeForEnter: 'P',
|
||||
constructor: function(args){
|
||||
if(args){
|
||||
dojo.mixin(this,args);
|
||||
}
|
||||
},
|
||||
setEditor: function(editor){
|
||||
this.editor=editor;
|
||||
if(this.blockNodeForEnter=='BR'){
|
||||
if(dojo.isIE){
|
||||
editor.contentDomPreFilters.push(dojo.hitch(this, "regularPsToSingleLinePs"));
|
||||
editor.contentDomPostFilters.push(dojo.hitch(this, "singleLinePsToRegularPs"));
|
||||
editor.onLoadDeferred.addCallback(dojo.hitch(this, "_fixNewLineBehaviorForIE"));
|
||||
}else{
|
||||
editor.onLoadDeferred.addCallback(dojo.hitch(this,function(d){
|
||||
try{
|
||||
this.editor.document.execCommand("insertBrOnReturn", false, true);
|
||||
}catch(e){};
|
||||
return d;
|
||||
}));
|
||||
}
|
||||
}else if(this.blockNodeForEnter){
|
||||
//add enter key handler
|
||||
// FIXME: need to port to the new event code!!
|
||||
dojo['require']('dijit._editor.range');
|
||||
var h=dojo.hitch(this,this.handleEnterKey);
|
||||
editor.addKeyHandler(13, 0, h); //enter
|
||||
editor.addKeyHandler(13, 2, h); //shift+enter
|
||||
this.connect(this.editor,'onKeyPressed','onKeyPressed');
|
||||
}
|
||||
},
|
||||
connect: function(o,f,tf){
|
||||
if(!this._connects){
|
||||
this._connects=[];
|
||||
}
|
||||
this._connects.push(dojo.connect(o,f,this,tf));
|
||||
},
|
||||
destroy: function(){
|
||||
dojo.forEach(this._connects,dojo.disconnect);
|
||||
this._connects=[];
|
||||
},
|
||||
onKeyPressed: function(e){
|
||||
if(this._checkListLater){
|
||||
if(dojo.withGlobal(this.editor.window, 'isCollapsed', dijit._editor.selection)){
|
||||
if(!dojo.withGlobal(this.editor.window, 'hasAncestorElement', dijit._editor.selection, ['LI'])){
|
||||
//circulate the undo detection code by calling RichText::execCommand directly
|
||||
dijit._editor.RichText.prototype.execCommand.apply(this.editor, ['formatblock',this.blockNodeForEnter]);
|
||||
//set the innerHTML of the new block node
|
||||
var block = dojo.withGlobal(this.editor.window, 'getAncestorElement', dijit._editor.selection, [this.blockNodeForEnter])
|
||||
if(block){
|
||||
block.innerHTML=this.bogusHtmlContent;
|
||||
if(dojo.isIE){
|
||||
//the following won't work, it will move the caret to the last list item in the previous list
|
||||
// var newrange = dijit.range.create();
|
||||
// newrange.setStart(block.firstChild,0);
|
||||
// var selection = dijit.range.getSelection(this.editor.window)
|
||||
// selection.removeAllRanges();
|
||||
// selection.addRange(newrange);
|
||||
//move to the start by move backward one char
|
||||
var r = this.editor.document.selection.createRange();
|
||||
r.move('character',-1);
|
||||
r.select();
|
||||
}
|
||||
}else{
|
||||
alert('onKeyPressed: Can not find the new block node');
|
||||
}
|
||||
}
|
||||
}
|
||||
this._checkListLater = false;
|
||||
}else if(this._pressedEnterInBlock){
|
||||
//the new created is the original current P, so we have previousSibling below
|
||||
this.removeTrailingBr(this._pressedEnterInBlock.previousSibling);
|
||||
delete this._pressedEnterInBlock;
|
||||
}
|
||||
},
|
||||
bogusHtmlContent: ' ',
|
||||
blockNodes: /^(?:H1|H2|H3|H4|H5|H6|LI)$/,
|
||||
handleEnterKey: function(e){
|
||||
// summary: manually handle enter key event to make the behavior consistant across
|
||||
// all supported browsers. See property blockNodeForEnter for available options
|
||||
if(!this.blockNodeForEnter){ return true; } //let browser handle this
|
||||
if(e.shiftKey //shift+enter always generates <br>
|
||||
|| this.blockNodeForEnter=='BR'){
|
||||
var parent = dojo.withGlobal(this.editor.window, "getParentElement", dijit._editor.selection);
|
||||
var header = dijit.range.getAncestor(parent,this.editor.blockNodes);
|
||||
if(header){
|
||||
if(header.tagName=='LI'){
|
||||
return true; //let brower handle
|
||||
}
|
||||
var selection = dijit.range.getSelection(this.editor.window);
|
||||
var range = selection.getRangeAt(0);
|
||||
if(!range.collapsed){
|
||||
range.deleteContents();
|
||||
}
|
||||
if(dijit.range.atBeginningOfContainer(header, range.startContainer, range.startOffset)){
|
||||
dojo.place(this.editor.document.createElement('br'), header, "before");
|
||||
}else if(dijit.range.atEndOfContainer(header, range.startContainer, range.startOffset)){
|
||||
dojo.place(this.editor.document.createElement('br'), header, "after");
|
||||
var newrange = dijit.range.create();
|
||||
newrange.setStartAfter(header);
|
||||
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(newrange);
|
||||
}else{
|
||||
return true; //let brower handle
|
||||
}
|
||||
}else{
|
||||
//don't change this: do not call this.execCommand, as that may have other logic in subclass
|
||||
// FIXME
|
||||
dijit._editor.RichText.prototype.execCommand.call(this.editor, 'inserthtml', '<br>');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
var _letBrowserHandle = true;
|
||||
//blockNodeForEnter is either P or DIV
|
||||
//first remove selection
|
||||
var selection = dijit.range.getSelection(this.editor.window);
|
||||
var range = selection.getRangeAt(0);
|
||||
if(!range.collapsed){
|
||||
range.deleteContents();
|
||||
}
|
||||
|
||||
var block = dijit.range.getBlockAncestor(range.endContainer, null, this.editor.editNode);
|
||||
|
||||
if(block.blockNode && block.blockNode.tagName == 'LI'){
|
||||
this._checkListLater = true;
|
||||
return true;
|
||||
}else{
|
||||
this._checkListLater = false;
|
||||
}
|
||||
|
||||
//text node directly under body, let's wrap them in a node
|
||||
if(!block.blockNode){
|
||||
this.editor.document.execCommand('formatblock',false, this.blockNodeForEnter);
|
||||
//get the newly created block node
|
||||
// FIXME
|
||||
block = {blockNode:dojo.withGlobal(this.editor.window, "getAncestorElement", dijit._editor.selection, [this.blockNodeForEnter]),
|
||||
blockContainer: this.editor.editNode};
|
||||
if(block.blockNode){
|
||||
if((block.blockNode.textContent||block.blockNode.innerHTML).replace(/^\s+|\s+$/g, "").length==0){
|
||||
this.removeTrailingBr(block.blockNode);
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
block.blockNode = this.editor.editNode;
|
||||
}
|
||||
selection = dijit.range.getSelection(this.editor.window);
|
||||
range = selection.getRangeAt(0);
|
||||
}
|
||||
var newblock = this.editor.document.createElement(this.blockNodeForEnter);
|
||||
newblock.innerHTML=this.bogusHtmlContent;
|
||||
this.removeTrailingBr(block.blockNode);
|
||||
if(dijit.range.atEndOfContainer(block.blockNode, range.endContainer, range.endOffset)){
|
||||
if(block.blockNode === block.blockContainer){
|
||||
block.blockNode.appendChild(newblock);
|
||||
}else{
|
||||
dojo.place(newblock, block.blockNode, "after");
|
||||
}
|
||||
_letBrowserHandle = false;
|
||||
//lets move caret to the newly created block
|
||||
var newrange = dijit.range.create();
|
||||
newrange.setStart(newblock,0);
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(newrange);
|
||||
if(this.editor.height){
|
||||
newblock.scrollIntoView(false);
|
||||
}
|
||||
}else if(dijit.range.atBeginningOfContainer(block.blockNode,
|
||||
range.startContainer, range.startOffset)){
|
||||
if(block.blockNode === block.blockContainer){
|
||||
dojo.place(newblock, block.blockNode, "first");
|
||||
}else{
|
||||
dojo.place(newblock, block.blockNode, "before");
|
||||
}
|
||||
if(this.editor.height){
|
||||
//browser does not scroll the caret position into view, do it manually
|
||||
newblock.scrollIntoView(false);
|
||||
}
|
||||
_letBrowserHandle = false;
|
||||
}else{ //press enter in the middle of P
|
||||
if(dojo.isMoz){
|
||||
//press enter in middle of P may leave a trailing <br/>, let's remove it later
|
||||
this._pressedEnterInBlock = block.blockNode;
|
||||
}
|
||||
}
|
||||
return _letBrowserHandle;
|
||||
},
|
||||
removeTrailingBr: function(container){
|
||||
if(/P|DIV|LI/i .test(container.tagName)){
|
||||
var para = container;
|
||||
}else{
|
||||
var para = dijit._editor.selection.getParentOfType(container,['P','DIV','LI']);
|
||||
}
|
||||
|
||||
if(!para){ return; }
|
||||
if(para.lastChild){
|
||||
if(para.childNodes.length>1 && para.lastChild.nodeType==3 && /^[\s\xAD]*$/ .test(para.lastChild.nodeValue)){
|
||||
dojo._destroyElement(para.lastChild);
|
||||
}
|
||||
if(para.lastChild && para.lastChild.tagName=='BR'){
|
||||
dojo._destroyElement(para.lastChild);
|
||||
}
|
||||
}
|
||||
if(para.childNodes.length==0){
|
||||
para.innerHTML=this.bogusHtmlContent;
|
||||
}
|
||||
},
|
||||
_fixNewLineBehaviorForIE: function(d){
|
||||
if(typeof this.editor.document.__INSERTED_EDITIOR_NEWLINE_CSS == "undefined"){
|
||||
var lineFixingStyles = "p{margin:0 !important;}";
|
||||
var insertCssText = function(
|
||||
/*String*/ cssStr,
|
||||
/*Document*/ doc,
|
||||
/*String*/ URI)
|
||||
{
|
||||
// summary:
|
||||
// Attempt to insert CSS rules into the document through inserting a
|
||||
// style element
|
||||
|
||||
// DomNode Style = insertCssText(String ".dojoMenu {color: green;}"[, DomDoc document, dojo.uri.Uri Url ])
|
||||
if(!cssStr){
|
||||
return; // HTMLStyleElement
|
||||
}
|
||||
if(!doc){ doc = document; }
|
||||
// if(URI){// fix paths in cssStr
|
||||
// cssStr = dojo.html.fixPathsInCssText(cssStr, URI);
|
||||
// }
|
||||
var style = doc.createElement("style");
|
||||
style.setAttribute("type", "text/css");
|
||||
// IE is b0rken enough to require that we add the element to the doc
|
||||
// before changing it's properties
|
||||
var head = doc.getElementsByTagName("head")[0];
|
||||
if(!head){ // must have a head tag
|
||||
console.debug("No head tag in document, aborting styles");
|
||||
return; // HTMLStyleElement
|
||||
}else{
|
||||
head.appendChild(style);
|
||||
}
|
||||
if(style.styleSheet){// IE
|
||||
var setFunc = function(){
|
||||
try{
|
||||
style.styleSheet.cssText = cssStr;
|
||||
}catch(e){ dojo.debug(e); }
|
||||
};
|
||||
if(style.styleSheet.disabled){
|
||||
setTimeout(setFunc, 10);
|
||||
}else{
|
||||
setFunc();
|
||||
}
|
||||
}else{ // w3c
|
||||
var cssText = doc.createTextNode(cssStr);
|
||||
style.appendChild(cssText);
|
||||
}
|
||||
return style; // HTMLStyleElement
|
||||
}
|
||||
insertCssText(lineFixingStyles, this.editor.document);
|
||||
this.editor.document.__INSERTED_EDITIOR_NEWLINE_CSS = true;
|
||||
// this.regularPsToSingleLinePs(this.editNode);
|
||||
return d;
|
||||
}
|
||||
},
|
||||
regularPsToSingleLinePs: function(element, noWhiteSpaceInEmptyP){
|
||||
function wrapLinesInPs(el){
|
||||
// move "lines" of top-level text nodes into ps
|
||||
function wrapNodes(nodes){
|
||||
// nodes are assumed to all be siblings
|
||||
var newP = nodes[0].ownerDocument.createElement('p'); // FIXME: not very idiomatic
|
||||
nodes[0].parentNode.insertBefore(newP, nodes[0]);
|
||||
for(var i=0; i<nodes.length; i++){
|
||||
newP.appendChild(nodes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
var currentNodeIndex = 0;
|
||||
var nodesInLine = [];
|
||||
var currentNode;
|
||||
while(currentNodeIndex < el.childNodes.length){
|
||||
currentNode = el.childNodes[currentNodeIndex];
|
||||
if( (currentNode.nodeName!='BR') &&
|
||||
(currentNode.nodeType==1) &&
|
||||
(dojo.style(currentNode, "display")!="block")
|
||||
){
|
||||
nodesInLine.push(currentNode);
|
||||
}else{
|
||||
// hit line delimiter; process nodesInLine if there are any
|
||||
var nextCurrentNode = currentNode.nextSibling;
|
||||
if(nodesInLine.length){
|
||||
wrapNodes(nodesInLine);
|
||||
currentNodeIndex = (currentNodeIndex+1)-nodesInLine.length;
|
||||
if(currentNode.nodeName=="BR"){
|
||||
dojo._destroyElement(currentNode);
|
||||
}
|
||||
}
|
||||
nodesInLine = [];
|
||||
}
|
||||
currentNodeIndex++;
|
||||
}
|
||||
if(nodesInLine.length){ wrapNodes(nodesInLine); }
|
||||
}
|
||||
|
||||
function splitP(el){
|
||||
// split a paragraph into seperate paragraphs at BRs
|
||||
var currentNode = null;
|
||||
var trailingNodes = [];
|
||||
var lastNodeIndex = el.childNodes.length-1;
|
||||
for(var i=lastNodeIndex; i>=0; i--){
|
||||
currentNode = el.childNodes[i];
|
||||
if(currentNode.nodeName=="BR"){
|
||||
var newP = currentNode.ownerDocument.createElement('p');
|
||||
dojo.place(newP, el, "after");
|
||||
if (trailingNodes.length==0 && i != lastNodeIndex) {
|
||||
newP.innerHTML = " "
|
||||
}
|
||||
dojo.forEach(trailingNodes, function(node){
|
||||
newP.appendChild(node);
|
||||
});
|
||||
dojo._destroyElement(currentNode);
|
||||
trailingNodes = [];
|
||||
}else{
|
||||
trailingNodes.unshift(currentNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var pList = [];
|
||||
var ps = element.getElementsByTagName('p');
|
||||
dojo.forEach(ps, function(p){ pList.push(p); });
|
||||
dojo.forEach(pList, function(p){
|
||||
if( (p.previousSibling) &&
|
||||
(p.previousSibling.nodeName == 'P' || dojo.style(p.previousSibling, 'display') != 'block')
|
||||
){
|
||||
var newP = p.parentNode.insertBefore(this.document.createElement('p'), p);
|
||||
// this is essential to prevent IE from losing the P.
|
||||
// if it's going to be innerHTML'd later we need
|
||||
// to add the to _really_ force the issue
|
||||
newP.innerHTML = noWhiteSpaceInEmptyP ? "" : " ";
|
||||
}
|
||||
splitP(p);
|
||||
},this.editor);
|
||||
wrapLinesInPs(element);
|
||||
return element;
|
||||
},
|
||||
|
||||
singleLinePsToRegularPs: function(element){
|
||||
function getParagraphParents(node){
|
||||
var ps = node.getElementsByTagName('p');
|
||||
var parents = [];
|
||||
for(var i=0; i<ps.length; i++){
|
||||
var p = ps[i];
|
||||
var knownParent = false;
|
||||
for(var k=0; k < parents.length; k++){
|
||||
if(parents[k] === p.parentNode){
|
||||
knownParent = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!knownParent){
|
||||
parents.push(p.parentNode);
|
||||
}
|
||||
}
|
||||
return parents;
|
||||
}
|
||||
|
||||
function isParagraphDelimiter(node){
|
||||
if(node.nodeType != 1 || node.tagName != 'P'){
|
||||
return (dojo.style(node, 'display') == 'block');
|
||||
}else{
|
||||
if(!node.childNodes.length || node.innerHTML==" "){ return true }
|
||||
//return node.innerHTML.match(/^(<br\ ?\/?>| |\ \;)$/i);
|
||||
}
|
||||
}
|
||||
|
||||
var paragraphContainers = getParagraphParents(element);
|
||||
for(var i=0; i<paragraphContainers.length; i++){
|
||||
var container = paragraphContainers[i];
|
||||
var firstPInBlock = null;
|
||||
var node = container.firstChild;
|
||||
var deleteNode = null;
|
||||
while(node){
|
||||
if(node.nodeType != "1" || node.tagName != 'P'){
|
||||
firstPInBlock = null;
|
||||
}else if (isParagraphDelimiter(node)){
|
||||
deleteNode = node;
|
||||
firstPInBlock = null;
|
||||
}else{
|
||||
if(firstPInBlock == null){
|
||||
firstPInBlock = node;
|
||||
}else{
|
||||
if( (!firstPInBlock.lastChild || firstPInBlock.lastChild.nodeName != 'BR') &&
|
||||
(node.firstChild) &&
|
||||
(node.firstChild.nodeName != 'BR')
|
||||
){
|
||||
firstPInBlock.appendChild(this.editor.document.createElement('br'));
|
||||
}
|
||||
while(node.firstChild){
|
||||
firstPInBlock.appendChild(node.firstChild);
|
||||
}
|
||||
deleteNode = node;
|
||||
}
|
||||
}
|
||||
node = node.nextSibling;
|
||||
if(deleteNode){
|
||||
dojo._destroyElement(deleteNode);
|
||||
deleteNode = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return element;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
if(!dojo._hasResource["dijit._editor.plugins.LinkDialog"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._editor.plugins.LinkDialog"] = true;
|
||||
dojo.provide("dijit._editor.plugins.LinkDialog");
|
||||
|
||||
dojo.require("dijit._Widget");
|
||||
dojo.require("dijit._Templated");
|
||||
dojo.require("dijit._editor._Plugin");
|
||||
dojo.require("dijit.Dialog");
|
||||
dojo.require("dijit.form.Button");
|
||||
dojo.require("dijit.form.ValidationTextBox");
|
||||
dojo.require("dojo.i18n");
|
||||
dojo.require("dojo.string");
|
||||
dojo.requireLocalization("dijit._editor", "LinkDialog", null, "ROOT");
|
||||
|
||||
dojo.declare("dijit._editor.plugins.DualStateDropDownButton",
|
||||
dijit.form.DropDownButton,
|
||||
{
|
||||
// summary: a DropDownButton but button can be displayed in two states (checked or unchecked)
|
||||
setChecked: dijit.form.ToggleButton.prototype.setChecked
|
||||
}
|
||||
);
|
||||
|
||||
dojo.declare("dijit._editor.plugins.UrlTextBox",
|
||||
dijit.form.ValidationTextBox,
|
||||
{
|
||||
// summary: the URL input box we use in our dialog
|
||||
|
||||
// regular expression for URLs, generated from dojo.regexp.url()
|
||||
regExp: "((https?|ftps?)\\://|)(([0-9a-zA-Z]([-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?\\.)+(arpa|aero|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|xxx|jobs|mobi|post|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|eu|es|et|fi|fj|fk|fm|fo|fr|ga|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sk|sl|sm|sn|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tm|tn|to|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)|(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])|(0[xX]0*[\\da-fA-F]?[\\da-fA-F]\\.){3}0[xX]0*[\\da-fA-F]?[\\da-fA-F]|(0+[0-3][0-7][0-7]\\.){3}0+[0-3][0-7][0-7]|(0|[1-9]\\d{0,8}|[1-3]\\d{9}|4[01]\\d{8}|42[0-8]\\d{7}|429[0-3]\\d{6}|4294[0-8]\\d{5}|42949[0-5]\\d{4}|429496[0-6]\\d{3}|4294967[01]\\d{2}|42949672[0-8]\\d|429496729[0-5])|0[xX]0*[\\da-fA-F]{1,8}|([\\da-fA-F]{1,4}\\:){7}[\\da-fA-F]{1,4}|([\\da-fA-F]{1,4}\\:){6}((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])))(\\:(0|[1-9]\\d*))?(/([^?#\\s/]+/)*)?([^?#\\s/]+(\\?[^?#\\s/]*)?(#[A-Za-z][\\w.:-]*)?)?",
|
||||
|
||||
required: true,
|
||||
|
||||
postMixInProperties: function(){
|
||||
dijit._editor.plugins.UrlTextBox.superclass.postMixInProperties.apply(this, arguments);
|
||||
this.invalidMessage = dojo.i18n.getLocalization("dijit._editor", "LinkDialog", this.lang).urlInvalidMessage;
|
||||
},
|
||||
|
||||
getValue: function(){
|
||||
if(!/^(https?|ftps?)/.test(this.textbox.value)){
|
||||
this.textbox.value="http://"+this.textbox.value;
|
||||
}
|
||||
return this.textbox.value;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
dojo.declare("dijit._editor.plugins.LinkDialog",
|
||||
dijit._editor._Plugin,
|
||||
{
|
||||
buttonClass: dijit._editor.plugins.DualStateDropDownButton,
|
||||
|
||||
linkDialogTemplate: [
|
||||
"<label for='urlInput'>${url} </label>",
|
||||
"<input dojoType=dijit._editor.plugins.UrlTextBox name='urlInput'><br>",
|
||||
"<label for='textInput'>${text} </label>",
|
||||
"<input dojoType=dijit.form.TextBox name='textInput'>",
|
||||
"<br>",
|
||||
"<button dojoType=dijit.form.Button type='submit'>${set}</button>"
|
||||
].join(""),
|
||||
|
||||
useDefaultCommand: false,
|
||||
|
||||
command: "createLink",
|
||||
|
||||
dropDown: null,
|
||||
|
||||
constructor: function(){
|
||||
var _this = this;
|
||||
var messages = dojo.i18n.getLocalization("dijit._editor", "LinkDialog", this.lang);
|
||||
this.dropDown = new dijit.TooltipDialog({
|
||||
title: messages.title,
|
||||
execute: dojo.hitch(this, "setValue"),
|
||||
onOpen: function(){
|
||||
_this._onOpenDialog();
|
||||
dijit.TooltipDialog.prototype.onOpen.apply(this, arguments);
|
||||
},
|
||||
onCancel: function(){
|
||||
setTimeout(dojo.hitch(_this, "_onCloseDialog"),0);
|
||||
},
|
||||
onClose: dojo.hitch(this, "_onCloseDialog")
|
||||
});
|
||||
this.dropDown.setContent(dojo.string.substitute(this.linkDialogTemplate, messages));
|
||||
this.dropDown.startup();
|
||||
},
|
||||
|
||||
setValue: function(args){
|
||||
// summary: callback from the dialog when user hits "set" button
|
||||
//TODO: prevent closing popup if the text is empty
|
||||
this._onCloseDialog();
|
||||
if(dojo.isIE){ //see #4151
|
||||
var a = dojo.withGlobal(this.editor.window, "getAncestorElement",dijit._editor.selection, ['a']);
|
||||
if(a){
|
||||
dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [a]);
|
||||
}
|
||||
}
|
||||
var attstr='href="'+args.urlInput+'" _djrealurl="'+args.urlInput+'"';
|
||||
// console.log(args,this.editor,'<a '+attstr+'>'+args.textInput+'</a>');
|
||||
this.editor.execCommand('inserthtml', '<a '+attstr+'>'+args.textInput+'</a>');
|
||||
// this.editor.execCommand(this.command, args.urlInput);
|
||||
},
|
||||
|
||||
// _savedSelection: null,
|
||||
_onCloseDialog: function(){
|
||||
// FIXME: IE is really messed up here!!
|
||||
if(dojo.isIE){
|
||||
if(this._savedSelection){
|
||||
var b=this._savedSelection;
|
||||
this._savedSelection=null;
|
||||
this.editor.focus();
|
||||
var range = this.editor.document.selection.createRange();
|
||||
range.moveToBookmark(b);
|
||||
range.select();
|
||||
}
|
||||
}else{this.editor.focus();
|
||||
}
|
||||
},
|
||||
_onOpenDialog: function(){
|
||||
var a = dojo.withGlobal(this.editor.window, "getAncestorElement",dijit._editor.selection, ['a']);
|
||||
var url='',text='';
|
||||
if(a){
|
||||
url=a.getAttribute('_djrealurl');
|
||||
text=a.textContent||a.innerText;
|
||||
dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [a,true]);
|
||||
}else{
|
||||
text=dojo.withGlobal(this.editor.window, dijit._editor.selection.getSelectedText);
|
||||
}
|
||||
// FIXME: IE is *really* b0rken
|
||||
if(dojo.isIE){
|
||||
var range = this.editor.document.selection.createRange();
|
||||
this._savedSelection = range.getBookmark();
|
||||
}
|
||||
this.dropDown.setValues({'urlInput':url,'textInput':text});
|
||||
//dijit.focus(this.urlInput);
|
||||
},
|
||||
|
||||
updateState: function(){
|
||||
// summary: change shading on button if we are over a link (or not)
|
||||
|
||||
var _e = this.editor;
|
||||
if(!_e){ return; }
|
||||
if(!_e.isLoaded){ return; }
|
||||
if(this.button){
|
||||
try{
|
||||
// display button differently if there is an existing link associated with the current selection
|
||||
var hasA = dojo.withGlobal(this.editor.window, "hasAncestorElement",dijit._editor.selection, ['a']);
|
||||
this.button.setChecked(hasA);
|
||||
}catch(e){
|
||||
console.debug(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
566
spring-faces/src/main/java/META-INF/dijit/_editor/range.js
Normal file
566
spring-faces/src/main/java/META-INF/dijit/_editor/range.js
Normal file
@@ -0,0 +1,566 @@
|
||||
if(!dojo._hasResource["dijit._editor.range"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._editor.range"] = true;
|
||||
dojo.provide("dijit._editor.range");
|
||||
|
||||
dijit.range={};
|
||||
|
||||
dijit.range.getIndex=function(/*DomNode*/node, /*DomNode*/parent){
|
||||
// dojo.profile.start("dijit.range.getIndex");
|
||||
var ret=[], retR=[];
|
||||
var stop = parent;
|
||||
var onode = node;
|
||||
|
||||
while(node != stop){
|
||||
var i = 0;
|
||||
var pnode = node.parentNode, n;
|
||||
while(n=pnode.childNodes[i++]){
|
||||
if(n===node){
|
||||
--i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i>=pnode.childNodes.length){
|
||||
dojo.debug("Error finding index of a node in dijit.range.getIndex");
|
||||
}
|
||||
ret.unshift(i);
|
||||
retR.unshift(i-pnode.childNodes.length);
|
||||
node = pnode;
|
||||
}
|
||||
|
||||
//normalized() can not be called so often to prevent
|
||||
//invalidating selection/range, so we have to detect
|
||||
//here that any text nodes in a row
|
||||
if(ret.length>0 && onode.nodeType==3){
|
||||
var n = onode.previousSibling;
|
||||
while(n && n.nodeType==3){
|
||||
ret[ret.length-1]--;
|
||||
n = n.previousSibling;
|
||||
}
|
||||
n = onode.nextSibling;
|
||||
while(n && n.nodeType==3){
|
||||
retR[retR.length-1]++;
|
||||
n = n.nextSibling;
|
||||
}
|
||||
}
|
||||
// dojo.profile.end("dijit.range.getIndex");
|
||||
return {o: ret, r:retR};
|
||||
}
|
||||
|
||||
dijit.range.getNode = function(/*Array*/index, /*DomNode*/parent){
|
||||
if(!dojo.isArray(index) || index.length==0){
|
||||
return parent;
|
||||
}
|
||||
var node = parent;
|
||||
// if(!node)debugger
|
||||
dojo.every(index, function(i){
|
||||
if(i>=0&&i< node.childNodes.length){
|
||||
node = node.childNodes[i];
|
||||
}else{
|
||||
node = null;
|
||||
console.debug('Error: can not find node with index',index,'under parent node',parent );
|
||||
return false; //terminate dojo.every
|
||||
}
|
||||
return true; //carry on the every loop
|
||||
});
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
dijit.range.getCommonAncestor = function(n1,n2,root){
|
||||
var getAncestors = function(n,root){
|
||||
var as=[];
|
||||
while(n){
|
||||
as.unshift(n);
|
||||
if(n!=root && n.tagName!='BODY'){
|
||||
n = n.parentNode;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return as;
|
||||
};
|
||||
var n1as = getAncestors(n1,root);
|
||||
var n2as = getAncestors(n2,root);
|
||||
|
||||
var m = Math.min(n1as.length,n2as.length);
|
||||
var com = n1as[0]; //at least, one element should be in the array: the root (BODY by default)
|
||||
for(var i=1;i<m;i++){
|
||||
if(n1as[i]===n2as[i]){
|
||||
com = n1as[i]
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return com;
|
||||
}
|
||||
|
||||
dijit.range.getAncestor = function(/*DomNode*/node, /*RegEx?*/regex, /*DomNode?*/root){
|
||||
root = root || node.ownerDocument.body;
|
||||
while(node && node !== root){
|
||||
var name = node.nodeName.toUpperCase() ;
|
||||
if(regex.test(name)){
|
||||
return node;
|
||||
}
|
||||
|
||||
node = node.parentNode;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
dijit.range.BlockTagNames = /^(?:P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|DT|DE)$/;
|
||||
dijit.range.getBlockAncestor = function(/*DomNode*/node, /*RegEx?*/regex, /*DomNode?*/root){
|
||||
root = root || node.ownerDocument.body;
|
||||
regex = regex || dijit.range.BlockTagNames;
|
||||
var block=null, blockContainer;
|
||||
while(node && node !== root){
|
||||
var name = node.nodeName.toUpperCase() ;
|
||||
if(!block && regex.test(name)){
|
||||
block = node;
|
||||
}
|
||||
if(!blockContainer && (/^(?:BODY|TD|TH|CAPTION)$/).test(name)){
|
||||
blockContainer = node;
|
||||
}
|
||||
|
||||
node = node.parentNode;
|
||||
}
|
||||
return {blockNode:block, blockContainer:blockContainer || node.ownerDocument.body};
|
||||
}
|
||||
|
||||
dijit.range.atBeginningOfContainer = function(/*DomNode*/container, /*DomNode*/node, /*Int*/offset){
|
||||
var atBeginning = false;
|
||||
var offsetAtBeginning = (offset == 0);
|
||||
if(!offsetAtBeginning && node.nodeType==3){ //if this is a text node, check whether the left part is all space
|
||||
if(dojo.trim(node.nodeValue.substr(0,offset))==0){
|
||||
offsetAtBeginning = true;
|
||||
}
|
||||
}
|
||||
if(offsetAtBeginning){
|
||||
var cnode = node;
|
||||
atBeginning = true;
|
||||
while(cnode && cnode !== container){
|
||||
if(cnode.previousSibling){
|
||||
atBeginning = false;
|
||||
break;
|
||||
}
|
||||
cnode = cnode.parentNode;
|
||||
}
|
||||
}
|
||||
return atBeginning;
|
||||
}
|
||||
|
||||
dijit.range.atEndOfContainer = function(/*DomNode*/container, /*DomNode*/node, /*Int*/offset){
|
||||
var atEnd = false;
|
||||
var offsetAtEnd = (offset == (node.length || node.childNodes.length));
|
||||
if(!offsetAtEnd && node.nodeType==3){ //if this is a text node, check whether the right part is all space
|
||||
if(dojo.trim(node.nodeValue.substr(offset))==0){
|
||||
offsetAtEnd = true;
|
||||
}
|
||||
}
|
||||
if(offsetAtEnd){
|
||||
var cnode = node;
|
||||
atEnd = true;
|
||||
while(cnode && cnode !== container){
|
||||
if(cnode.nextSibling){
|
||||
atEnd = false;
|
||||
break;
|
||||
}
|
||||
cnode = cnode.parentNode;
|
||||
}
|
||||
}
|
||||
return atEnd;
|
||||
}
|
||||
|
||||
dijit.range.adjacentNoneTextNode=function(startnode, next){
|
||||
var node = startnode;
|
||||
var len = (0-startnode.length) || 0;
|
||||
var prop = next?'nextSibling':'previousSibling';
|
||||
while(node){
|
||||
if(node.nodeType!=3){
|
||||
break;
|
||||
}
|
||||
len += node.length
|
||||
node = node[prop];
|
||||
}
|
||||
return [node,len];
|
||||
}
|
||||
|
||||
dijit.range._w3c = Boolean(window['getSelection']);
|
||||
dijit.range.create = function(){
|
||||
if(dijit.range._w3c){
|
||||
return document.createRange();
|
||||
}else{//IE
|
||||
return new dijit.range.W3CRange;
|
||||
}
|
||||
}
|
||||
|
||||
dijit.range.getSelection = function(win, /*Boolean?*/ignoreUpdate){
|
||||
if(dijit.range._w3c){
|
||||
return win.getSelection();
|
||||
}else{//IE
|
||||
var id=win.__W3CRange;
|
||||
if(!id || !dijit.range.ie.cachedSelection[id]){
|
||||
var s = new dijit.range.ie.selection(win);
|
||||
//use win as the key in an object is not reliable, which
|
||||
//can leads to quite odd behaviors. thus we generate a
|
||||
//string and use it as a key in the cache
|
||||
id=(new Date).getTime();
|
||||
while(id in dijit.range.ie.cachedSelection){
|
||||
id=id+1;
|
||||
}
|
||||
id=String(id);
|
||||
dijit.range.ie.cachedSelection[id] = s;
|
||||
}else{
|
||||
var s = dijit.range.ie.cachedSelection[id];
|
||||
}
|
||||
if(!ignoreUpdate){
|
||||
s._getCurrentSelection();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
if(!dijit.range._w3c){
|
||||
dijit.range.ie={
|
||||
cachedSelection: {},
|
||||
selection: function(win){
|
||||
this._ranges = [];
|
||||
this.addRange = function(r, /*boolean*/internal){
|
||||
this._ranges.push(r);
|
||||
if(!internal){
|
||||
r._select();
|
||||
}
|
||||
this.rangeCount = this._ranges.length;
|
||||
};
|
||||
this.removeAllRanges = function(){
|
||||
//don't detach, the range may be used later
|
||||
// for(var i=0;i<this._ranges.length;i++){
|
||||
// this._ranges[i].detach();
|
||||
// }
|
||||
this._ranges = [];
|
||||
this.rangeCount = 0;
|
||||
};
|
||||
var _initCurrentRange = function(){
|
||||
var r = win.document.selection.createRange();
|
||||
var type=win.document.selection.type.toUpperCase();
|
||||
if(type == "CONTROL"){
|
||||
//TODO: multiple range selection(?)
|
||||
return new dijit.range.W3CRange(dijit.range.ie.decomposeControlRange(r));
|
||||
}else{
|
||||
return new dijit.range.W3CRange(dijit.range.ie.decomposeTextRange(r));
|
||||
}
|
||||
};
|
||||
this.getRangeAt = function(i){
|
||||
return this._ranges[i];
|
||||
};
|
||||
this._getCurrentSelection = function(){
|
||||
this.removeAllRanges();
|
||||
var r=_initCurrentRange();
|
||||
if(r){
|
||||
this.addRange(r, true);
|
||||
}
|
||||
};
|
||||
},
|
||||
decomposeControlRange: function(range){
|
||||
var firstnode = range.item(0), lastnode = range.item(range.length-1)
|
||||
var startContainer = firstnode.parentNode, endContainer = lastnode.parentNode;
|
||||
var startOffset = dijit.range.getIndex(firstnode, startContainer).o;
|
||||
var endOffset = dijit.range.getIndex(lastnode, endContainer).o+1;
|
||||
return [[startContainer, startOffset],[endContainer, endOffset]];
|
||||
},
|
||||
getEndPoint: function(range, end){
|
||||
var atmrange = range.duplicate();
|
||||
atmrange.collapse(!end);
|
||||
var cmpstr = 'EndTo' + (end?'End':'Start');
|
||||
var parentNode = atmrange.parentElement();
|
||||
|
||||
var startnode, startOffset, lastNode;
|
||||
if(parentNode.childNodes.length>0){
|
||||
dojo.every(parentNode.childNodes, function(node,i){
|
||||
var calOffset;
|
||||
if(node.nodeType != 3){
|
||||
atmrange.moveToElementText(node);
|
||||
|
||||
if(atmrange.compareEndPoints(cmpstr,range) > 0){
|
||||
startnode = node.previousSibling;
|
||||
if(lastNode && lastNode.nodeType == 3){
|
||||
//where share we put the start? in the text node or after?
|
||||
startnode = lastNode;
|
||||
calOffset = true;
|
||||
}else{
|
||||
startnode = parentNode;
|
||||
startOffset = i;
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
if(i==parentNode.childNodes.length-1){
|
||||
startnode = parentNode;
|
||||
startOffset = parentNode.childNodes.length;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if(i==parentNode.childNodes.length-1){//at the end of this node
|
||||
startnode = node;
|
||||
calOffset = true;
|
||||
}
|
||||
}
|
||||
// try{
|
||||
if(calOffset && startnode){
|
||||
var prevnode = dijit.range.adjacentNoneTextNode(startnode)[0];
|
||||
if(prevnode){
|
||||
startnode = prevnode.nextSibling;
|
||||
}else{
|
||||
startnode = parentNode.firstChild; //firstChild must be a text node
|
||||
}
|
||||
var prevnodeobj = dijit.range.adjacentNoneTextNode(startnode);
|
||||
prevnode = prevnodeobj[0];
|
||||
var lenoffset = prevnodeobj[1];
|
||||
if(prevnode){
|
||||
atmrange.moveToElementText(prevnode);
|
||||
atmrange.collapse(false);
|
||||
}else{
|
||||
atmrange.moveToElementText(parentNode);
|
||||
}
|
||||
atmrange.setEndPoint(cmpstr, range);
|
||||
startOffset = atmrange.text.length-lenoffset;
|
||||
|
||||
return false;
|
||||
}
|
||||
// }catch(e){ debugger }
|
||||
lastNode = node;
|
||||
return true;
|
||||
});
|
||||
}else{
|
||||
startnode = parentNode;
|
||||
startOffset = 0;
|
||||
}
|
||||
|
||||
//if at the end of startnode and we are dealing with start container, then
|
||||
//move the startnode to nextSibling if it is a text node
|
||||
//TODO: do this for end container?
|
||||
if(!end && startnode.nodeType!=3 && startOffset == startnode.childNodes.length){
|
||||
if(startnode.nextSibling && startnode.nextSibling.nodeType==3){
|
||||
startnode = startnode.nextSibling;
|
||||
startOffset = 0;
|
||||
}
|
||||
}
|
||||
return [startnode, startOffset];
|
||||
},
|
||||
setEndPoint: function(range, container, offset){
|
||||
//text node
|
||||
var atmrange = range.duplicate();
|
||||
if(container.nodeType!=3){ //normal node
|
||||
atmrange.moveToElementText(container);
|
||||
atmrange.collapse(true);
|
||||
if(offset == container.childNodes.length){
|
||||
if(offset > 0){
|
||||
//a simple atmrange.collapse(false); won't work here:
|
||||
//although moveToElementText(node) is supposed to encompass the content of the node,
|
||||
//but when collapse to end, it is in fact after the ending tag of node (collapse to start
|
||||
//is after the begining tag of node as expected)
|
||||
var node = container.lastChild;
|
||||
var len = 0;
|
||||
while(node && node.nodeType == 3){
|
||||
len += node.length;
|
||||
container = node; //pass through
|
||||
node = node.previousSibling;
|
||||
}
|
||||
if(node){
|
||||
atmrange.moveToElementText(node);
|
||||
}
|
||||
atmrange.collapse(false);
|
||||
offset = len; //pass through
|
||||
}else{ //no childNodes
|
||||
atmrange.moveToElementText(container);
|
||||
atmrange.collapse(true);
|
||||
}
|
||||
}else{
|
||||
if(offset > 0){
|
||||
var node = container.childNodes[offset-1];
|
||||
if(node.nodeType==3){
|
||||
container = node;
|
||||
offset = node.length;
|
||||
//pass through
|
||||
}else{
|
||||
atmrange.moveToElementText(node);
|
||||
atmrange.collapse(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(container.nodeType==3){
|
||||
var prevnodeobj = dijit.range.adjacentNoneTextNode(container);
|
||||
var prevnode = prevnodeobj[0], len = prevnodeobj[1];
|
||||
if(prevnode){
|
||||
atmrange.moveToElementText(prevnode);
|
||||
atmrange.collapse(false);
|
||||
//if contentEditable is not inherit, the above collapse won't make the end point
|
||||
//in the correctly position: it always has a -1 offset, so compensate it
|
||||
if(prevnode.contentEditable!='inherit'){
|
||||
len++;
|
||||
}
|
||||
}else{
|
||||
atmrange.moveToElementText(container.parentNode);
|
||||
atmrange.collapse(true);
|
||||
}
|
||||
|
||||
offset += len;
|
||||
if(offset>0){
|
||||
if(atmrange.moveEnd('character',offset) != offset){
|
||||
alert('Error when moving!');
|
||||
}
|
||||
atmrange.collapse(false);
|
||||
}
|
||||
}
|
||||
|
||||
return atmrange;
|
||||
},
|
||||
decomposeTextRange: function(range){
|
||||
var tmpary = dijit.range.ie.getEndPoint(range);
|
||||
var startContainter = tmpary[0], startOffset = tmpary[1];
|
||||
var endContainter = tmpary[0], endOffset = tmpary[1];
|
||||
|
||||
if(range.htmlText.length){
|
||||
if(range.htmlText == range.text){ //in the same text node
|
||||
endOffset = startOffset+range.text.length;
|
||||
}else{
|
||||
tmpary = dijit.range.ie.getEndPoint(range,true);
|
||||
endContainter = tmpary[0], endOffset = tmpary[1];
|
||||
}
|
||||
}
|
||||
return [[startContainter, startOffset],[endContainter, endOffset], range.parentElement()];
|
||||
},
|
||||
setRange: function(range, startContainter,
|
||||
startOffset, endContainter, endOffset, check){
|
||||
var startrange = dijit.range.ie.setEndPoint(range, startContainter, startOffset);
|
||||
range.setEndPoint('StartToStart', startrange);
|
||||
if(!this.collapsed){
|
||||
var endrange = dijit.range.ie.setEndPoint(range, endContainter, endOffset);
|
||||
range.setEndPoint('EndToEnd', endrange);
|
||||
}
|
||||
|
||||
return range;
|
||||
}
|
||||
}
|
||||
|
||||
dojo.declare("dijit.range.W3CRange",null, {
|
||||
constructor: function(){
|
||||
if(arguments.length>0){
|
||||
this.setStart(arguments[0][0][0],arguments[0][0][1]);
|
||||
this.setEnd(arguments[0][1][0],arguments[0][1][1],arguments[0][2]);
|
||||
}else{
|
||||
this.commonAncestorContainer = null;
|
||||
this.startContainer = null;
|
||||
this.startOffset = 0;
|
||||
this.endContainer = null;
|
||||
this.endOffset = 0;
|
||||
this.collapsed = true;
|
||||
}
|
||||
},
|
||||
_simpleSetEndPoint: function(node, range, end){
|
||||
var r = (this._body||node.ownerDocument.body).createTextRange();
|
||||
if(node.nodeType!=1){
|
||||
r.moveToElementText(node.parentNode);
|
||||
}else{
|
||||
r.moveToElementText(node);
|
||||
}
|
||||
r.collapse(true);
|
||||
range.setEndPoint(end?'EndToEnd':'StartToStart',r);
|
||||
},
|
||||
_updateInternal: function(__internal_common){
|
||||
if(this.startContainer !== this.endContainer){
|
||||
if(!__internal_common){
|
||||
var r = (this._body||this.startContainer.ownerDocument.body).createTextRange();
|
||||
this._simpleSetEndPoint(this.startContainer,r);
|
||||
this._simpleSetEndPoint(this.endContainer,r,true);
|
||||
__internal_common = r.parentElement();
|
||||
}
|
||||
this.commonAncestorContainer = dijit.range.getCommonAncestor(this.startContainer, this.endContainer, __internal_common);
|
||||
}else{
|
||||
this.commonAncestorContainer = this.startContainer;
|
||||
}
|
||||
this.collapsed = (this.startContainer === this.endContainer) && (this.startOffset == this.endOffset);
|
||||
},
|
||||
setStart: function(node, offset, __internal_common){
|
||||
if(this.startContainer === node && this.startOffset == offset){
|
||||
return;
|
||||
}
|
||||
delete this._cachedBookmark;
|
||||
|
||||
this.startContainer = node;
|
||||
this.startOffset = offset;
|
||||
if(!this.endContainer){
|
||||
this.setEnd(node, offset, __internal_common);
|
||||
}else{
|
||||
this._updateInternal(__internal_common);
|
||||
}
|
||||
},
|
||||
setEnd: function(node, offset, __internal_common){
|
||||
if(this.endContainer === node && this.endOffset == offset){
|
||||
return;
|
||||
}
|
||||
delete this._cachedBookmark;
|
||||
|
||||
this.endContainer = node;
|
||||
this.endOffset = offset;
|
||||
if(!this.startContainer){
|
||||
this.setStart(node, offset, __internal_common);
|
||||
}else{
|
||||
this._updateInternal(__internal_common);
|
||||
}
|
||||
},
|
||||
setStartAfter: function(node, offset){
|
||||
this._setPoint('setStart', node, offset, 1);
|
||||
},
|
||||
setStartBefore: function(node, offset){
|
||||
this._setPoint('setStart', node, offset, 0);
|
||||
},
|
||||
setEndAfter: function(node, offset){
|
||||
this._setPoint('setEnd', node, offset, 1);
|
||||
},
|
||||
setEndBefore: function(node, offset){
|
||||
this._setPoint('setEnd', node, offset, 0);
|
||||
},
|
||||
_setPoint: function(what, node, offset, ext){
|
||||
var index = dijit.range.getIndex(node, node.parentNode).o;
|
||||
this[what](node.parentNode, index.pop()+ext);
|
||||
},
|
||||
_getIERange: function(){
|
||||
var r=(this._body||this.endContainer.ownerDocument.body).createTextRange();
|
||||
dijit.range.ie.setRange(r, this.startContainer, this.startOffset, this.endContainer, this.endOffset);
|
||||
return r;
|
||||
},
|
||||
getBookmark: function(body){
|
||||
this._getIERange();
|
||||
return this._cachedBookmark;
|
||||
},
|
||||
_select: function(){
|
||||
var r = this._getIERange();
|
||||
r.select();
|
||||
},
|
||||
deleteContents: function(){
|
||||
var r = this._getIERange();
|
||||
r.pasteHTML('');
|
||||
this.endContainer = this.startContainer;
|
||||
this.endOffset = this.startOffset;
|
||||
this.collapsed = true;
|
||||
},
|
||||
cloneRange: function(){
|
||||
var r = new dijit.range.W3CRange([[this.startContainer,this.startOffset],
|
||||
[this.endContainer,this.endOffset]]);
|
||||
r._body = this._body;
|
||||
return r;
|
||||
},
|
||||
detach: function(){
|
||||
this._body = null;
|
||||
this.commonAncestorContainer = null;
|
||||
this.startContainer = null;
|
||||
this.startOffset = 0;
|
||||
this.endContainer = null;
|
||||
this.endOffset = 0;
|
||||
this.collapsed = true;
|
||||
}
|
||||
});
|
||||
} //if(!dijit.range._w3c)
|
||||
|
||||
}
|
||||
220
spring-faces/src/main/java/META-INF/dijit/_editor/selection.js
Normal file
220
spring-faces/src/main/java/META-INF/dijit/_editor/selection.js
Normal file
@@ -0,0 +1,220 @@
|
||||
if(!dojo._hasResource["dijit._editor.selection"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._editor.selection"] = true;
|
||||
dojo.provide("dijit._editor.selection");
|
||||
|
||||
// FIXME:
|
||||
// all of these methods branch internally for IE. This is probably
|
||||
// sub-optimal in terms of runtime performance. We should investigate the
|
||||
// size difference for differentiating at definition time.
|
||||
|
||||
dojo.mixin(dijit._editor.selection, {
|
||||
getType: function(){
|
||||
// summary: Get the selection type (like document.select.type in IE).
|
||||
if(dojo.doc["selection"]){ //IE
|
||||
return dojo.doc.selection.type.toLowerCase();
|
||||
}else{
|
||||
var stype = "text";
|
||||
|
||||
// Check if the actual selection is a CONTROL (IMG, TABLE, HR, etc...).
|
||||
var oSel;
|
||||
try{
|
||||
oSel = dojo.global.getSelection();
|
||||
}catch(e){ /*squelch*/ }
|
||||
|
||||
if(oSel && oSel.rangeCount==1){
|
||||
var oRange = oSel.getRangeAt(0);
|
||||
if( (oRange.startContainer == oRange.endContainer) &&
|
||||
((oRange.endOffset - oRange.startOffset) == 1) &&
|
||||
(oRange.startContainer.nodeType != 3 /* text node*/)
|
||||
){
|
||||
stype = "control";
|
||||
}
|
||||
}
|
||||
return stype;
|
||||
}
|
||||
},
|
||||
|
||||
getSelectedText: function(){
|
||||
// summary:
|
||||
// Return the text (no html tags) included in the current selection or null if no text is selected
|
||||
if(dojo.doc["selection"]){ //IE
|
||||
if(dijit._editor.selection.getType() == 'control'){
|
||||
return null;
|
||||
}
|
||||
return dojo.doc.selection.createRange().text;
|
||||
}else{
|
||||
var selection = dojo.global.getSelection();
|
||||
if(selection){
|
||||
return selection.toString();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getSelectedHtml: function(){
|
||||
// summary:
|
||||
// Return the html of the current selection or null if unavailable
|
||||
if(dojo.doc["selection"]){ //IE
|
||||
if(dijit._editor.selection.getType() == 'control'){
|
||||
return null;
|
||||
}
|
||||
return dojo.doc.selection.createRange().htmlText;
|
||||
}else{
|
||||
var selection = dojo.global.getSelection();
|
||||
if(selection && selection.rangeCount){
|
||||
var frag = selection.getRangeAt(0).cloneContents();
|
||||
var div = document.createElement("div");
|
||||
div.appendChild(frag);
|
||||
return div.innerHTML;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
getSelectedElement: function(){
|
||||
// summary:
|
||||
// Retrieves the selected element (if any), just in the case that
|
||||
// a single element (object like and image or a table) is
|
||||
// selected.
|
||||
if(this.getType() == "control"){
|
||||
if(dojo.doc["selection"]){ //IE
|
||||
var range = dojo.doc.selection.createRange();
|
||||
if(range && range.item){
|
||||
return dojo.doc.selection.createRange().item(0);
|
||||
}
|
||||
}else{
|
||||
var selection = dojo.global.getSelection();
|
||||
return selection.anchorNode.childNodes[ selection.anchorOffset ];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getParentElement: function(){
|
||||
// summary:
|
||||
// Get the parent element of the current selection
|
||||
if(this.getType() == "control"){
|
||||
var p = this.getSelectedElement();
|
||||
if(p){ return p.parentNode; }
|
||||
}else{
|
||||
if(dojo.doc["selection"]){ //IE
|
||||
return dojo.doc.selection.createRange().parentElement();
|
||||
}else{
|
||||
var selection = dojo.global.getSelection();
|
||||
if(selection){
|
||||
var node = selection.anchorNode;
|
||||
|
||||
while(node && (node.nodeType != 1)){ // not an element
|
||||
node = node.parentNode;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
hasAncestorElement: function(/*String*/tagName /* ... */){
|
||||
// summary:
|
||||
// Check whether current selection has a parent element which is
|
||||
// of type tagName (or one of the other specified tagName)
|
||||
return (this.getAncestorElement.apply(this, arguments) != null);
|
||||
},
|
||||
|
||||
getAncestorElement: function(/*String*/tagName /* ... */){
|
||||
// summary:
|
||||
// Return the parent element of the current selection which is of
|
||||
// type tagName (or one of the other specified tagName)
|
||||
|
||||
var node = this.getSelectedElement() || this.getParentElement();
|
||||
return this.getParentOfType(node, arguments);
|
||||
},
|
||||
|
||||
isTag: function(/*DomNode*/node, /*Array*/tags){
|
||||
if(node && node.tagName){
|
||||
var _nlc = node.tagName.toLowerCase();
|
||||
for(var i=0; i<tags.length; i++){
|
||||
var _tlc = String(tags[i]).toLowerCase();
|
||||
if(_nlc == _tlc){
|
||||
return _tlc;
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
},
|
||||
|
||||
getParentOfType: function(/*DomNode*/node, /*Array*/tags){
|
||||
while(node){
|
||||
if(this.isTag(node, tags).length){
|
||||
return node;
|
||||
}
|
||||
node = node.parentNode;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
remove: function(){
|
||||
// summary: delete current selection
|
||||
var _s = dojo.doc.selection;
|
||||
if(_s){ //IE
|
||||
if(_s.type.toLowerCase() != "none"){
|
||||
_s.clear();
|
||||
}
|
||||
return _s;
|
||||
}else{
|
||||
_s = dojo.global.getSelection();
|
||||
_s.deleteFromDocument();
|
||||
return _s;
|
||||
}
|
||||
},
|
||||
|
||||
selectElementChildren: function(/*DomNode*/element,/*Boolean?*/nochangefocus){
|
||||
// summary:
|
||||
// clear previous selection and select the content of the node
|
||||
// (excluding the node itself)
|
||||
var _window = dojo.global;
|
||||
var _document = dojo.doc;
|
||||
element = dojo.byId(element);
|
||||
if(_document.selection && dojo.body().createTextRange){ // IE
|
||||
var range = element.ownerDocument.body.createTextRange();
|
||||
range.moveToElementText(element);
|
||||
if(!nochangefocus){
|
||||
range.select();
|
||||
}
|
||||
}else if(_window["getSelection"]){
|
||||
var selection = _window.getSelection();
|
||||
if(selection["setBaseAndExtent"]){ // Safari
|
||||
selection.setBaseAndExtent(element, 0, element, element.innerText.length - 1);
|
||||
}else if(selection["selectAllChildren"]){ // Mozilla
|
||||
selection.selectAllChildren(element);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
selectElement: function(/*DomNode*/element,/*Boolean?*/nochangefocus){
|
||||
// summary:
|
||||
// clear previous selection and select element (including all its children)
|
||||
var _document = dojo.doc;
|
||||
element = dojo.byId(element);
|
||||
if(_document.selection && dojo.body().createTextRange){ // IE
|
||||
try{
|
||||
var range = dojo.body().createControlRange();
|
||||
range.addElement(element);
|
||||
if(!nochangefocus){
|
||||
range.select();
|
||||
}
|
||||
}catch(e){
|
||||
this.selectElementChildren(element,nochangefocus);
|
||||
}
|
||||
}else if(dojo.global["getSelection"]){
|
||||
var selection = dojo.global.getSelection();
|
||||
// FIXME: does this work on Safari?
|
||||
if(selection["removeAllRanges"]){ // Mozilla
|
||||
var range = _document.createRange() ;
|
||||
range.selectNode(element) ;
|
||||
selection.removeAllRanges() ;
|
||||
selection.addRange(range) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
408
spring-faces/src/main/java/META-INF/dijit/_tree/Controller.js
Normal file
408
spring-faces/src/main/java/META-INF/dijit/_tree/Controller.js
Normal file
@@ -0,0 +1,408 @@
|
||||
if(!dojo._hasResource["dijit._tree.Controller"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._tree.Controller"] = true;
|
||||
dojo.provide("dijit._tree.Controller");
|
||||
|
||||
dojo.require("dijit._Widget");
|
||||
dojo.require("dijit.Tree");
|
||||
|
||||
dojo.declare(
|
||||
"dijit._tree.Controller",
|
||||
[dijit._Widget],
|
||||
{
|
||||
// Summary: _tree.Controller performs all basic operations on Tree
|
||||
// Description:
|
||||
// Controller is the component to operate on model.
|
||||
// Tree/_tree.Node know how to modify themselves and show to user,
|
||||
// but operating on the tree often involves higher-level extensible logic,
|
||||
// like: database synchronization, node loading, reacting on clicks etc.
|
||||
// That's why it is handled by separate controller.
|
||||
// Controller processes expand/collapse and should be used if you
|
||||
// modify a tree.
|
||||
|
||||
// treeId: String
|
||||
// id of Tree widget that I'm controlling
|
||||
treeId: "",
|
||||
|
||||
postMixInProperties: function(){
|
||||
// setup to handle events from tree
|
||||
|
||||
// if the store supports Notification, subscribe to the notifcation events
|
||||
if (this.store._features['dojo.data.api.Notification']){
|
||||
dojo.connect(this.store, "onNew", this, "onNew");
|
||||
dojo.connect(this.store, "onDelete", this, "onDelete");
|
||||
dojo.connect(this.store, "onSet", this, "onSet");
|
||||
}
|
||||
|
||||
|
||||
// setup to handle events from tree
|
||||
dojo.subscribe(this.treeId, this, "_listener");
|
||||
},
|
||||
|
||||
_listener: function(/*Object*/ message){
|
||||
// summary: dispatcher to handle events from tree
|
||||
var event = message.event;
|
||||
var eventHandler = "on" + event.charAt(0).toUpperCase() + event.substr(1);
|
||||
if(this[eventHandler]){
|
||||
this[eventHandler](message);
|
||||
}
|
||||
},
|
||||
|
||||
onBeforeTreeDestroy: function(message){
|
||||
dojo.unsubscribe(message.tree.id);
|
||||
},
|
||||
|
||||
onExecute: function(/*Object*/ message){
|
||||
// summary: an execute event has occured
|
||||
|
||||
message.node.tree.focusNode(message.node);
|
||||
|
||||
// TODO: user guide: tell users to listen for execute events
|
||||
console.log("execute message for " + message.node + ": ", message);
|
||||
},
|
||||
|
||||
onNext: function(/*Object*/ message){
|
||||
// summary: down arrow pressed; get next visible node, set focus there
|
||||
var returnNode = this._navToNextNode(message.node);
|
||||
if(returnNode && returnNode.isTreeNode){
|
||||
returnNode.tree.focusNode(returnNode);
|
||||
return returnNode;
|
||||
}
|
||||
},
|
||||
|
||||
onNew: function(/*Object*/ item, parentInfo){
|
||||
//summary: new event from the store.
|
||||
|
||||
if (parentInfo){
|
||||
var parent = this._itemNodeMap[this.store.getIdentity(parentInfo.item)];
|
||||
}
|
||||
|
||||
var childParams = {item:item};
|
||||
if (parent){
|
||||
if (!parent.isFolder){
|
||||
parent.makeFolder();
|
||||
}
|
||||
if (parent.state=="LOADED" || parent.isExpanded){
|
||||
var childrenMap=parent.addChildren([childParams]);
|
||||
}
|
||||
} else {
|
||||
var childrenMap=this.tree.addChildren([childParams]);
|
||||
}
|
||||
|
||||
if (childrenMap){
|
||||
dojo.mixin(this._itemNodeMap, childrenMap);
|
||||
//this._itemNodeMap[this.store.getIdentity(item)]=child;
|
||||
}
|
||||
},
|
||||
|
||||
onDelete: function(/*Object*/ message){
|
||||
//summary: delete event from the store
|
||||
//since the object has just been deleted, we need to
|
||||
//use the name directly
|
||||
var identity = this.store.getIdentity(message);
|
||||
var node = this._itemNodeMap[identity];
|
||||
|
||||
if (node){
|
||||
parent = node.getParent();
|
||||
parent.deleteNode(node);
|
||||
this._itemNodeMap[identity]=null;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
onSet: function(/*Object*/ message){
|
||||
//summary: set data event on an item in the store
|
||||
var identity = this.store.getIdentity(message);
|
||||
var node = this._itemNodeMap[identity];
|
||||
node.setLabelNode(this.store.getLabel(message));
|
||||
},
|
||||
|
||||
_navToNextNode: function(node){
|
||||
// summary: get next visible node
|
||||
var returnNode;
|
||||
// if this is an expanded node, get the first child
|
||||
if(node.isFolder && node.isExpanded && node.hasChildren()){
|
||||
returnNode = node.getChildren()[0];
|
||||
}else{
|
||||
// find a parent node with a sibling
|
||||
while(node.isTreeNode){
|
||||
returnNode = node.getNextSibling();
|
||||
if(returnNode){
|
||||
break;
|
||||
}
|
||||
node = node.getParent();
|
||||
}
|
||||
}
|
||||
return returnNode;
|
||||
},
|
||||
|
||||
onPrevious: function(/*Object*/ message){
|
||||
// summary: up arrow pressed; move to previous visible node
|
||||
|
||||
var nodeWidget = message.node;
|
||||
var returnWidget = nodeWidget;
|
||||
|
||||
// if younger siblings
|
||||
var previousSibling = nodeWidget.getPreviousSibling();
|
||||
if(previousSibling){
|
||||
nodeWidget = previousSibling;
|
||||
// if the previous nodeWidget is expanded, dive in deep
|
||||
while(nodeWidget.isFolder && nodeWidget.isExpanded && nodeWidget.hasChildren()){
|
||||
returnWidget = nodeWidget;
|
||||
// move to the last child
|
||||
var children = nodeWidget.getChildren();
|
||||
nodeWidget = children[children.length-1];
|
||||
}
|
||||
}else{
|
||||
// if this is the first child, return the parent
|
||||
nodeWidget = nodeWidget.getParent();
|
||||
}
|
||||
|
||||
if(nodeWidget && nodeWidget.isTreeNode){
|
||||
returnWidget = nodeWidget;
|
||||
}
|
||||
|
||||
if(returnWidget && returnWidget.isTreeNode){
|
||||
returnWidget.tree.focusNode(returnWidget);
|
||||
return returnWidget;
|
||||
}
|
||||
},
|
||||
|
||||
onZoomIn: function(/*Object*/ message){
|
||||
// summary: right arrow pressed; go to child node
|
||||
var nodeWidget = message.node;
|
||||
var returnWidget = nodeWidget;
|
||||
|
||||
// if not expanded, expand, else move to 1st child
|
||||
if(nodeWidget.isFolder && !nodeWidget.isExpanded){
|
||||
this._expand(nodeWidget);
|
||||
}else if(nodeWidget.hasChildren()){
|
||||
nodeWidget = nodeWidget.getChildren()[0];
|
||||
}
|
||||
|
||||
if(nodeWidget && nodeWidget.isTreeNode){
|
||||
returnWidget = nodeWidget;
|
||||
}
|
||||
|
||||
if(returnWidget && returnWidget.isTreeNode){
|
||||
returnWidget.tree.focusNode(returnWidget);
|
||||
return returnWidget;
|
||||
}
|
||||
},
|
||||
|
||||
onZoomOut: function(/*Object*/ message){
|
||||
// summary: left arrow pressed; go to parent
|
||||
|
||||
var node = message.node;
|
||||
var returnWidget = node;
|
||||
|
||||
// if not collapsed, collapse, else move to parent
|
||||
if(node.isFolder && node.isExpanded){
|
||||
this._collapse(node);
|
||||
}else{
|
||||
node = node.getParent();
|
||||
}
|
||||
if(node && node.isTreeNode){
|
||||
returnWidget = node;
|
||||
}
|
||||
|
||||
if(returnWidget && returnWidget.isTreeNode){
|
||||
returnWidget.tree.focusNode(returnWidget);
|
||||
return returnWidget;
|
||||
}
|
||||
},
|
||||
|
||||
onFirst: function(/*Object*/ message){
|
||||
// summary: home pressed; get first visible node, set focus there
|
||||
var returnNode = this._navToFirstNode(message.tree);
|
||||
if(returnNode){
|
||||
returnNode.tree.focusNode(returnNode);
|
||||
return returnNode;
|
||||
}
|
||||
},
|
||||
|
||||
_navToFirstNode: function(/*Object*/ tree){
|
||||
// summary: get first visible node
|
||||
var returnNode;
|
||||
if(tree){
|
||||
returnNode = tree.getChildren()[0];
|
||||
if(returnNode && returnNode.isTreeNode){
|
||||
return returnNode;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onLast: function(/*Object*/ message){
|
||||
// summary: end pressed; go to last visible node
|
||||
|
||||
var returnWidget = message.node.tree;
|
||||
|
||||
var lastChild = returnWidget;
|
||||
while(lastChild.isExpanded){
|
||||
var c = lastChild.getChildren();
|
||||
lastChild = c[c.length - 1];
|
||||
if(lastChild.isTreeNode){
|
||||
returnWidget = lastChild;
|
||||
}
|
||||
}
|
||||
|
||||
if(returnWidget && returnWidget.isTreeNode){
|
||||
returnWidget.tree.focusNode(returnWidget);
|
||||
return returnWidget;
|
||||
}
|
||||
},
|
||||
|
||||
onToggleOpen: function(/*Object*/ message){
|
||||
// summary: user clicked the +/- icon; expand or collapse my children.
|
||||
var node = message.node;
|
||||
if(node.isExpanded){
|
||||
this._collapse(node);
|
||||
}else{
|
||||
this._expand(node);
|
||||
}
|
||||
},
|
||||
|
||||
onLetterKeyNav: function(message){
|
||||
// summary: letter key pressed; search for node starting with first char = key
|
||||
var node = startNode = message.node;
|
||||
var tree = message.tree;
|
||||
var key = message.key;
|
||||
do{
|
||||
node = this._navToNextNode(node);
|
||||
//check for last node, jump to first node if necessary
|
||||
if(!node){
|
||||
node = this._navToFirstNode(tree);
|
||||
}
|
||||
}while(node !== startNode && (node.label.charAt(0).toLowerCase() != key));
|
||||
if(node && node.isTreeNode){
|
||||
// no need to set focus if back where we started
|
||||
if(node !== startNode){
|
||||
node.tree.focusNode(node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
},
|
||||
|
||||
_expand: function(node){
|
||||
if(node.isFolder){
|
||||
node.expand(); // skip trees or non-folders
|
||||
var t = node.tree;
|
||||
if(t.lastFocused){ t.focusNode(t.lastFocused); } // restore focus
|
||||
}
|
||||
},
|
||||
|
||||
_collapse: function(node){
|
||||
if(node.isFolder){
|
||||
// are we collapsing a child that has the tab index?
|
||||
if(dojo.query("[tabindex=0]", node.domNode).length > 0){
|
||||
node.tree.focusNode(node);
|
||||
}
|
||||
node.collapse();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
dojo.declare(
|
||||
"dijit._tree.DataController",
|
||||
dijit._tree.Controller,
|
||||
{
|
||||
// summary
|
||||
// Controller for tree that hooks up to dojo.data
|
||||
|
||||
onAfterTreeCreate: function(message){
|
||||
// when a tree is created, we query against the store to get the top level nodes
|
||||
// in the tree
|
||||
var tree = this.tree = message.tree;
|
||||
this._itemNodeMap={};
|
||||
|
||||
var _this = this;
|
||||
function onComplete(/*dojo.data.Item[]*/ items){
|
||||
var childParams=dojo.map(items,
|
||||
function(item){
|
||||
return {
|
||||
item: item,
|
||||
isFolder: _this.store.hasAttribute(item, _this.childrenAttr)
|
||||
};
|
||||
});
|
||||
|
||||
_this._itemNodeMap = tree.setChildren(childParams);
|
||||
}
|
||||
|
||||
this.store.fetch({ query: this.query, onComplete: onComplete });
|
||||
},
|
||||
|
||||
_expand: function(/*_TreeNode*/ node){
|
||||
var store = this.store;
|
||||
var getValue = this.store.getValue;
|
||||
|
||||
switch(node.state){
|
||||
case "LOADING":
|
||||
// ignore clicks while we are in the process of loading data
|
||||
return;
|
||||
|
||||
case "UNCHECKED":
|
||||
// need to load all the children, and then expand
|
||||
var parentItem = node.item;
|
||||
var childItems = store.getValues(parentItem, this.childrenAttr);
|
||||
|
||||
// count how many items need to be loaded
|
||||
var _waitCount = 0;
|
||||
dojo.forEach(childItems, function(item){ if(!store.isItemLoaded(item)){ _waitCount++; } });
|
||||
|
||||
if(_waitCount == 0){
|
||||
// all items are already loaded. proceed..
|
||||
this._onLoadAllItems(node, childItems);
|
||||
}else{
|
||||
// still waiting for some or all of the items to load
|
||||
node.markProcessing();
|
||||
|
||||
var _this = this;
|
||||
function onItem(item){
|
||||
if(--_waitCount == 0){
|
||||
// all nodes have been loaded, send them to the tree
|
||||
node.unmarkProcessing();
|
||||
_this._onLoadAllItems(node, childItems);
|
||||
}
|
||||
}
|
||||
dojo.forEach(childItems, function(item){
|
||||
if(!store.isItemLoaded(item)){
|
||||
store.loadItem({item: item, onItem: onItem});
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// data is already loaded; just proceed
|
||||
dijit._tree.Controller.prototype._expand.apply(this, arguments);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
_onLoadAllItems: function(/*_TreeNode*/ node, /*dojo.data.Item[]*/ items){
|
||||
// sumary: callback when all the children of a given node have been loaded
|
||||
// TODO: should this be used when the top level nodes are loaded too?
|
||||
var childParams=dojo.map(items, function(item){
|
||||
return {
|
||||
item: item,
|
||||
isFolder: this.store.hasAttribute(item, this.childrenAttr)
|
||||
};
|
||||
}, this);
|
||||
|
||||
dojo.mixin(this._itemNodeMap,node.setChildren(childParams));
|
||||
|
||||
dijit._tree.Controller.prototype._expand.apply(this, arguments);
|
||||
},
|
||||
|
||||
_collapse: function(/*_TreeNode*/ node){
|
||||
if(node.state == "LOADING"){
|
||||
// ignore clicks while we are in the process of loading data
|
||||
return;
|
||||
}
|
||||
dijit._tree.Controller.prototype._collapse.apply(this, arguments);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
11
spring-faces/src/main/java/META-INF/dijit/_tree/Node.html
Normal file
11
spring-faces/src/main/java/META-INF/dijit/_tree/Node.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<div class="dijitTreeNode dijitTreeExpandLeaf dijitTreeChildrenNo" waiRole="presentation"
|
||||
><span dojoAttachPoint="expandoNode" class="dijitTreeExpando" waiRole="presentation"
|
||||
></span
|
||||
><span dojoAttachPoint="expandoNodeText" class="dijitExpandoText" waiRole="presentation"
|
||||
></span
|
||||
>
|
||||
<div dojoAttachPoint="contentNode" class="dijitTreeContent" waiRole="presentation">
|
||||
<div dojoAttachPoint="iconNode" class="dijitInline dijitTreeIcon" waiRole="presentation"></div>
|
||||
<span dojoAttachPoint=labelNode class="dijitTreeLabel" wairole="treeitem" expanded="true" tabindex="-1"></span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
<div class="dijitTreeContainer" style="" waiRole="tree"
|
||||
dojoAttachEvent="onclick:_onClick,onkeypress:_onKeyPress"
|
||||
></div>
|
||||
127
spring-faces/src/main/java/META-INF/dijit/bench/benchReceive.php
Normal file
127
spring-faces/src/main/java/META-INF/dijit/bench/benchReceive.php
Normal file
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
/*
|
||||
|
||||
benchReceive.php - example way to handle incoming benchmark data,
|
||||
or how to use JSON php class to mangle data. No benchmark data
|
||||
is stored currently.
|
||||
|
||||
--
|
||||
-- Table structure for table `benchmarks`
|
||||
--
|
||||
|
||||
CREATE TABLE `benchmarks` (
|
||||
`id` int(11) NOT NULL auto_increment,
|
||||
`useragent` varchar(242) NOT NULL default '',
|
||||
`dojover` varchar(96) NOT NULL default '',
|
||||
`testNum` int(11) NOT NULL default '0',
|
||||
`dijit` varchar(64) NOT NULL default '',
|
||||
`testCount` int(11) NOT NULL default '0',
|
||||
`testAverage` float NOT NULL default '0',
|
||||
`testMethod` varchar(10) NOT NULL default '',
|
||||
`testTime` bigint(20) NOT NULL default '0',
|
||||
`dataSet` varchar(64) NOT NULL default '',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `dijit` (`dijit`,`testAverage`),
|
||||
KEY `dataSet` (`dataSet`)
|
||||
) TYPE=MyISAM;
|
||||
|
||||
--
|
||||
-- [end table struct] --
|
||||
|
||||
*/
|
||||
|
||||
if (is_array($_POST)) {
|
||||
|
||||
$username = '';
|
||||
$password = '';
|
||||
$dataBase = '';
|
||||
$table = '';
|
||||
|
||||
mysql_connect("localhost",$username,$password);
|
||||
mysql_select_db($dataBase);
|
||||
|
||||
require("../../dojo/tests/resources/JSON.php");
|
||||
$json = new Services_JSON();
|
||||
|
||||
// see "escape()" call in benchTest.html
|
||||
$string = $json->decode(urldecode($_POST['key']));
|
||||
// $string = $json->decode($_POST['key']);
|
||||
|
||||
print "<h1>Thank YOU!</h1>";
|
||||
print "
|
||||
<p>Your results have been added to our database. No
|
||||
personal information outside of what you see here
|
||||
has been stored.
|
||||
</p>
|
||||
|
||||
<p>You can <a href= \"javascript:history.back()\">go back</a>
|
||||
and run more tests, or even better, load up another browser
|
||||
and the submit your tests again!
|
||||
</p>
|
||||
|
||||
<p>again ... thanks for your time.</p>
|
||||
|
||||
";
|
||||
|
||||
print "<h3>Results Submitted:</h3>";
|
||||
print "<pre style=\"font:6pt Terminal,sans-serif; border:1px solid #cecece; background-color:#ededed; padding:20px; \">";
|
||||
|
||||
$ua = $string->clientNavigator;
|
||||
$dojov = $string->dojoVersion;
|
||||
|
||||
print "Client: ".$ua."\n";
|
||||
print "Dojo v".$dojov."\n";
|
||||
|
||||
if (is_array($string->dataSet)) {
|
||||
print "\nTest Results:";
|
||||
// should client serialize a key, or is this safer?
|
||||
$dataSet = md5(serialize($string));
|
||||
foreach ($string->dataSet as $test) {
|
||||
$data = array(
|
||||
'dataSet' => $dataSet,
|
||||
'useragent' => $ua,
|
||||
'dojover' => $dojov,
|
||||
'testNum' => $test->testNum,
|
||||
'testMethod' => $test->testMethod,
|
||||
'testTime' => $test->testTime,
|
||||
'testAverage' => $test->testAverage,
|
||||
'testCount' => $test->testCount,
|
||||
'dijit' => $test->dijit
|
||||
);
|
||||
print_r($data);
|
||||
add_rec($table,$data);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($string->errors)) {
|
||||
// not saving errors at this point
|
||||
print "\nErrors:";
|
||||
foreach ($string->errors as $error) {
|
||||
print_r($error);
|
||||
}
|
||||
}
|
||||
print "</pre>";
|
||||
}
|
||||
|
||||
function add_rec($table, $data) {
|
||||
|
||||
if (!is_array($data)) { return FALSE; }
|
||||
|
||||
$keys = array_keys($data);
|
||||
$values = array_values($data);
|
||||
$field=0;
|
||||
|
||||
for ($field;$field<sizeof($data);$field++) {
|
||||
if (!ereg("^[0-9].*$",$keys[$field])) {
|
||||
$sqlfields = $sqlfields.$keys[$field]."=\"".$values[$field]."\", ";
|
||||
}
|
||||
}
|
||||
$sqlfields = (substr($sqlfields,0,(strlen($sqlfields)-2)));
|
||||
|
||||
if ($query = mysql_query("insert into $table set $sqlfields")) {
|
||||
$id = mysql_insert_id();
|
||||
return ($id); } else { return FALSE; }
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
189
spring-faces/src/main/java/META-INF/dijit/bench/benchTool.html
Normal file
189
spring-faces/src/main/java/META-INF/dijit/bench/benchTool.html
Normal file
@@ -0,0 +1,189 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Dojo interactive benchmark tool</title>
|
||||
<script type="text/javascript" src="../../dojo/dojo.js"></script>
|
||||
<script type="text/javascript">
|
||||
// FIXME:
|
||||
// the url below points to dojo.inpdx.net/benchResults.php
|
||||
// need to setup DB on dtk.org and change URL here to store
|
||||
// results elsewhere ... work db structure in accompanying
|
||||
// .php file
|
||||
// basic stats are located at http://dojo.inpdx.net/benchmarks.html
|
||||
|
||||
dojo.require("dojo.fx");
|
||||
// FIXME: this seems an excessive fix for IE6 issue ...
|
||||
dojo.require("dijit.dijit");
|
||||
// dojo.require("dijit.form.Button");
|
||||
dojo.require("dijit.dijit-all");
|
||||
dojo.require("dojo.parser");
|
||||
|
||||
|
||||
// setup global variables
|
||||
var masterResults = { clientNavigator: navigator.userAgent, dataSet: [], errors: [] }
|
||||
var isRunning = false;
|
||||
var theCount, theClass, runner = null;
|
||||
var testCount = 0;
|
||||
dojo.addOnLoad(function(){
|
||||
theCount = dojo.byId('countNode');
|
||||
theClass = dojo.byId('classNode');
|
||||
runner = dojo.byId('runner');
|
||||
masterResults.dojoVersion = dojo.version.toString();
|
||||
});
|
||||
|
||||
|
||||
function _toggleRunMsg(){
|
||||
var newMsg = (isRunning) ? " Run Test " : " Running ..."
|
||||
dojo.fx.chain([
|
||||
dojo.fadeOut({
|
||||
node:runner,
|
||||
duration:200,
|
||||
onEnd: function(){
|
||||
runner.innerHTML = newMsg;
|
||||
isRunning=!isRunning;
|
||||
}
|
||||
}),
|
||||
dojo.fadeIn({ node:runner, duration: 200 })
|
||||
]).play();
|
||||
}
|
||||
|
||||
function runTest(){
|
||||
if(isRunning){ return; }
|
||||
_toggleRunMsg();
|
||||
setTimeout("_runRealTest()",1000);
|
||||
}
|
||||
|
||||
function _runRealTest(){
|
||||
|
||||
var _error = false;
|
||||
var count = theCount.value;
|
||||
var aclass = theClass.value.toString();
|
||||
var theMethod = (dojo.byId('parse').checked) ? "parse" : "create";
|
||||
|
||||
var tmpNode = document.createElement('div');
|
||||
|
||||
switch(theMethod){
|
||||
case "parse" :
|
||||
var tmpString = [];
|
||||
for(var i=0; i<count; i++){
|
||||
tmpString.push('<div dojoType="', aclass, '"></div>');
|
||||
}
|
||||
tmpNode.innerHTML = tmpString.join("");
|
||||
var tmpTimer = new Date().getTime();
|
||||
dojo.parser.parse(tmpNode);
|
||||
var endTime = new Date().getTime() - tmpTimer;
|
||||
break;
|
||||
case "create" :
|
||||
var construction = dojo.getObject(aclass);
|
||||
var tmpTimer = new Date().getTime();
|
||||
for(var i=0; i<count; i++){
|
||||
var tmp = new construction({});
|
||||
tmpNode.appendChild(tmp.domNode);
|
||||
}
|
||||
var endTime = new Date().getTime() - tmpTimer;
|
||||
break;
|
||||
}
|
||||
|
||||
var average = (endTime / count);
|
||||
var msg = "It took: "+endTime+"ms to "+theMethod+" "+count+" "+aclass+" widgets"+
|
||||
"<br>(average: "+average+" ms/widget)<br><br>";
|
||||
|
||||
masterResults.dataSet.push({
|
||||
testNum: ++testCount,
|
||||
dijit: aclass,
|
||||
testCount: count,
|
||||
testAverage: average,
|
||||
testMethod: theMethod,
|
||||
testTime: endTime
|
||||
});
|
||||
|
||||
dojo.byId("results").innerHTML += msg;
|
||||
setTimeout("_toggleRunMsg()",250);
|
||||
|
||||
// Nodes have to be in the document for IE7 to GC them.
|
||||
// Do this after generating the widgets to dispel
|
||||
// notion that widget parents have to be in document
|
||||
// a-priori.
|
||||
dojo.byId("limbo").appendChild(tmpNode);
|
||||
}
|
||||
|
||||
function doDebug(){
|
||||
var key = escape(dojo.toJson(masterResults));
|
||||
dojo.byId('hiddenHolder').value = key;
|
||||
return true;
|
||||
}
|
||||
|
||||
</script>
|
||||
<style>
|
||||
@import "../../dijit/themes/tundra/tundra.css";
|
||||
@import "../../dijit/themes/dijit.css";
|
||||
@import "../../dojo/resources/dojo.css";
|
||||
@import "../../dijit/tests/css/dijitTests.css";
|
||||
|
||||
#limbo {
|
||||
display: none;
|
||||
}
|
||||
#theContainer {
|
||||
float:left;
|
||||
display: block; padding:12px; padding-top:0;
|
||||
width:420px; margin-left:20px;
|
||||
background-color:#fff; -moz-border-radius:8pt 8pt;
|
||||
border:2px solid #ededed;
|
||||
}
|
||||
#leftControl { float:left; width:300px; }
|
||||
#testControl, #submitControl { border:2px solid #ededed; padding:12px; -moz-border-radius:8pt 8pt; background-color:#fff; }
|
||||
#results { overflow:auto; height:300px; border:1px solid #ccc; color:darkred; padding:8px; }
|
||||
#results li { list-style-type: none; }
|
||||
#results ul { margin:0; padding:0; }
|
||||
.runHolder, .submitButton {
|
||||
border:1px solid #ccc; padding:3px; -moz-border-radius:8pt 8pt; text-align:center;
|
||||
cursor:pointer; background-color:#ededed; display:block; width:125px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body class="tundra">
|
||||
<div id="limbo"></div>
|
||||
<h1 class="testTitle">Dojo Benchmark Tool</h1>
|
||||
|
||||
<div id="leftControl">
|
||||
<div id="testControl">
|
||||
|
||||
Class: <input type="text" name="dijit" id="classNode" value="dijit.form.Button"><br><br>
|
||||
Count: <input type="text" name="count" id="countNode" value="100" size="4" ><br><br>
|
||||
|
||||
Method: <label for="parse">
|
||||
<input type="radio" name="theMethod" value="parse" id="parse" checked="on"> Parse
|
||||
</label>
|
||||
<label for="create">
|
||||
<input type="radio" name="theMethod" value="create" id="create"> Create
|
||||
</label>
|
||||
|
||||
<br><br>
|
||||
<span onclick="runTest()" class="runHolder"><span id="runner"> Run Test </span></span>
|
||||
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div id="submitControl">
|
||||
<p>
|
||||
* The results of these tests are important to us. Please feel free to submit your dataSet
|
||||
to Dojotoolkit.org. Your privacy will be respected.
|
||||
|
||||
</p>
|
||||
<div id="hiddenResults">
|
||||
<form id="resultForm" action="http://dojo.inpdx.net/benchResults.php"
|
||||
method="POST" onsubmit="doDebug()">
|
||||
<input type="hidden" id="hiddenHolder" value="" name="key">
|
||||
<input type="submit" value=" Submit Data " class="submitButton">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="theContainer"><h3>Results:</h3><div id="results"></div></div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>PROGRAMMATIC - Dojo Widget Creation Test</title>
|
||||
<script type="text/javascript" src="../../dojo/dojo.js"></script>
|
||||
<script type="text/javascript" src="../dijit.js"></script>
|
||||
<script type="text/javascript">
|
||||
var queryCount = location.search.match(/count=(\d*)/);
|
||||
var count = (queryCount ? parseInt(queryCount[1]) : 100);
|
||||
var queryClass = location.search.match(/class=([a-zA-z.]*)/);
|
||||
var className = (queryClass ? queryClass[1] : "form.Button");
|
||||
|
||||
dojo.require("dijit." + className);
|
||||
dojo.require("dojo.parser");
|
||||
logMessage = window.alert;
|
||||
</script>
|
||||
<style type="text/css">
|
||||
@import "../themes/tundra/tundra.css";
|
||||
/* group multiple buttons in a row */
|
||||
.box {
|
||||
display: block;
|
||||
text-align: center;
|
||||
}
|
||||
.box .dojoButton {
|
||||
width: 80px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.dojoButtonContents {
|
||||
font-size: 1.6em;
|
||||
}
|
||||
|
||||
#buttonContainer {
|
||||
border: 1px solid black;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#results {
|
||||
color: darkred;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class=tundra>
|
||||
<script language='javascript'>
|
||||
document.write("<h2>Currently Creating "+count+" "+className+" instances</h2>");
|
||||
</script>
|
||||
Pass <code>?count=<i><b>100</b></i></code> in the query string to change the number of widgets.<br>
|
||||
Pass <code>?class=<i><b>form.Button</b></i></code> in the query string to change the widget class.
|
||||
<h3 id="results"></h3>
|
||||
|
||||
<div id="buttonContainer" class='box'></div>
|
||||
<br>
|
||||
<script type="text/javascript">
|
||||
// See if we can make a widget in script and attach it to the DOM ourselves.
|
||||
var constructor = dojo.getObject("dijit."+className);
|
||||
function makeEm(){
|
||||
var container = dojo.byId("buttonContainer");
|
||||
var t0 = new Date().getTime();
|
||||
for (var i = 1; i <= count; i++) {
|
||||
var it =
|
||||
new constructor(
|
||||
{label:"Button "+i, onclick:'logMessage("clicked simple")'}
|
||||
);
|
||||
container.appendChild(it.domNode);
|
||||
it.domNode.style.display = '';
|
||||
}
|
||||
var t1 = new Date().getTime();
|
||||
dojo.byId("results").innerHTML = "It took " + (t1 - t0) + " msec to create " + count + " "+className+" instances programmatically.";
|
||||
}
|
||||
dojo.addOnLoad(makeEm);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,75 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>PROGRAMMATIC - Dojo Button 100 Test</title>
|
||||
<script type="text/javascript" src="../../dojo/dojo.js" XdjConfig='isDebug: true, debugAtAllCosts: true'></script>
|
||||
<script type="text/javascript">
|
||||
dojo.require("dijit.form.Button");
|
||||
dojo.require("dojo.parser");
|
||||
logMessage = window.alert;
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
@import "../themes/tundra/tundra.css";
|
||||
|
||||
/* group multiple buttons in a row */
|
||||
.box {
|
||||
display: block;
|
||||
text-align: center;
|
||||
}
|
||||
.box .dojoButton {
|
||||
width:80px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.dojoButtonContents {
|
||||
font-size: 1.6em;
|
||||
}
|
||||
|
||||
#buttonContainer {
|
||||
border:1px solid black;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
#results {
|
||||
color:darkred;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body class=tundra>
|
||||
<h2>Creating dojot.form.buttons programmatically</h2>
|
||||
<h3 id="results"></h3>
|
||||
|
||||
<div id="buttonContainer" class='box'></div>
|
||||
|
||||
<br>
|
||||
Pass "?count=<i><b>n</b></i>" in the query string to change the number of buttons.
|
||||
|
||||
<script type="text/javascript">
|
||||
// See if we can make a widget in script and attach it to the DOM ourselves.
|
||||
|
||||
function makeEm() {
|
||||
var queryCount = location.search.match(/count=(\d*)/);
|
||||
var count = (queryCount ? parseInt(queryCount[1]) : 100);
|
||||
var container = dojo.byId("buttonContainer");
|
||||
var t0 = new Date().getTime();
|
||||
for (var i = 1; i <= count; i++) {
|
||||
var it =
|
||||
new dijit.form.Button(
|
||||
{label:"Button "+i, onclick:'logMessage("clicked simple")'}
|
||||
);
|
||||
container.appendChild(it.domNode);
|
||||
it.domNode.style.display = '';
|
||||
}
|
||||
var t1 = new Date().getTime();
|
||||
dojo.byId("results").innerHTML = "It took " + (t1 - t0) + " msec to create " + count + " Buttons programmatically.";
|
||||
}
|
||||
dojo.addOnLoad(makeEm);
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,68 @@
|
||||
<html>
|
||||
<style>
|
||||
th { vertical-align:bottom; }
|
||||
td {
|
||||
padding:10px;
|
||||
text-align:right;
|
||||
}
|
||||
.computer { vertical-align:top; }
|
||||
</style>
|
||||
<body>
|
||||
<h3>Widget instantiation timing test results</h3>
|
||||
|
||||
<table>
|
||||
|
||||
<tr><th rowspan=2>Computer/OS</th><th rowspan=2>Browser</th><th colspan=3>Parsing</th><th colspan=3>Programmatic</th></tr>
|
||||
<tr> <th>100</th><th>500</th><th>1000</th><th>100</th><th>500</th><th>1000</th></tr>
|
||||
<tr><td class='computer' rowspan=3>MacBook Pro 2.16<br> OS 10.4 2GB RAM</td>
|
||||
<td>FF (2.0.0.3)</td>
|
||||
<td>303</td><td>1724</td><td>3505</td>
|
||||
<td>195</td><td>1006</td><td>2266</td>
|
||||
</tr>
|
||||
<tr><td>Safari (2.04)</td>
|
||||
<td>192</td><td>1460</td><td>4463</td>
|
||||
<td>142</td><td>895</td><td>2403</td>
|
||||
</tr>
|
||||
<tr><td>WebKit Nightly (21223)</td>
|
||||
<td>110</td><td>540</td><td>1096</td>
|
||||
<td>85</td><td>458</td><td>940</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr><td class='computer' rowspan=2>Dell Precision 2.13 PPro<br> XP SP 2 - 2GB RAM</td>
|
||||
<td>FF (2.0.0.3)</td>
|
||||
<td>282</td><td>1266</td><td>2484</td>
|
||||
<td>250</td><td>890</td><td>1766</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>IE7 (7.0.5730.11)</td>
|
||||
<td>303</td><td>2079</td><td>5172</td>
|
||||
<td>203</td><td>1140</td><td>2422</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><!--browser--></td>
|
||||
<td><!--100 parse--></td><td><!--500 parse--></td><td><!--1000 parse--></td>
|
||||
<td><!--100 code--></td><td><!--500 code--></td><td><!--1000 code--></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
<H3>If you want to play:</H3>
|
||||
<p>
|
||||
<ol>
|
||||
<li> Run the following tests:
|
||||
<ul>
|
||||
<li><a href='http://dojotoolkit.org/~owen/bench/dojo/dijit/bench/test_Button-parse.php?count=100'>http://dojotoolkit.org/~owen/bench/dojo/dijit/bench/test_Button-parse.php?count=100</a></li>
|
||||
<li><a href='http://dojotoolkit.org/~owen/bench/dojo/dijit/bench/test_Button-programmatic.html?count=100'>http://dojotoolkit.org/~owen/bench/dojo/dijit/bench/test_Button-programmatic.html?count=100</a></li>
|
||||
</ul>
|
||||
<br>
|
||||
Change the "count=" to 100, 500, 1000 for each.
|
||||
<br><br>
|
||||
Restart the browser between each test/count. Run each test 3 times and record the smallest number.
|
||||
</li>
|
||||
<li>Record your tests in the copy of this file in SVN: <code>dijit/bench/test_Button-results.html</code> and check it in. Reference ticket #2968.
|
||||
</ol>
|
||||
</p>
|
||||
|
||||
</body>
|
||||
@@ -0,0 +1,186 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>test of various synchronous page searching methods</title>
|
||||
<style type="text/css">
|
||||
@import "../../dojo/resources/dojo.css";
|
||||
@import "../themes/tundra/tundra.css";
|
||||
</style>
|
||||
<script type="text/javascript" src="../../dojo/dojo.js"
|
||||
djConfig="parseOnLoad: true, isDebug: true"></script>
|
||||
<script type="text/javascript">
|
||||
dojo.require("dojo.parser"); // scan page for widgets and instantiate them
|
||||
dojo.require("dijit._Widget");
|
||||
dojo.require("dijit._Templated");
|
||||
|
||||
/* dummy widget for benchmarking purposes */
|
||||
dojo.declare(
|
||||
"SimpleButton",
|
||||
[ dijit._Widget, dijit._Templated ],
|
||||
function(){ },
|
||||
{
|
||||
label: "",
|
||||
|
||||
templateString: "<button dojoAttachEvent='onclick:onClick'>${label}</button>",
|
||||
|
||||
onClick: function(){
|
||||
this.domNode.style.backgroundColor="green";
|
||||
},
|
||||
postCreate: function(){
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 style="font-size: 40px; line-height: 50px;">This page contains a huge number of nodes, most of which are "chaff".</h1>
|
||||
<h3>Here's the relative timings for this page</h3>
|
||||
<div id="profileOutputTable"></div>
|
||||
<!--
|
||||
<h3>And some comparison data</h3>
|
||||
<table border=1>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>IE
|
||||
<th>Safari
|
||||
<th>Gecko (on PC)
|
||||
<th>Gecko (on intel mac)
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>4890
|
||||
<td>3242
|
||||
<td>3094
|
||||
<td>3782
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
-->
|
||||
|
||||
|
||||
<?
|
||||
$containerDepth = 30;
|
||||
$leadingChaff = 100;
|
||||
$trailingChaff = 100;
|
||||
$items = 100;
|
||||
?>
|
||||
<?
|
||||
function generateChaff($iters){
|
||||
for($i=0;$i<$iters;$i++){ ?>
|
||||
<pre class="highlighted"><code><span class="hl-reserved">var </span><span class="hl-identifier">dlg</span><span class="hl-default"> = </span><span class="hl-reserved">new </span><span class="hl-identifier">blah</span><span class="hl-default">.</span><span class="hl-identifier">ext</span><span class="hl-default">.</span><span class="hl-identifier">LayoutDialog</span><span class="hl-brackets">(</span><span class="hl-identifier">config</span><span class="hl-code">.</span><span class="hl-identifier">id</span><span class="hl-code"> || </span><span class="hl-identifier">blah</span><span class="hl-code">.</span><span class="hl-identifier">util</span><span class="hl-code">.</span><span class="hl-identifier">Dom</span><span class="hl-code">.</span><span class="hl-identifier">generateId</span><span class="hl-brackets">()</span><span class="hl-code">, </span><span class="hl-brackets">{
|
||||
</span><span title="autoCreate" class="hl-identifier">autoCreate</span><span class="hl-code"> : </span><span class="hl-reserved">true</span><span class="hl-code">,
|
||||
</span><span title="minWidth" class="hl-identifier">minWidth</span><span class="hl-code">:</span><span class="hl-number">400</span><span class="hl-code">,
|
||||
</span><span title="minHeight" class="hl-identifier">minHeight</span><span class="hl-code">:</span><span class="hl-number">300</span><span class="hl-code">,
|
||||
</span>
|
||||
<span title="syncHeightBeforeShow" class="hl-identifier">syncHeightBeforeShow</span><span class="hl-code">: </span><span class="hl-reserved">true</span><span class="hl-code">,
|
||||
</span><span title="shadow" class="hl-identifier">shadow</span><span class="hl-code">:</span><span class="hl-reserved">true</span><span class="hl-code">,
|
||||
</span><span title="fixedcenter" class="hl-identifier">fixedcenter</span><span class="hl-code">: </span><span class="hl-reserved">true</span><span class="hl-code">,
|
||||
</span><span title="center" class="hl-identifier">center</span><span class="hl-code">:</span><span class="hl-brackets">{</span><span class="hl-identifier">autoScroll</span><span class="hl-code">:</span><span class="hl-reserved">false</span><span class="hl-brackets">}</span><span class="hl-code">,
|
||||
</span><span title="east" class="hl-identifier">east</span><span class="hl-code">:</span><span class="hl-brackets">{</span><span class="hl-identifier">split</span><span class="hl-code">:</span><span class="hl-reserved">true</span><span class="hl-code">,</span><span class="hl-identifier">initialSize</span><span class="hl-code">:</span><span class="hl-number">150</span><span class="hl-code">,</span><span class="hl-identifier">minSize</span><span class="hl-code">:</span><span class="hl-number">150</span><span class="hl-code">,</span><span class="hl-identifier">maxSize</span><span class="hl-code">:</span><span class="hl-number">250</span><span class="hl-brackets">}
|
||||
})</span><span class="hl-default">;
|
||||
</span><span class="hl-identifier">dlg</span><span class="hl-default">.</span><span class="hl-identifier">setTitle</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">Choose an Image</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-default">;
|
||||
</span><span class="hl-identifier">dlg</span><span class="hl-default">.</span><span class="hl-identifier">getEl</span><span class="hl-brackets">()</span><span class="hl-default">.</span><span class="hl-identifier">addClass</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">ychooser-dlg</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-default">;</span></code></pre><br />
|
||||
<pre class="highlighted"><code><span class="hl-reserved">var </span><span class="hl-identifier">animated</span><span class="hl-default"> = </span><span class="hl-reserved">new </span><span class="hl-identifier">blah</span><span class="hl-default">.</span><span class="hl-identifier">ext</span><span class="hl-default">.</span><span class="hl-identifier">Resizable</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">animated</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-brackets">{
|
||||
</span><span title="east" class="hl-identifier">width</span><span class="hl-code">: </span><span class="hl-number">200</span><span class="hl-code">,
|
||||
</span><span title="east" class="hl-identifier">height</span><span class="hl-code">: </span><span class="hl-number">100</span><span class="hl-code">,
|
||||
</span><span title="east" class="hl-identifier">minWidth</span><span class="hl-code">:</span><span class="hl-number">100</span><span class="hl-code">,
|
||||
</span><span class="hl-identifier">minHeight</span><span class="hl-code">:</span><span class="hl-number">50</span><span class="hl-code">,
|
||||
</span><span class="hl-identifier">animate</span><span class="hl-code">:</span><span class="hl-reserved">true</span><span class="hl-code">,
|
||||
</span><span class="hl-identifier">easing</span><span class="hl-code">: </span><span class="hl-identifier">YAHOO</span><span class="hl-code">.</span><span class="hl-identifier">util</span><span class="hl-code">.</span><span class="hl-identifier">Easing</span><span class="hl-code">.</span><span class="hl-identifier">backIn</span><span class="hl-code">,
|
||||
</span><span class="hl-identifier">duration</span><span class="hl-code">:</span><span class="hl-number">.6
|
||||
</span><span class="hl-brackets">})</span><span class="hl-default">;</span></code></pre>
|
||||
<h4>The standard Lorem Ipsum passage, used since the 1500s</h4>
|
||||
<p>
|
||||
"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
|
||||
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
|
||||
ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
|
||||
aliquip ex ea commodo consequat. Duis aute irure dolor in
|
||||
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
|
||||
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
|
||||
culpa qui officia deserunt mollit anim id est laborum."
|
||||
</p>
|
||||
|
||||
<h4>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</h4>
|
||||
|
||||
<p>
|
||||
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem
|
||||
accusantium doloremque laudantium, totam rem aperiam, eaque ipsa
|
||||
quae ab illo inventore veritatis et quasi architecto beatae vitae
|
||||
dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit
|
||||
aspernatur aut odit aut fugit, sed quia consequuntur magni dolores
|
||||
eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam
|
||||
est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci
|
||||
velit, sed quia non numquam eius modi tempora incidunt ut labore et
|
||||
dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam,
|
||||
quis nostrum exercitationem ullam corporis suscipit laboriosam,
|
||||
nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure
|
||||
reprehenderit qui in ea voluptate velit esse quam nihil molestiae
|
||||
consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla
|
||||
pariatur?"
|
||||
</p>
|
||||
|
||||
<h4>1914 translation by H. Rackham</h4>
|
||||
|
||||
<p>
|
||||
"But I must explain to you how all this mistaken idea of denouncing
|
||||
pleasure and praising pain was born and I will give you a complete
|
||||
account of the system, and expound the actual teachings of the
|
||||
great explorer of the truth, the master-builder of human happiness.
|
||||
No one rejects, dislikes, or avoids pleasure itself, because it is
|
||||
pleasure, but because those who do not know how to pursue pleasure
|
||||
rationally encounter consequences that are extremely painful. Nor
|
||||
again is there anyone who loves or pursues or desires to obtain
|
||||
pain of itself, because it is pain, but because occasionally
|
||||
circumstances occur in which toil and pain can procure him some
|
||||
great pleasure. To take a trivial example, which of us ever
|
||||
undertakes laborious physical exercise, except to obtain some
|
||||
advantage from it? But who has any right to find fault with a man
|
||||
who chooses to enjoy a pleasure that has no annoying consequences,
|
||||
or one who avoids a pain that produces no resultant pleasure?"
|
||||
</p>
|
||||
<? }
|
||||
} // end generateChaff
|
||||
$widgetName = "SimpleButton";
|
||||
?>
|
||||
<? generateChaff($leadingChaff); ?>
|
||||
<hr>
|
||||
<? for($i=0;$i<$containerDepth;$i++){ ?>
|
||||
<table border="1" cellpadding="0" cellspacing="0" width="100%">
|
||||
<!--
|
||||
<table>
|
||||
-->
|
||||
<tr>
|
||||
<td>
|
||||
<br>
|
||||
chaff!
|
||||
<br>
|
||||
<? } ?>
|
||||
<? for($i=0;$i<$items;$i++){ ?>
|
||||
<div dojoType="<?= $widgetName ?>" label="item2 <?= $i ?>">item2 <?= $i ?></div>
|
||||
<? } ?>
|
||||
<? for($i=0;$i<$containerDepth;$i++){ ?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<? } ?>
|
||||
<? generateChaff($trailingChaff); ?>
|
||||
<? for($i=0;$i<$items;$i++){ ?>
|
||||
<div dojoType="<?= $widgetName ?>" label="item2 <?= $i ?>"><span>item <?= $i ?></span></div>
|
||||
<? } ?>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
oldTime = new Date();
|
||||
dojo.addOnLoad(function(){
|
||||
var time = new Date().getTime() - oldTime;
|
||||
var p = document.createElement("p");
|
||||
alert("Widgets loaded in " + time + "ms");
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
90
spring-faces/src/main/java/META-INF/dijit/changes.txt
Normal file
90
spring-faces/src/main/java/META-INF/dijit/changes.txt
Normal file
@@ -0,0 +1,90 @@
|
||||
Changes from Dojo 0.4 dojo.widgets to new dijit project
|
||||
=======================================================
|
||||
|
||||
The widgets and widget infrastructure have been separated into separate project,
|
||||
vastly streamlined and with a new directory structure. There are many other changes.
|
||||
|
||||
Markup
|
||||
------
|
||||
|
||||
dojoType="button" replaced by dojoType="dijit.Button" Must use fully qualified class name,
|
||||
and it's case-sensitive.
|
||||
|
||||
Need to manually dojo.require("dojo.parser") to get parsing
|
||||
|
||||
Widget namespaces and widget auto-loading are desupported.
|
||||
|
||||
onClick="foo" now overrides (ie, replaces) the default onClick() function rather than attaching to it,
|
||||
so widget designers should make empty onClick() functions (when appropriate).
|
||||
|
||||
Programmatic creation
|
||||
---------------------
|
||||
Create widgets via
|
||||
|
||||
new dijit.Button(params, srcNodeRef)
|
||||
|
||||
createWidget() call removed since multiple renderers are no longer supported (see next section).
|
||||
|
||||
At least for the dijit widgets, all widgets are guaranteed to work programatically, which in
|
||||
effect means that all widgets must have templates, unless the default <div> works.
|
||||
|
||||
Renderers
|
||||
---------
|
||||
Removed support for multiple renderers (svg & vml & a11y) for a single widget.
|
||||
If a widget wants to render differently on different platforms, there must be
|
||||
branching code inside the widget, or it needs to call a library that branches
|
||||
based on the browser type (like dojo.gfx or dojo.charting).
|
||||
|
||||
|
||||
Templates
|
||||
---------
|
||||
"this." is no longer used within ${} substitution notation. See ticket #2905.
|
||||
dojoRoot,buildScriptBase,dojoModuleUrl are no longer supported, but
|
||||
any JavaScript properties on the widget's 'this' may be referenced with dotted notation.
|
||||
The attributes dojoOn* are desupported (including dojoOnBuild);
|
||||
also can't use id attribute to affect a dojoAttachPoint.
|
||||
|
||||
dojoAttachEvent is case sensitive, so capitalization matters. You will probably have
|
||||
to change
|
||||
|
||||
dojoAttachEvent="onClick"
|
||||
|
||||
to
|
||||
|
||||
dojoAttachEvent="onclick: onClick"
|
||||
|
||||
(given that the event name is lowercase, and assuming that the method name is camel case)
|
||||
|
||||
lists within dojoAttachPoint, dojoAttachEvent, waiRole, and waiState are now comma-separated
|
||||
(not separated by semi-colons)
|
||||
|
||||
Parent/Child relationships
|
||||
--------------------------
|
||||
By default widgets exist as islands, not knowing about their parent widget or children widgets.
|
||||
The exception is the destroy() function which will also delete all descendant widgets.
|
||||
Some widgets like Tree and SplitContainer will know about their children, but those widgets
|
||||
will use the special mixins in Container.js / Layout.js.
|
||||
|
||||
Widget.js base class
|
||||
--------------------
|
||||
|
||||
- Widget.js, Domwidget.js, HtmlWidget.js combined into dijit.base.Widget, with TemplatedWidget mixin
|
||||
for widgets with templates
|
||||
|
||||
- on widget creation, postMixInProperties(), buildRendering() and postCreate() is called.
|
||||
fillInTemplate() is no longer called. In addition, those functions call signatures have changed.
|
||||
No arguments are passed. To get the source dom Node, just reference this.srcDomNode.
|
||||
When postCreate() is called the widget children don't yet exist.
|
||||
|
||||
- The TemplatedWidget mixin defines buildRendering(). widgetsInTemplate not ported yet.
|
||||
|
||||
- onResized() removed
|
||||
|
||||
- the whole parent/child relationship thing is gone
|
||||
|
||||
- extraArgs[] is gone
|
||||
|
||||
- postCreate() called but child widgets don't exist yet
|
||||
|
||||
- templateCssPath ignored. User must manually include tundra.css file
|
||||
|
||||
20
spring-faces/src/main/java/META-INF/dijit/dijit-all.js
Normal file
20
spring-faces/src/main/java/META-INF/dijit/dijit-all.js
Normal file
File diff suppressed because one or more lines are too long
14087
spring-faces/src/main/java/META-INF/dijit/dijit-all.js.uncompressed.js
Normal file
14087
spring-faces/src/main/java/META-INF/dijit/dijit-all.js.uncompressed.js
Normal file
File diff suppressed because it is too large
Load Diff
20
spring-faces/src/main/java/META-INF/dijit/dijit.js
Normal file
20
spring-faces/src/main/java/META-INF/dijit/dijit.js
Normal file
File diff suppressed because one or more lines are too long
2950
spring-faces/src/main/java/META-INF/dijit/dijit.js.uncompressed.js
Normal file
2950
spring-faces/src/main/java/META-INF/dijit/dijit.js.uncompressed.js
Normal file
File diff suppressed because it is too large
Load Diff
273
spring-faces/src/main/java/META-INF/dijit/form/Button.js
Normal file
273
spring-faces/src/main/java/META-INF/dijit/form/Button.js
Normal file
@@ -0,0 +1,273 @@
|
||||
if(!dojo._hasResource["dijit.form.Button"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.form.Button"] = true;
|
||||
dojo.provide("dijit.form.Button");
|
||||
|
||||
dojo.require("dijit.form._FormWidget");
|
||||
dojo.require("dijit._Container");
|
||||
|
||||
dojo.declare("dijit.form.Button", dijit.form._FormWidget, {
|
||||
/*
|
||||
* usage
|
||||
* <button dojoType="button" onClick="...">Hello world</button>
|
||||
*
|
||||
* var button1 = new dijit.form.Button({label: "hello world", onClick: foo});
|
||||
* dojo.body().appendChild(button1.domNode);
|
||||
*/
|
||||
// summary
|
||||
// Basically the same thing as a normal HTML button, but with special styling.
|
||||
|
||||
// label: String
|
||||
// text to display in button
|
||||
label: "",
|
||||
|
||||
// showLabel: Boolean
|
||||
// whether or not to display the text label in button
|
||||
showLabel: true,
|
||||
|
||||
// iconClass: String
|
||||
// class to apply to div in button to make it display an icon
|
||||
iconClass: "",
|
||||
|
||||
type: "button",
|
||||
baseClass: "dijitButton",
|
||||
templateString:"<div class=\"dijit dijitLeft dijitInline dijitButton\" baseClass=\"${baseClass}\"\n\tdojoAttachEvent=\"onclick:_onButtonClick,onmouseover:_onMouse,onmouseout:_onMouse,onmousedown:_onMouse\"\n\t><div class='dijitRight'\n\t><button class=\"dijitStretch dijitButtonNode dijitButtonContents\" dojoAttachPoint=\"focusNode,titleNode\"\n\t\ttabIndex=\"${tabIndex}\" type=\"${type}\" id=\"${id}\" name=\"${name}\" waiRole=\"button\" waiState=\"labelledby-${id}_label\"\n\t\t><div class=\"dijitInline ${iconClass}\"></div\n\t\t><span class=\"dijitButtonText\" id=\"${id}_label\" dojoAttachPoint=\"containerNode\">${label}</span\n\t></button\n></div></div>\n",
|
||||
|
||||
// TODO: set button's title to this.containerNode.innerText
|
||||
|
||||
_onButtonClick: function(/*Event*/ e){
|
||||
// summary: callback when the user mouse clicks the button portion
|
||||
dojo.stopEvent(e);
|
||||
if(this.disabled){ return; }
|
||||
return this.onClick(e);
|
||||
},
|
||||
|
||||
postCreate: function(){
|
||||
// summary:
|
||||
// get label and set as title on button icon if necessary
|
||||
if (this.showLabel == false){
|
||||
var labelText = "";
|
||||
this.label = this.containerNode.innerHTML;
|
||||
labelText = dojo.trim(this.containerNode.innerText || this.containerNode.textContent);
|
||||
// set title attrib on iconNode
|
||||
this.titleNode.title=labelText;
|
||||
dojo.addClass(this.containerNode,"dijitDisplayNone");
|
||||
}
|
||||
dijit.form._FormWidget.prototype.postCreate.apply(this, arguments);
|
||||
},
|
||||
|
||||
onClick: function(/*Event*/ e){
|
||||
// summary: callback for when button is clicked; user can override this function
|
||||
|
||||
// for some reason type=submit buttons don't automatically submit the form; do it manually
|
||||
if(this.type=="submit"){
|
||||
for(var node=this.domNode; node; node=node.parentNode){
|
||||
var widget=dijit.byNode(node);
|
||||
if(widget && widget._onSubmit){
|
||||
widget._onSubmit(e);
|
||||
break;
|
||||
}
|
||||
if(node.tagName.toLowerCase() == "form"){
|
||||
node.submit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
setLabel: function(/*String*/ content){
|
||||
// summary: reset the label (text) of the button; takes an HTML string
|
||||
this.containerNode.innerHTML = this.label = content;
|
||||
if(dojo.isMozilla){ // Firefox has re-render issues with tables
|
||||
var oldDisplay = dojo.getComputedStyle(this.domNode).display;
|
||||
this.domNode.style.display="none";
|
||||
var _this = this;
|
||||
setTimeout(function(){_this.domNode.style.display=oldDisplay;},1);
|
||||
}
|
||||
if (this.showLabel == false){
|
||||
this.titleNode.title=dojo.trim(this.containerNode.innerText || this.containerNode.textContent);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
* usage
|
||||
* <button dojoType="DropDownButton" label="Hello world"><div dojotype=dijit.Menu>...</div></button>
|
||||
*
|
||||
* var button1 = new dijit.form.DropDownButton({ label: "hi", dropDown: new dijit.Menu(...) });
|
||||
* dojo.body().appendChild(button1);
|
||||
*/
|
||||
dojo.declare("dijit.form.DropDownButton", [dijit.form.Button, dijit._Container], {
|
||||
// summary
|
||||
// push the button and a menu shows up
|
||||
|
||||
baseClass : "dijitDropDownButton",
|
||||
|
||||
templateString:"<div class=\"dijit dijitLeft dijitInline dijitDropDownButton\" baseClass=\"dijitDropDownButton\"\n\tdojoAttachEvent=\"onmouseover:_onMouse,onmouseout:_onMouse,onmousedown:_onMouse,onclick:_onArrowClick,onkeypress:_onKey\"\n\t><div class='dijitRight'>\n\t<button tabIndex=\"${tabIndex}\" class=\"dijitStretch dijitButtonNode dijitButtonContents\" type=\"${type}\" id=\"${id}\" name=\"${name}\"\n\t\tdojoAttachPoint=\"focusNode,titleNode\" waiRole=\"button\" waiState=\"haspopup-true,labelledby-${id}_label\"\n\t\t><div class=\"dijitInline ${iconClass}\"></div\n\t\t><span class=\"dijitButtonText\" \tdojoAttachPoint=\"containerNode,popupStateNode\"\n\t\tid=\"${id}_label\">${label}</span\n\t\t><span class='dijitA11yDownArrow'>▼</span>\n\t</button>\n</div></div>\n",
|
||||
|
||||
_fillContent: function(){
|
||||
// my inner HTML contains both the button contents and a drop down widget, like
|
||||
// <DropDownButton> <span>push me</span> <Menu> ... </Menu> </DropDownButton>
|
||||
// The first node is assumed to be the button content. The widget is the popup.
|
||||
if(this.srcNodeRef){ // programatically created buttons might not define srcNodeRef
|
||||
//FIXME: figure out how to filter out the widget and use all remaining nodes as button
|
||||
// content, not just nodes[0]
|
||||
var nodes = dojo.query("*", this.srcNodeRef);
|
||||
dijit.form.DropDownButton.superclass._fillContent.call(this, nodes[0]);
|
||||
|
||||
// save pointer to srcNode so we can grab the drop down widget after it's instantiated
|
||||
this.dropDownContainer = this.srcNodeRef;
|
||||
}
|
||||
},
|
||||
|
||||
startup: function(){
|
||||
// the child widget from srcNodeRef is the dropdown widget. Insert it in the page DOM,
|
||||
// make it invisible, and store a reference to pass to the popup code.
|
||||
if(!this.dropDown){
|
||||
var dropDownNode = dojo.query("[widgetId]", this.dropDownContainer)[0];
|
||||
this.dropDown = dijit.byNode(dropDownNode);
|
||||
delete this.dropDownContainer;
|
||||
}
|
||||
dojo.body().appendChild(this.dropDown.domNode);
|
||||
this.dropDown.domNode.style.display="none";
|
||||
},
|
||||
|
||||
_onArrowClick: function(/*Event*/ e){
|
||||
// summary: callback when the user mouse clicks on menu popup node
|
||||
if(this.disabled){ return; }
|
||||
this._toggleDropDown();
|
||||
},
|
||||
|
||||
_onKey: function(/*Event*/ e){
|
||||
// summary: callback when the user presses a key on menu popup node
|
||||
if(this.disabled){ return; }
|
||||
if(e.keyCode == dojo.keys.DOWN_ARROW){
|
||||
if(!this.dropDown || this.dropDown.domNode.style.display=="none"){
|
||||
dojo.stopEvent(e);
|
||||
return this._toggleDropDown();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_onBlur: function(){
|
||||
// summary: called magically when focus has shifted away from this widget and it's dropdown
|
||||
dijit.popup.closeAll();
|
||||
// don't focus on button. the user has explicitly focused on something else.
|
||||
},
|
||||
|
||||
_toggleDropDown: function(){
|
||||
// summary: toggle the drop-down widget; if it is up, close it, if not, open it
|
||||
if(this.disabled){ return; }
|
||||
dijit.focus(this.popupStateNode);
|
||||
var dropDown = this.dropDown;
|
||||
if(!dropDown){ return false; }
|
||||
if(!dropDown.isShowingNow){
|
||||
// If there's an href, then load that first, so we don't get a flicker
|
||||
if(dropDown.href && !dropDown.isLoaded){
|
||||
var self = this;
|
||||
var handler = dojo.connect(dropDown, "onLoad", function(){
|
||||
dojo.disconnect(handler);
|
||||
self._openDropDown();
|
||||
});
|
||||
dropDown._loadCheck(true);
|
||||
return;
|
||||
}else{
|
||||
this._openDropDown();
|
||||
}
|
||||
}else{
|
||||
dijit.popup.closeAll();
|
||||
this._opened = false;
|
||||
}
|
||||
},
|
||||
|
||||
_openDropDown: function(){
|
||||
var dropDown = this.dropDown;
|
||||
var oldWidth=dropDown.domNode.style.width;
|
||||
var self = this;
|
||||
|
||||
dijit.popup.open({
|
||||
parent: this,
|
||||
popup: dropDown,
|
||||
around: this.domNode,
|
||||
orient: this.isLeftToRight() ? {'BL':'TL', 'BR':'TR', 'TL':'BL', 'TR':'BR'}
|
||||
: {'BR':'TR', 'BL':'TL', 'TR':'BR', 'TL':'BL'},
|
||||
onExecute: function(){
|
||||
dijit.popup.closeAll();
|
||||
self.focus();
|
||||
},
|
||||
onCancel: function(){
|
||||
dijit.popup.closeAll();
|
||||
self.focus();
|
||||
},
|
||||
onClose: function(){
|
||||
dropDown.domNode.style.width = oldWidth;
|
||||
self.popupStateNode.removeAttribute("popupActive");
|
||||
}
|
||||
});
|
||||
if(this.domNode.offsetWidth > dropDown.domNode.offsetWidth){
|
||||
var adjustNode = null;
|
||||
if(!this.isLeftToRight()){
|
||||
adjustNode = dropDown.domNode.parentNode;
|
||||
var oldRight = adjustNode.offsetLeft + adjustNode.offsetWidth;
|
||||
}
|
||||
// make menu at least as wide as the button
|
||||
dojo.marginBox(dropDown.domNode, {w: this.domNode.offsetWidth});
|
||||
if(adjustNode){
|
||||
adjustNode.style.left = oldRight - this.domNode.offsetWidth + "px";
|
||||
}
|
||||
}
|
||||
this.popupStateNode.setAttribute("popupActive", "true");
|
||||
this._opened=true;
|
||||
if(dropDown.focus){
|
||||
dropDown.focus();
|
||||
}
|
||||
// TODO: set this.checked and call setStateClass(), to affect button look while drop down is shown
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
* usage
|
||||
* <button dojoType="ComboButton" onClick="..."><span>Hello world</span><div dojoType=dijit.Menu>...</div></button>
|
||||
*
|
||||
* var button1 = new dijit.form.ComboButton({label: "hello world", onClick: foo, dropDown: "myMenu"});
|
||||
* dojo.body().appendChild(button1.domNode);
|
||||
*/
|
||||
dojo.declare("dijit.form.ComboButton", dijit.form.DropDownButton, {
|
||||
// summary
|
||||
// left side is normal button, right side displays menu
|
||||
templateString:"<table class='dijit dijitReset dijitInline dijitLeft dijitComboButton' baseClass='dijitComboButton'\n\tid=\"${id}\" name=\"${name}\" cellspacing='0' cellpadding='0'\n\tdojoAttachEvent=\"onmouseover:_onMouse,onmouseout:_onMouse,onmousedown:_onMouse\">\n\t<tr>\n\t\t<td\tclass=\"dijitStretch dijitButtonContents dijitButtonNode\"\n\t\t\ttabIndex=\"${tabIndex}\"\n\t\t\tdojoAttachEvent=\"ondijitclick:_onButtonClick\" dojoAttachPoint=\"titleNode\"\n\t\t\twaiRole=\"button\" waiState=\"labelledby-${id}_label\">\n\t\t\t<div class=\"dijitInline ${iconClass}\"></div>\n\t\t\t<span class=\"dijitButtonText\" id=\"${id}_label\" dojoAttachPoint=\"containerNode\">${label}</span>\n\t\t</td>\n\t\t<td class='dijitReset dijitRight dijitButtonNode dijitDownArrowButton'\n\t\t\tdojoAttachPoint=\"popupStateNode,focusNode\"\n\t\t\tdojoAttachEvent=\"onmouseover:_onMouse,onmouseout:_onMouse,onmousedown:_onMouse,ondijitclick:_onArrowClick, onkeypress:_onKey\"\n\t\t\tbaseClass=\"dijitComboButtonDownArrow\"\n\t\t\ttitle=\"${optionsTitle}\"\n\t\t\ttabIndex=\"${tabIndex}\"\n\t\t\twaiRole=\"button\" waiState=\"haspopup-true\"\n\t\t><div waiRole=\"presentation\">▼</div>\n\t</td></tr>\n</table>\n",
|
||||
|
||||
// optionsTitle: String
|
||||
// text that describes the options menu (accessibility)
|
||||
optionsTitle: "",
|
||||
|
||||
baseClass: "dijitComboButton"
|
||||
});
|
||||
|
||||
dojo.declare("dijit.form.ToggleButton", dijit.form.Button, {
|
||||
// summary
|
||||
// A button that can be in two states (checked or not).
|
||||
// Can be base class for things like tabs or checkbox or radio buttons
|
||||
|
||||
baseClass: "dijitToggleButton",
|
||||
|
||||
// checked: Boolean
|
||||
// Corresponds to the native HTML <input> element's attribute.
|
||||
// In markup, specified as "checked='checked'" or just "checked".
|
||||
// True if the button is depressed, or the checkbox is checked,
|
||||
// or the radio button is selected, etc.
|
||||
checked: false,
|
||||
|
||||
onClick: function(/*Event*/ evt){
|
||||
this.setChecked(!this.checked);
|
||||
},
|
||||
|
||||
setChecked: function(/*Boolean*/ checked){
|
||||
// summary
|
||||
// Programatically deselect the button
|
||||
this.checked = checked;
|
||||
this._setStateClass();
|
||||
this.onChange(checked);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
120
spring-faces/src/main/java/META-INF/dijit/form/CheckBox.js
Normal file
120
spring-faces/src/main/java/META-INF/dijit/form/CheckBox.js
Normal file
@@ -0,0 +1,120 @@
|
||||
if(!dojo._hasResource["dijit.form.CheckBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.form.CheckBox"] = true;
|
||||
dojo.provide("dijit.form.CheckBox");
|
||||
|
||||
dojo.require("dijit.form.Button");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.form.CheckBox",
|
||||
dijit.form.ToggleButton,
|
||||
{
|
||||
// summary:
|
||||
// Same as an HTML checkbox, but with fancy styling.
|
||||
//
|
||||
// description:
|
||||
// User interacts with real html inputs.
|
||||
// On onclick (which occurs by mouse click, space-bar, or
|
||||
// using the arrow keys to switch the selected radio button),
|
||||
// we update the state of the checkbox/radio.
|
||||
//
|
||||
// There are two modes:
|
||||
// 1. High contrast mode
|
||||
// 2. Normal mode
|
||||
// In case 1, the regular html inputs are shown and used by the user.
|
||||
// In case 2, the regular html inputs are invisible but still used by
|
||||
// the user. They are turned quasi-invisible and overlay the background-image.
|
||||
|
||||
templateString:"<span class=\"${baseClass}\" baseClass=\"${baseClass}\"\n\t><input\n\t \tid=\"${id}\" tabIndex=\"${tabIndex}\" type=\"${_type}\" name=\"${name}\" value=\"${value}\"\n\t\tclass=\"dijitCheckBoxInput\"\n\t\tdojoAttachPoint=\"inputNode,focusNode\"\n\t \tdojoAttachEvent=\"onmouseover:_onMouse,onmouseout:_onMouse,onclick:onClick\"\n></span>\n",
|
||||
|
||||
baseClass: "dijitCheckBox",
|
||||
|
||||
// Value of "type" attribute for <input>
|
||||
_type: "checkbox",
|
||||
|
||||
// value: Value
|
||||
// equivalent to value field on normal checkbox (if checked, the value is passed as
|
||||
// the value when form is submitted)
|
||||
value: "on",
|
||||
|
||||
postCreate: function(){
|
||||
dojo.setSelectable(this.inputNode, false);
|
||||
this.setChecked(this.checked);
|
||||
dijit.form.ToggleButton.prototype.postCreate.apply(this, arguments);
|
||||
},
|
||||
|
||||
setChecked: function(/*Boolean*/ checked){
|
||||
this.checked = checked;
|
||||
if(dojo.isIE){
|
||||
if(checked){ this.inputNode.setAttribute('checked', 'checked'); }
|
||||
else{ this.inputNode.removeAttribute('checked'); }
|
||||
}else{ this.inputNode.checked = checked; }
|
||||
dijit.form.ToggleButton.prototype.setChecked.apply(this, arguments);
|
||||
},
|
||||
|
||||
setValue: function(/*String*/ value){
|
||||
if(value == null){ value = ""; }
|
||||
this.inputNode.value = value;
|
||||
dijit.form.CheckBox.superclass.setValue.call(this,value);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
dojo.declare(
|
||||
"dijit.form.RadioButton",
|
||||
dijit.form.CheckBox,
|
||||
{
|
||||
// summary:
|
||||
// Same as an HTML radio, but with fancy styling.
|
||||
//
|
||||
// description:
|
||||
// Implementation details
|
||||
//
|
||||
// Specialization:
|
||||
// We keep track of dijit radio groups so that we can update the state
|
||||
// of all the siblings (the "context") in a group based on input
|
||||
// events. We don't rely on browser radio grouping.
|
||||
|
||||
_type: "radio",
|
||||
baseClass: "dijitRadio",
|
||||
|
||||
// This shared object keeps track of all widgets, grouped by name
|
||||
_groups: {},
|
||||
|
||||
postCreate: function(){
|
||||
// add this widget to _groups
|
||||
(this._groups[this.name] = this._groups[this.name] || []).push(this);
|
||||
|
||||
dijit.form.CheckBox.prototype.postCreate.apply(this, arguments);
|
||||
},
|
||||
|
||||
uninitialize: function(){
|
||||
// remove this widget from _groups
|
||||
dojo.forEach(this._groups[this.name], function(widget, i, arr){
|
||||
if(widget === this){
|
||||
arr.splice(i, 1);
|
||||
return;
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
|
||||
setChecked: function(/*Boolean*/ checked){
|
||||
// If I am being checked then have to deselect currently checked radio button
|
||||
if(checked){
|
||||
dojo.forEach(this._groups[this.name], function(widget){
|
||||
if(widget != this && widget.checked){
|
||||
widget.setChecked(false);
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
dijit.form.CheckBox.prototype.setChecked.apply(this, arguments);
|
||||
},
|
||||
|
||||
onClick: function(/*Event*/ e){
|
||||
if(!this.checked){
|
||||
this.setChecked(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
679
spring-faces/src/main/java/META-INF/dijit/form/ComboBox.js
Normal file
679
spring-faces/src/main/java/META-INF/dijit/form/ComboBox.js
Normal file
@@ -0,0 +1,679 @@
|
||||
if(!dojo._hasResource["dijit.form.ComboBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.form.ComboBox"] = true;
|
||||
dojo.provide("dijit.form.ComboBox");
|
||||
|
||||
dojo.require("dojo.data.ItemFileReadStore");
|
||||
dojo.require("dijit.form._DropDownTextBox");
|
||||
dojo.require("dijit.form.ValidationTextBox");
|
||||
dojo.requireLocalization("dijit.form", "ComboBox", null, "ROOT");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.form.ComboBoxMixin",
|
||||
dijit.form._DropDownTextBox,
|
||||
{
|
||||
// summary:
|
||||
// Auto-completing text box, and base class for FilteringSelect widget.
|
||||
//
|
||||
// The drop down box's values are populated from an class called
|
||||
// a data provider, which returns a list of values based on the characters
|
||||
// that the user has typed into the input box.
|
||||
//
|
||||
// Some of the options to the ComboBox are actually arguments to the data
|
||||
// provider.
|
||||
|
||||
// pageSize: Integer
|
||||
// Argument to data provider.
|
||||
// Specifies number of search results per page (before hitting "next" button)
|
||||
pageSize: 30,
|
||||
|
||||
// store: Object
|
||||
// Reference to data provider object used by this ComboBox
|
||||
store: null,
|
||||
|
||||
// query: Object
|
||||
// A query that can be passed to 'store' to initially filter the items,
|
||||
// before doing further filtering based on searchAttr and the key.
|
||||
query: {},
|
||||
|
||||
// autoComplete: Boolean
|
||||
// If you type in a partial string, and then tab out of the <input> box,
|
||||
// automatically copy the first entry displayed in the drop down list to
|
||||
// the <input> field
|
||||
autoComplete: true,
|
||||
|
||||
// searchDelay: Integer
|
||||
// Delay in milliseconds between when user types something and we start
|
||||
// searching based on that value
|
||||
searchDelay: 100,
|
||||
|
||||
// searchAttr: String
|
||||
// Searches pattern match against this field
|
||||
searchAttr: "name",
|
||||
|
||||
// ignoreCase: Boolean
|
||||
// Does the ComboBox menu ignore case?
|
||||
ignoreCase: true,
|
||||
|
||||
_hasMasterPopup:true,
|
||||
|
||||
_popupClass:"dijit.form._ComboBoxMenu",
|
||||
|
||||
getValue:function(){
|
||||
// don't get the textbox value but rather the previously set hidden value
|
||||
return dijit.form.TextBox.superclass.getValue.apply(this, arguments);
|
||||
},
|
||||
|
||||
setDisplayedValue:function(/*String*/ value){
|
||||
this.setValue(value, true);
|
||||
},
|
||||
|
||||
_getCaretPos: function(/*DomNode*/ element){
|
||||
// khtml 3.5.2 has selection* methods as does webkit nightlies from 2005-06-22
|
||||
if(typeof(element.selectionStart)=="number"){
|
||||
// FIXME: this is totally borked on Moz < 1.3. Any recourse?
|
||||
return element.selectionStart;
|
||||
}else if(dojo.isIE){
|
||||
// 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(/*DomNode*/ element, /*Number*/ location){
|
||||
location = parseInt(location);
|
||||
this._setSelectedRange(element, location, location);
|
||||
},
|
||||
|
||||
_setSelectedRange: function(/*DomNode*/ element, /*Number*/ start, /*Number*/ 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){
|
||||
dijit.focus(element);
|
||||
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();
|
||||
dijit.focus(element);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onkeypress: function(/*Event*/ evt){
|
||||
// summary: handles keyboard events
|
||||
if(evt.ctrlKey || evt.altKey){
|
||||
return;
|
||||
}
|
||||
var doSearch = false;
|
||||
if(this._isShowingNow){this._popupWidget.handleKey(evt);}
|
||||
switch(evt.keyCode){
|
||||
case dojo.keys.PAGE_DOWN:
|
||||
case dojo.keys.DOWN_ARROW:
|
||||
if(!this._isShowingNow||this._prev_key_esc){
|
||||
this._arrowPressed();
|
||||
doSearch=true;
|
||||
}else{
|
||||
this._announceOption(this._popupWidget.getHighlightedOption());
|
||||
}
|
||||
dojo.stopEvent(evt);
|
||||
this._prev_key_backspace = false;
|
||||
this._prev_key_esc = false;
|
||||
break;
|
||||
|
||||
case dojo.keys.PAGE_UP:
|
||||
case dojo.keys.UP_ARROW:
|
||||
if(this._isShowingNow){
|
||||
this._announceOption(this._popupWidget.getHighlightedOption());
|
||||
}
|
||||
dojo.stopEvent(evt);
|
||||
this._prev_key_backspace = false;
|
||||
this._prev_key_esc = false;
|
||||
break;
|
||||
|
||||
case dojo.keys.ENTER:
|
||||
// prevent submitting form if user presses enter
|
||||
// also prevent accepting the value if either Next or Previous are selected
|
||||
if(this._isShowingNow){
|
||||
// only stop event on prev/next
|
||||
var highlighted=this._popupWidget.getHighlightedOption();
|
||||
if(highlighted==this._popupWidget.nextButton){
|
||||
this._nextSearch(1);
|
||||
dojo.stopEvent(evt);
|
||||
break;
|
||||
}
|
||||
else if(highlighted==this._popupWidget.previousButton){
|
||||
this._nextSearch(-1);
|
||||
dojo.stopEvent(evt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// default case:
|
||||
// prevent submit, but allow event to bubble
|
||||
evt.preventDefault();
|
||||
// fall through
|
||||
|
||||
case dojo.keys.TAB:
|
||||
if(this._isShowingNow){
|
||||
this._prev_key_backspace = false;
|
||||
this._prev_key_esc = false;
|
||||
if(this._isShowingNow&&this._popupWidget.getHighlightedOption()){
|
||||
this._popupWidget.setValue({target:this._popupWidget.getHighlightedOption()}, true);
|
||||
}else{
|
||||
this.setDisplayedValue(this.getDisplayedValue());
|
||||
}
|
||||
this._hideResultList();
|
||||
}else{
|
||||
// also allow arbitrary user input
|
||||
this.setDisplayedValue(this.getDisplayedValue());
|
||||
}
|
||||
break;
|
||||
|
||||
case dojo.keys.SPACE:
|
||||
this._prev_key_backspace = false;
|
||||
this._prev_key_esc = false;
|
||||
if(this._isShowingNow && this._popupWidget.getHighlightedOption()){
|
||||
dojo.stopEvent(evt);
|
||||
this._selectOption();
|
||||
this._hideResultList();
|
||||
}
|
||||
else{doSearch=true;}
|
||||
break;
|
||||
|
||||
case dojo.keys.ESCAPE:
|
||||
this._prev_key_backspace = false;
|
||||
this._prev_key_esc = true;
|
||||
this._hideResultList();
|
||||
this.setValue(this.getValue());
|
||||
break;
|
||||
|
||||
case dojo.keys.DELETE:
|
||||
case dojo.keys.BACKSPACE:
|
||||
this._prev_key_esc = false;
|
||||
this._prev_key_backspace = true;
|
||||
doSearch=true;
|
||||
break;
|
||||
|
||||
case dojo.keys.RIGHT_ARROW: // fall through
|
||||
|
||||
case dojo.keys.LEFT_ARROW: // fall through
|
||||
this._prev_key_backspace = false;
|
||||
this._prev_key_esc = false;
|
||||
break;
|
||||
|
||||
default:// non char keys (F1-F12 etc..) shouldn't open list
|
||||
this._prev_key_backspace = false;
|
||||
this._prev_key_esc = false;
|
||||
if(evt.charCode!=0){
|
||||
doSearch=true;
|
||||
}
|
||||
}
|
||||
if(this.searchTimer){
|
||||
clearTimeout(this.searchTimer);
|
||||
}
|
||||
if(doSearch){
|
||||
// need to wait a tad before start search so that the event bubbles through DOM and we have value visible
|
||||
this.searchTimer = setTimeout(dojo.hitch(this, this._startSearchFromInput), this.searchDelay);
|
||||
}
|
||||
},
|
||||
|
||||
_autoCompleteText: function(/*String*/ text){
|
||||
// summary:
|
||||
// Fill in the textbox with the first item from the drop down list, and
|
||||
// highlight the characters that were auto-completed. For example, if user
|
||||
// typed "CA" and the drop down list appeared, the textbox would be changed to
|
||||
// "California" and "ifornia" would be highlighted.
|
||||
|
||||
// IE7: clear selection so next highlight works all the time
|
||||
this._setSelectedRange(this.focusNode, this.focusNode.value.length, this.focusNode.value.length);
|
||||
// does text autoComplete the value in the textbox?
|
||||
// #3744: escape regexp so the user's input isn't treated as a regular expression.
|
||||
// Example: If the user typed "(" then the regexp would throw "unterminated parenthetical."
|
||||
// Also see #2558 for the autocompletion bug this regular expression fixes.
|
||||
if(new RegExp("^"+escape(this.focusNode.value), this.ignoreCase ? "i" : "").test(escape(text))){
|
||||
var cpos = this._getCaretPos(this.focusNode);
|
||||
// only try to extend if we added the last character at the end of the input
|
||||
if((cpos+1) > this.focusNode.value.length){
|
||||
// only add to input node as we would overwrite Capitalisation of chars
|
||||
// actually, that is ok
|
||||
this.focusNode.value = text;//.substr(cpos);
|
||||
// visually highlight the autocompleted characters
|
||||
this._setSelectedRange(this.focusNode, cpos, this.focusNode.value.length);
|
||||
}
|
||||
}else{
|
||||
// text does not autoComplete; replace the whole value and highlight
|
||||
this.focusNode.value = text;
|
||||
this._setSelectedRange(this.focusNode, 0, this.focusNode.value.length);
|
||||
}
|
||||
},
|
||||
|
||||
_openResultList: function(/*Object*/ results, /*Object*/ dataObject){
|
||||
if(this.disabled||dataObject.query[this.searchAttr]!=this._lastQuery){
|
||||
return;
|
||||
}
|
||||
this._popupWidget.clearResultList();
|
||||
if(!results.length){
|
||||
this._hideResultList();
|
||||
return;
|
||||
}
|
||||
|
||||
// Fill in the textbox with the first item from the drop down list, and
|
||||
// highlight the characters that were auto-completed. For example, if user
|
||||
// typed "CA" and the drop down list appeared, the textbox would be changed to
|
||||
// "California" and "ifornia" would be highlighted.
|
||||
|
||||
var zerothvalue=new String(this.store.getValue(results[0], this.searchAttr));
|
||||
if(zerothvalue&&(this.autoComplete)&&
|
||||
(!this._prev_key_backspace)&&
|
||||
// when the user clicks the arrow button to show the full list,
|
||||
// startSearch looks for "*".
|
||||
// it does not make sense to autocomplete
|
||||
// if they are just previewing the options available.
|
||||
(dataObject.query[this.searchAttr]!="*")){
|
||||
this._autoCompleteText(zerothvalue);
|
||||
// announce the autocompleted value
|
||||
dijit.wai.setAttr(this.focusNode || this.domNode, "waiState", "valuenow", zerothvalue);
|
||||
}
|
||||
this._popupWidget.createOptions(results, dataObject, dojo.hitch(this, this._getMenuLabelFromItem));
|
||||
|
||||
// show our list (only if we have content, else nothing)
|
||||
this._showResultList();
|
||||
},
|
||||
|
||||
onfocus:function(){
|
||||
dijit.form._DropDownTextBox.prototype.onfocus.apply(this, arguments);
|
||||
this.inherited('onfocus', arguments);
|
||||
},
|
||||
|
||||
onblur:function(){ /* not _onBlur! */
|
||||
// call onblur first to avoid race conditions with _hasFocus
|
||||
dijit.form._DropDownTextBox.prototype.onblur.apply(this, arguments);
|
||||
if(!this._isShowingNow){
|
||||
// if the user clicks away from the textbox, set the value to the textbox value
|
||||
this.setDisplayedValue(this.getDisplayedValue());
|
||||
}
|
||||
// don't call this since the TextBox setValue is asynchronous
|
||||
// if you uncomment this line, when you click away from the textbox,
|
||||
// the value in the textbox reverts to match the hidden value
|
||||
//this.parentClass.onblur.apply(this, arguments);
|
||||
},
|
||||
|
||||
_announceOption: function(/*Node*/ node){
|
||||
// summary:
|
||||
// a11y code that puts the highlighted option in the textbox
|
||||
// This way screen readers will know what is happening in the menu
|
||||
|
||||
if(node==null){return;}
|
||||
// pull the text value from the item attached to the DOM node
|
||||
var newValue;
|
||||
if(node==this._popupWidget.nextButton||node==this._popupWidget.previousButton){
|
||||
newValue=node.innerHTML;
|
||||
}else{
|
||||
newValue=this.store.getValue(node.item, this.searchAttr);
|
||||
}
|
||||
// get the text that the user manually entered (cut off autocompleted text)
|
||||
this.focusNode.value=this.focusNode.value.substring(0, this._getCaretPos(this.focusNode));
|
||||
// autocomplete the rest of the option to announce change
|
||||
this._autoCompleteText(newValue);
|
||||
},
|
||||
|
||||
_selectOption: function(/*Event*/ evt){
|
||||
var tgt = null;
|
||||
if(!evt){
|
||||
evt ={ target: this._popupWidget.getHighlightedOption()};
|
||||
}
|
||||
// what if nothing is highlighted yet?
|
||||
if(!evt.target){
|
||||
// handle autocompletion where the the user has hit ENTER or TAB
|
||||
this.setDisplayedValue(this.getDisplayedValue());
|
||||
return;
|
||||
// otherwise the user has accepted the autocompleted value
|
||||
}else{
|
||||
tgt = evt.target;
|
||||
}
|
||||
if(!evt.noHide){
|
||||
this._hideResultList();
|
||||
this._setCaretPos(this.focusNode, this.store.getValue(tgt.item, this.searchAttr).length);
|
||||
}
|
||||
this._doSelect(tgt);
|
||||
},
|
||||
|
||||
_doSelect: function(tgt){
|
||||
this.setValue(this.store.getValue(tgt.item, this.searchAttr), true);
|
||||
},
|
||||
|
||||
_onArrowClick: function(){
|
||||
// summary: callback when arrow is clicked
|
||||
if(this.disabled){
|
||||
return;
|
||||
}
|
||||
this.focus();
|
||||
this.makePopup();
|
||||
if(this._isShowingNow){
|
||||
this._hideResultList();
|
||||
}else{
|
||||
// forces full population of results, if they click
|
||||
// on the arrow it means they want to see more options
|
||||
this._startSearch("");
|
||||
}
|
||||
},
|
||||
|
||||
_startSearchFromInput: function(){
|
||||
this._startSearch(this.focusNode.value);
|
||||
},
|
||||
|
||||
_startSearch: function(/*String*/ key){
|
||||
this.makePopup();
|
||||
// create a new query to prevent accidentally querying for a hidden value from FilteringSelect's keyField
|
||||
var query=this.query;
|
||||
this._lastQuery=query[this.searchAttr]=key+"*";
|
||||
var dataObject=this.store.fetch({queryOptions:{ignoreCase:this.ignoreCase, deep:true}, query: query, onComplete:dojo.hitch(this, "_openResultList"), start:0, count:this.pageSize});
|
||||
function nextSearch(dataObject, direction){
|
||||
dataObject.start+=dataObject.count*direction;
|
||||
dataObject.store.fetch(dataObject);
|
||||
}
|
||||
this._nextSearch=this._popupWidget.onPage=dojo.hitch(this, nextSearch, dataObject);
|
||||
},
|
||||
|
||||
_getValueField:function(){
|
||||
return this.searchAttr;
|
||||
},
|
||||
|
||||
postMixInProperties: function(){
|
||||
dijit.form._DropDownTextBox.prototype.postMixInProperties.apply(this, arguments);
|
||||
if(!this.store){
|
||||
// if user didn't specify store, then assume there are option tags
|
||||
var items = dojo.query("> option", this.srcNodeRef).map(function(node){
|
||||
node.style.display="none";
|
||||
return { value: node.getAttribute("value"), name: String(node.innerHTML) };
|
||||
});
|
||||
this.store = new dojo.data.ItemFileReadStore({data: {identifier:this._getValueField(), items:items}});
|
||||
|
||||
// if there is no value set and there is an option list,
|
||||
// set the value to the first value to be consistent with native Select
|
||||
if(items&&items.length&&!this.value){
|
||||
// For <select>, IE does not let you set the value attribute of the srcNodeRef (and thus dojo.mixin does not copy it).
|
||||
// IE does understand selectedIndex though, which is automatically set by the selected attribute of an option tag
|
||||
this.value=items[this.srcNodeRef.selectedIndex!=-1?this.srcNodeRef.selectedIndex:0][this._getValueField()];
|
||||
}
|
||||
}
|
||||
// instantiate query so comboboxes with different data stores and default query work together
|
||||
if(this.query==dijit.form.ComboBoxMixin.prototype.query){this.query={};}
|
||||
},
|
||||
|
||||
postCreate: function(){
|
||||
// call the associated TextBox postCreate
|
||||
// ValidationTextBox for ComboBox; MappedTextBox for FilteringSelect
|
||||
this.inherited('postCreate', arguments);
|
||||
},
|
||||
|
||||
_getMenuLabelFromItem:function(/*Item*/ item){
|
||||
return {html:false, label:this.store.getValue(item, this.searchAttr)};
|
||||
},
|
||||
|
||||
open:function(){
|
||||
this._popupWidget.onChange=dojo.hitch(this, this._selectOption);
|
||||
// connect onkeypress to ComboBox
|
||||
this._popupWidget._onkeypresshandle=this._popupWidget.connect(this._popupWidget.domNode, "onkeypress", dojo.hitch(this, this.onkeypress));
|
||||
return dijit.form._DropDownTextBox.prototype.open.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
dojo.declare(
|
||||
"dijit.form._ComboBoxMenu",
|
||||
[dijit._Widget, dijit._Templated],
|
||||
|
||||
{
|
||||
// summary:
|
||||
// Focus-less div based menu for internal use in ComboBox
|
||||
|
||||
templateString:"<div class='dijitMenu' dojoAttachEvent='onclick,onmouseover,onmouseout' tabIndex='-1' style='display:none; position:absolute; overflow:\"auto\";'>"
|
||||
+"<div class='dijitMenuItem' dojoAttachPoint='previousButton'></div>"
|
||||
+"<div class='dijitMenuItem' dojoAttachPoint='nextButton'></div>"
|
||||
+"</div>",
|
||||
_onkeypresshandle:null,
|
||||
_messages:null,
|
||||
_comboBox:null,
|
||||
|
||||
postMixInProperties:function(){
|
||||
this._messages = dojo.i18n.getLocalization("dijit.form", "ComboBox", this.lang);
|
||||
this.inherited("postMixInProperties", arguments);
|
||||
},
|
||||
|
||||
setValue:function(/*Object*/ value){
|
||||
this.value=value;
|
||||
this.onChange(value);
|
||||
},
|
||||
|
||||
onChange:function(/*Object*/ value){},
|
||||
onPage:function(/*Number*/ direction){},
|
||||
|
||||
postCreate:function(){
|
||||
// fill in template with i18n messages
|
||||
this.previousButton.innerHTML=this._messages["previousMessage"];
|
||||
this.nextButton.innerHTML=this._messages["nextMessage"];
|
||||
this.inherited("postCreate", arguments);
|
||||
},
|
||||
|
||||
onClose:function(){
|
||||
this.disconnect(this._onkeypresshandle);
|
||||
this._blurOptionNode();
|
||||
},
|
||||
|
||||
_createOption:function(/*Object*/ item, labelFunc){
|
||||
// summary: creates an option to appear on the popup menu
|
||||
// subclassed by FilteringSelect
|
||||
|
||||
var labelObject=labelFunc(item);
|
||||
var menuitem = document.createElement("div");
|
||||
if(labelObject.html){menuitem.innerHTML=labelObject.label;}
|
||||
else{menuitem.appendChild(document.createTextNode(labelObject.label));}
|
||||
// #3250: in blank options, assign a normal height
|
||||
if(menuitem.innerHTML==""){
|
||||
menuitem.innerHTML=" "
|
||||
}
|
||||
menuitem.item=item;
|
||||
return menuitem;
|
||||
},
|
||||
|
||||
createOptions:function(results, dataObject, labelFunc){
|
||||
//this._dataObject=dataObject;
|
||||
//this._dataObject.onComplete=dojo.hitch(comboBox, comboBox._openResultList);
|
||||
// display "Previous . . ." button
|
||||
this.previousButton.style.display=dataObject.start==0?"none":"";
|
||||
// create options using _createOption function defined by parent ComboBox (or FilteringSelect) class
|
||||
// #2309: iterate over cache nondestructively
|
||||
var _this=this;
|
||||
dojo.forEach(results, function(item){
|
||||
var menuitem=_this._createOption(item, labelFunc);
|
||||
menuitem.className = "dijitMenuItem";
|
||||
_this.domNode.insertBefore(menuitem, _this.nextButton);
|
||||
});
|
||||
// display "Next . . ." button
|
||||
this.nextButton.style.display=dataObject.count==results.length?"":"none";
|
||||
},
|
||||
|
||||
clearResultList:function(){
|
||||
// keep the previous and next buttons of course
|
||||
while(this.domNode.childNodes.length>2){
|
||||
this.domNode.removeChild(this.domNode.childNodes[this.domNode.childNodes.length-2]);
|
||||
}
|
||||
},
|
||||
|
||||
// these functions are called in showResultList
|
||||
getItems:function(){
|
||||
return this.domNode.childNodes;
|
||||
},
|
||||
|
||||
getListLength:function(){
|
||||
return this.domNode.childNodes.length-2;
|
||||
},
|
||||
|
||||
onclick:function(/*Event*/ evt){
|
||||
if(evt.target === this.domNode){
|
||||
return;
|
||||
}else if(evt.target==this.previousButton){
|
||||
this.onPage(-1);
|
||||
}else if(evt.target==this.nextButton){
|
||||
this.onPage(1);
|
||||
}else{
|
||||
var tgt=evt.target;
|
||||
// while the clicked node is inside the div
|
||||
while(!tgt.item){
|
||||
// recurse to the top
|
||||
tgt=tgt.parentNode;
|
||||
}
|
||||
this.setValue({target:tgt}, true);
|
||||
}
|
||||
},
|
||||
|
||||
onmouseover:function(/*Event*/ evt){
|
||||
if(evt.target === this.domNode){ return; }
|
||||
this._focusOptionNode(evt.target);
|
||||
},
|
||||
|
||||
onmouseout:function(/*Event*/ evt){
|
||||
if(evt.target === this.domNode){ return; }
|
||||
this._blurOptionNode();
|
||||
},
|
||||
|
||||
_focusOptionNode:function(/*DomNode*/ node){
|
||||
// summary:
|
||||
// does the actual highlight
|
||||
if(this._highlighted_option != node){
|
||||
this._blurOptionNode();
|
||||
this._highlighted_option = node;
|
||||
dojo.addClass(this._highlighted_option, "dijitMenuItemHover");
|
||||
}
|
||||
},
|
||||
|
||||
_blurOptionNode:function(){
|
||||
// summary:
|
||||
// removes highlight on highlighted option
|
||||
if(this._highlighted_option){
|
||||
dojo.removeClass(this._highlighted_option, "dijitMenuItemHover");
|
||||
this._highlighted_option = null;
|
||||
}
|
||||
},
|
||||
|
||||
_highlightNextOption:function(){
|
||||
// because each press of a button clears the menu,
|
||||
// the highlighted option sometimes becomes detached from the menu!
|
||||
// test to see if the option has a parent to see if this is the case.
|
||||
if(!this.getHighlightedOption()){
|
||||
this._focusOptionNode(this.domNode.firstChild.style.display=="none"?this.domNode.firstChild.nextSibling:this.domNode.firstChild);
|
||||
}else if(this._highlighted_option.nextSibling&&this._highlighted_option.nextSibling.style.display!="none"){
|
||||
this._focusOptionNode(this._highlighted_option.nextSibling);
|
||||
}
|
||||
dijit.scrollIntoView(this._highlighted_option);
|
||||
},
|
||||
|
||||
|
||||
_highlightPrevOption:function(){
|
||||
// if nothing selected, highlight last option
|
||||
// makes sense if you select Previous and try to keep scrolling up the list
|
||||
if(!this.getHighlightedOption()){
|
||||
this._focusOptionNode(this.domNode.lastChild.style.display=="none"?this.domNode.lastChild.previousSibling:this.domNode.lastChild);
|
||||
}else if(this._highlighted_option.previousSibling&&this._highlighted_option.previousSibling.style.display!="none"){
|
||||
this._focusOptionNode(this._highlighted_option.previousSibling);
|
||||
}
|
||||
dijit.scrollIntoView(this._highlighted_option);
|
||||
},
|
||||
|
||||
_page:function(/*Boolean*/ up){
|
||||
var scrollamount=0;
|
||||
var oldscroll=this.domNode.scrollTop;
|
||||
var height=parseInt(dojo.getComputedStyle(this.domNode).height);
|
||||
// if no item is highlighted, highlight the first option
|
||||
if(!this.getHighlightedOption()){this._highlightNextOption();}
|
||||
while(scrollamount<height){
|
||||
if(up){
|
||||
// stop at option 1
|
||||
if(!this.getHighlightedOption().previousSibling||this._highlighted_option.previousSibling.style.display=="none"){break;}
|
||||
this._highlightPrevOption();
|
||||
}else{
|
||||
// stop at last option
|
||||
if(!this.getHighlightedOption().nextSibling||this._highlighted_option.nextSibling.style.display=="none"){break;}
|
||||
this._highlightNextOption();
|
||||
}
|
||||
// going backwards
|
||||
var newscroll=this.domNode.scrollTop;
|
||||
scrollamount+=(newscroll-oldscroll)*(up ? -1:1);
|
||||
oldscroll=newscroll;
|
||||
}
|
||||
},
|
||||
|
||||
pageUp:function(){
|
||||
this._page(true);
|
||||
},
|
||||
|
||||
pageDown:function(){
|
||||
this._page(false);
|
||||
},
|
||||
|
||||
getHighlightedOption:function(){
|
||||
// summary:
|
||||
// Returns the highlighted option.
|
||||
return this._highlighted_option&&this._highlighted_option.parentNode ? this._highlighted_option : null;
|
||||
},
|
||||
|
||||
handleKey:function(evt){
|
||||
switch(evt.keyCode){
|
||||
case dojo.keys.DOWN_ARROW:
|
||||
this._highlightNextOption();
|
||||
break;
|
||||
case dojo.keys.PAGE_DOWN:
|
||||
this.pageDown();
|
||||
break;
|
||||
case dojo.keys.UP_ARROW:
|
||||
this._highlightPrevOption();
|
||||
break;
|
||||
case dojo.keys.PAGE_UP:
|
||||
this.pageUp();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
dojo.declare(
|
||||
"dijit.form.ComboBox",
|
||||
[dijit.form.ValidationTextBox, dijit.form.ComboBoxMixin],
|
||||
{}
|
||||
);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
if(!dojo._hasResource["dijit.form.CurrencyTextBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.form.CurrencyTextBox"] = true;
|
||||
dojo.provide("dijit.form.CurrencyTextBox");
|
||||
|
||||
//FIXME: dojo.experimental throws an unreadable exception?
|
||||
//dojo.experimental("dijit.form.CurrencyTextBox");
|
||||
|
||||
dojo.require("dojo.currency");
|
||||
dojo.declare(
|
||||
"dijit.form.CurrencyTextBox",
|
||||
dijit.form.NumberTextBox,
|
||||
{
|
||||
// code: String
|
||||
// the ISO4217 currency code, a three letter sequence like "USD"
|
||||
// See http://en.wikipedia.org/wiki/ISO_4217
|
||||
currency: "",
|
||||
|
||||
regExpGen: dojo.currency.regexp,
|
||||
format: dojo.currency.format,
|
||||
parse: dojo.currency.parse,
|
||||
|
||||
postMixInProperties: function(){
|
||||
if(this.constraints === dijit.form.ValidationTextBox.prototype.constraints){
|
||||
// declare a constraints property on 'this' so we don't overwrite the shared default object in 'prototype'
|
||||
this.constraints = {};
|
||||
}
|
||||
this.constraints.currency = this.currency;
|
||||
dijit.form.CurrencyTextBox.superclass.postMixInProperties.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
if(!dojo._hasResource["dijit.form.DateTextBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.form.DateTextBox"] = true;
|
||||
dojo.provide("dijit.form.DateTextBox");
|
||||
|
||||
dojo.require("dijit._Calendar");
|
||||
dojo.require("dijit.form.TimeTextBox");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.form.DateTextBox",
|
||||
dijit.form.TimeTextBox,
|
||||
{
|
||||
// summary:
|
||||
// A validating, serializable, range-bound date text box.
|
||||
|
||||
_popupClass: "dijit._Calendar",
|
||||
|
||||
postMixInProperties: function(){
|
||||
this.inherited('postMixInProperties', arguments);
|
||||
this.constraints.selector = 'date';
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
if(!dojo._hasResource["dijit.form.FilteringSelect"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.form.FilteringSelect"] = true;
|
||||
dojo.provide("dijit.form.FilteringSelect");
|
||||
|
||||
dojo.require("dijit.form.ComboBox");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.form.FilteringSelect",
|
||||
[dijit.form.MappedTextBox, dijit.form.ComboBoxMixin],
|
||||
{
|
||||
/*
|
||||
* summary
|
||||
* Enhanced version of HTML's <select> tag.
|
||||
*
|
||||
* Similar features:
|
||||
* - There is a drop down list of possible values.
|
||||
* - You can only enter a value from the drop down list. (You can't enter an arbitrary value.)
|
||||
* - The value submitted with the form is the hidden value (ex: CA),
|
||||
* not the displayed value a.k.a. label (ex: California)
|
||||
*
|
||||
* Enhancements over plain HTML version:
|
||||
* - If you type in some text then it will filter down the list of possible values in the drop down list.
|
||||
* - List can be specified either as a static list or via a javascript function (that can get the list from a server)
|
||||
*/
|
||||
|
||||
// searchAttr: String
|
||||
// Searches pattern match against this field
|
||||
|
||||
// labelAttr: String
|
||||
// Optional. The text that actually appears in the drop down.
|
||||
// If not specified, the searchAttr text is used instead.
|
||||
labelAttr: "",
|
||||
|
||||
// labelType: String
|
||||
// "html" or "text"
|
||||
labelType: "text",
|
||||
|
||||
_isvalid:true,
|
||||
|
||||
isValid:function(){
|
||||
return this._isvalid;
|
||||
},
|
||||
|
||||
_callbackSetLabel: function(/*Array*/ result, /*Object*/ dataObject){
|
||||
// summary
|
||||
// Callback function that dynamically sets the label of the ComboBox
|
||||
|
||||
// setValue does a synchronous lookup,
|
||||
// so it calls _callbackSetLabel directly,
|
||||
// and so does not pass dataObject
|
||||
// dataObject==null means do not test the lastQuery, just continue
|
||||
if(dataObject&&dataObject.query[this.searchAttr]!=this._lastQuery){return;}
|
||||
if(!result.length){
|
||||
//#3268: do nothing on bad input
|
||||
//this._setValue("", "");
|
||||
//#3285: change CSS to indicate error
|
||||
this._isvalid=false;
|
||||
this.validate(this._hasFocus);
|
||||
}else{
|
||||
this._setValueFromItem(result[0]);
|
||||
}
|
||||
},
|
||||
|
||||
_openResultList: function(/*Object*/ results, /*Object*/ dataObject){
|
||||
// #3285: tap into search callback to see if user's query resembles a match
|
||||
if(dataObject.query[this.searchAttr]!=this._lastQuery){return;}
|
||||
this._isvalid=results.length!=0;
|
||||
this.validate(true);
|
||||
dijit.form.ComboBoxMixin.prototype._openResultList.apply(this, arguments);
|
||||
},
|
||||
|
||||
getValue:function(){
|
||||
// don't get the textbox value but rather the previously set hidden value
|
||||
return this.valueNode.value;
|
||||
},
|
||||
|
||||
_getValueField:function(){
|
||||
// used for option tag selects
|
||||
return "value";
|
||||
},
|
||||
|
||||
_setValue:function(/*String*/ value, /*String*/ displayedValue){
|
||||
this.valueNode.value = value;
|
||||
dijit.form.FilteringSelect.superclass.setValue.call(this, value, true, displayedValue);
|
||||
},
|
||||
|
||||
setValue: function(/*String*/ value){
|
||||
// summary
|
||||
// Sets the value of the select.
|
||||
// Also sets the label to the corresponding value by reverse lookup.
|
||||
|
||||
//#3347: fetchItemByIdentity if no keyAttr specified
|
||||
var self=this;
|
||||
var handleFetchByIdentity = function(item){
|
||||
if(item){
|
||||
if(self.store.isItemLoaded(item)){
|
||||
self._callbackSetLabel([item]);
|
||||
}else{
|
||||
self.store.loadItem({item:item, onItem: self._callbackSetLabel});
|
||||
}
|
||||
}else{
|
||||
self._isvalid=false;
|
||||
// prevent errors from Tooltip not being created yet
|
||||
self.validate(false);
|
||||
}
|
||||
}
|
||||
this.store.fetchItemByIdentity({identity: value, onItem: handleFetchByIdentity});
|
||||
},
|
||||
|
||||
_setValueFromItem: function(/*item*/ item){
|
||||
// summary
|
||||
// Set the displayed valued in the input box, based on a selected item.
|
||||
// Users shouldn't call this function; they should be calling setDisplayedValue() instead
|
||||
this._isvalid=true;
|
||||
this._setValue(this.store.getIdentity(item), this.labelFunc(item, this.store));
|
||||
},
|
||||
|
||||
labelFunc: function(/*item*/ item, /*dojo.data.store*/ store){
|
||||
// summary: Event handler called when the label changes
|
||||
// returns the label that the ComboBox should display
|
||||
return store.getValue(item, this.searchAttr);
|
||||
},
|
||||
|
||||
onkeyup: function(/*Event*/ evt){
|
||||
// summary: internal function
|
||||
// FilteringSelect needs to wait for the complete label before committing to a reverse lookup
|
||||
//this.setDisplayedValue(this.textbox.value);
|
||||
},
|
||||
|
||||
_doSelect: function(/*Event*/ tgt){
|
||||
// summary:
|
||||
// ComboBox's menu callback function
|
||||
// FilteringSelect overrides this to set both the visible and hidden value from the information stored in the menu
|
||||
|
||||
this._setValueFromItem(tgt.item);
|
||||
},
|
||||
|
||||
setDisplayedValue:function(/*String*/ label){
|
||||
// summary:
|
||||
// Set textbox to display label
|
||||
// Also performs reverse lookup to set the hidden value
|
||||
// Used in InlineEditBox
|
||||
|
||||
if(this.store){
|
||||
var query={};
|
||||
this._lastQuery=query[this.searchAttr]=label;
|
||||
// if the label is not valid, the callback will never set it,
|
||||
// so the last valid value will get the warning textbox
|
||||
// set the textbox value now so that the impending warning will make sense to the user
|
||||
this.textbox.value=label;
|
||||
this.store.fetch({query:query, queryOptions:{ignoreCase:this.ignoreCase, deep:true}, onComplete: dojo.hitch(this, this._callbackSetLabel)});
|
||||
}
|
||||
},
|
||||
|
||||
_getMenuLabelFromItem:function(/*Item*/ item){
|
||||
// internal function to help ComboBoxMenu figure out what to display
|
||||
if(this.labelAttr){return {html:this.labelType=="html", label:this.store.getValue(item, this.labelAttr)};}
|
||||
else{
|
||||
// because this function is called by ComboBoxMenu, this.inherited tries to find the superclass of ComboBoxMenu
|
||||
return dijit.form.ComboBoxMixin.prototype._getMenuLabelFromItem.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
270
spring-faces/src/main/java/META-INF/dijit/form/Form.js
Normal file
270
spring-faces/src/main/java/META-INF/dijit/form/Form.js
Normal file
@@ -0,0 +1,270 @@
|
||||
if(!dojo._hasResource["dijit.form.Form"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.form.Form"] = true;
|
||||
dojo.provide("dijit.form.Form");
|
||||
|
||||
dojo.require("dijit._Widget");
|
||||
dojo.require("dijit._Templated");
|
||||
|
||||
dojo.declare("dijit.form._FormMixin", null,
|
||||
{
|
||||
/*
|
||||
summary:
|
||||
Widget corresponding to <form> tag, for validation and serialization
|
||||
|
||||
usage:
|
||||
<form dojoType="dijit.form.Form" id="myForm">
|
||||
Name: <input type="text" name="name" />
|
||||
</form>
|
||||
myObj={name: "John Doe"};
|
||||
dijit.byId('myForm').setValues(myObj);
|
||||
|
||||
myObj=dijit.byId('myForm').getValues();
|
||||
TODO:
|
||||
* Repeater
|
||||
* better handling for arrays. Often form elements have names with [] like
|
||||
* people[3].sex (for a list of people [{name: Bill, sex: M}, ...])
|
||||
|
||||
*/
|
||||
|
||||
// execute: Function
|
||||
// User defined function to do stuff when the user hits the submit button
|
||||
execute: function(/*Object*/ formContents){},
|
||||
|
||||
// onCancel: Function
|
||||
// Callback when user has canceled dialog, to notify container
|
||||
// (user shouldn't override)
|
||||
onCancel: function(){},
|
||||
|
||||
// onExecute: Function
|
||||
// Callback when user is about to execute dialog, to notify container
|
||||
// (user shouldn't override)
|
||||
onExecute: function(){},
|
||||
|
||||
templateString: "<form dojoAttachPoint='containerNode' dojoAttachEvent='onsubmit:_onSubmit' enctype='multipart/form-data'></form>",
|
||||
|
||||
_onSubmit: function(/*event*/e) {
|
||||
// summary: callback when user hits submit button
|
||||
dojo.stopEvent(e);
|
||||
this.onExecute(); // notify container that we are about to execute
|
||||
this.execute(this.getValues());
|
||||
},
|
||||
|
||||
submit: function() {
|
||||
// summary: programatically submit form
|
||||
this.containerNode.submit();
|
||||
},
|
||||
|
||||
setValues: function(/*object*/obj) {
|
||||
// summary: fill in form values from a JSON structure
|
||||
|
||||
// generate map from name --> [list of widgets with that name]
|
||||
var map = {};
|
||||
dojo.forEach(this.getDescendants(), function(widget){
|
||||
if(!widget.name){ return; }
|
||||
var entry = map[widget.name] || (map[widget.name] = [] );
|
||||
entry.push(widget);
|
||||
});
|
||||
|
||||
// call setValue() or setChecked() for each widget, according to obj
|
||||
for(var name in map){
|
||||
var widgets = map[name], // array of widgets w/this name
|
||||
values = dojo.getObject(name, false, obj); // list of values for those widgets
|
||||
if(!dojo.isArray(values)){
|
||||
values = [ values ];
|
||||
}
|
||||
if(widgets[0].setChecked){
|
||||
// for checkbox/radio, values is a list of which widgets should be checked
|
||||
dojo.forEach(widgets, function(w, i){
|
||||
w.setChecked(dojo.indexOf(values, w.value) != -1);
|
||||
});
|
||||
}else{
|
||||
// otherwise, values is a list of values to be assigned sequentially to each widget
|
||||
dojo.forEach(widgets, function(w, i){
|
||||
w.setValue(values[i]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* TODO: code for plain input boxes (this shouldn't run for inputs that are part of widgets
|
||||
|
||||
dojo.forEach(this.containerNode.elements, function(element){
|
||||
if (element.name == ''){return}; // like "continue"
|
||||
var namePath = element.name.split(".");
|
||||
var myObj=obj;
|
||||
var name=namePath[namePath.length-1];
|
||||
for(var j=1,len2=namePath.length;j<len2;++j) {
|
||||
var p=namePath[j - 1];
|
||||
// repeater support block
|
||||
var nameA=p.split("[");
|
||||
if (nameA.length > 1) {
|
||||
if(typeof(myObj[nameA[0]]) == "undefined") {
|
||||
myObj[nameA[0]]=[ ];
|
||||
} // if
|
||||
|
||||
nameIndex=parseInt(nameA[1]);
|
||||
if(typeof(myObj[nameA[0]][nameIndex]) == "undefined") {
|
||||
myObj[nameA[0]][nameIndex]={};
|
||||
}
|
||||
myObj=myObj[nameA[0]][nameIndex];
|
||||
continue;
|
||||
} // repeater support ends
|
||||
|
||||
if(typeof(myObj[p]) == "undefined") {
|
||||
myObj=undefined;
|
||||
break;
|
||||
};
|
||||
myObj=myObj[p];
|
||||
}
|
||||
|
||||
if (typeof(myObj) == "undefined") {
|
||||
return; // like "continue"
|
||||
}
|
||||
if (typeof(myObj[name]) == "undefined" && this.ignoreNullValues) {
|
||||
return; // like "continue"
|
||||
}
|
||||
|
||||
// TODO: widget values (just call setValue() on the widget)
|
||||
|
||||
switch(element.type) {
|
||||
case "checkbox":
|
||||
element.checked = (name in myObj) &&
|
||||
dojo.some(myObj[name], function(val){ return val==element.value; });
|
||||
break;
|
||||
case "radio":
|
||||
element.checked = (name in myObj) && myObj[name]==element.value;
|
||||
break;
|
||||
case "select-multiple":
|
||||
element.selectedIndex=-1;
|
||||
dojo.forEach(element.options, function(option){
|
||||
option.selected = dojo.some(myObj[name], function(val){ return option.value == val; });
|
||||
});
|
||||
break;
|
||||
case "select-one":
|
||||
element.selectedIndex="0";
|
||||
dojo.forEach(element.options, function(option){
|
||||
option.selected = option.value == myObj[name];
|
||||
});
|
||||
break;
|
||||
case "hidden":
|
||||
case "text":
|
||||
case "textarea":
|
||||
case "password":
|
||||
element.value = myObj[name] || "";
|
||||
break;
|
||||
}
|
||||
});
|
||||
*/
|
||||
},
|
||||
|
||||
getValues: function() {
|
||||
// summary: generate JSON structure from form values
|
||||
|
||||
// get widget values
|
||||
var obj = {};
|
||||
dojo.forEach(this.getDescendants(), function(widget){
|
||||
var value = widget.getValue ? widget.getValue() : widget.value;
|
||||
var name = widget.name;
|
||||
if(!name){ return; }
|
||||
|
||||
// Store widget's value(s) as a scalar, except for checkboxes which are automatically arrays
|
||||
if(widget.setChecked){
|
||||
if(/Radio/.test(widget.declaredClass)){
|
||||
// radio button
|
||||
if(widget.checked){
|
||||
dojo.setObject(name, value, obj);
|
||||
}
|
||||
}else{
|
||||
// checkbox/toggle button
|
||||
var ary=dojo.getObject(name, false, obj);
|
||||
if(!ary){
|
||||
ary=[];
|
||||
dojo.setObject(name, ary, obj);
|
||||
}
|
||||
if(widget.checked){
|
||||
ary.push(value);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
// plain input
|
||||
dojo.setObject(name, value, obj);
|
||||
}
|
||||
});
|
||||
|
||||
/***
|
||||
* code for plain input boxes (see also dojo.formToObject, can we use that instead of this code?
|
||||
* but it doesn't understand [] notation, presumably)
|
||||
var obj = { };
|
||||
dojo.forEach(this.containerNode.elements, function(elm){
|
||||
if (!elm.name) {
|
||||
return; // like "continue"
|
||||
}
|
||||
var namePath = elm.name.split(".");
|
||||
var myObj=obj;
|
||||
var name=namePath[namePath.length-1];
|
||||
for(var j=1,len2=namePath.length;j<len2;++j) {
|
||||
var nameIndex = null;
|
||||
var p=namePath[j - 1];
|
||||
var nameA=p.split("[");
|
||||
if (nameA.length > 1) {
|
||||
if(typeof(myObj[nameA[0]]) == "undefined") {
|
||||
myObj[nameA[0]]=[ ];
|
||||
} // if
|
||||
nameIndex=parseInt(nameA[1]);
|
||||
if(typeof(myObj[nameA[0]][nameIndex]) == "undefined") {
|
||||
myObj[nameA[0]][nameIndex]={};
|
||||
}
|
||||
} else if(typeof(myObj[nameA[0]]) == "undefined") {
|
||||
myObj[nameA[0]]={}
|
||||
} // if
|
||||
|
||||
if (nameA.length == 1) {
|
||||
myObj=myObj[nameA[0]];
|
||||
} else {
|
||||
myObj=myObj[nameA[0]][nameIndex];
|
||||
} // if
|
||||
} // for
|
||||
|
||||
if ((elm.type != "select-multiple" && elm.type != "checkbox" && elm.type != "radio") || (elm.type=="radio" && elm.checked)) {
|
||||
if(name == name.split("[")[0]) {
|
||||
myObj[name]=elm.value;
|
||||
} else {
|
||||
// can not set value when there is no name
|
||||
}
|
||||
} else if (elm.type == "checkbox" && elm.checked) {
|
||||
if(typeof(myObj[name]) == 'undefined') {
|
||||
myObj[name]=[ ];
|
||||
}
|
||||
myObj[name].push(elm.value);
|
||||
} else if (elm.type == "select-multiple") {
|
||||
if(typeof(myObj[name]) == 'undefined') {
|
||||
myObj[name]=[ ];
|
||||
}
|
||||
for (var jdx=0,len3=elm.options.length; jdx<len3; ++jdx) {
|
||||
if (elm.options[jdx].selected) {
|
||||
myObj[name].push(elm.options[jdx].value);
|
||||
}
|
||||
}
|
||||
} // if
|
||||
name=undefined;
|
||||
}); // forEach
|
||||
***/
|
||||
return obj;
|
||||
},
|
||||
|
||||
isValid: function() {
|
||||
// TODO: ComboBox might need time to process a recently input value. This should be async?
|
||||
// make sure that every widget that has a validator function returns true
|
||||
return dojo.every(this.getDescendants(), function(widget){
|
||||
return !widget.isValid || widget.isValid();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
dojo.declare(
|
||||
"dijit.form.Form",
|
||||
[dijit._Widget, dijit._Templated, dijit.form._FormMixin],
|
||||
null
|
||||
);
|
||||
|
||||
}
|
||||
289
spring-faces/src/main/java/META-INF/dijit/form/InlineEditBox.js
Normal file
289
spring-faces/src/main/java/META-INF/dijit/form/InlineEditBox.js
Normal file
@@ -0,0 +1,289 @@
|
||||
if(!dojo._hasResource["dijit.form.InlineEditBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.form.InlineEditBox"] = true;
|
||||
dojo.provide("dijit.form.InlineEditBox");
|
||||
|
||||
dojo.require("dojo.i18n");
|
||||
|
||||
dojo.require("dijit.form._FormWidget");
|
||||
dojo.require("dijit._Container");
|
||||
dojo.require("dijit.form.Button");
|
||||
|
||||
dojo.requireLocalization("dijit", "common", null, "ROOT,de");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.form.InlineEditBox",
|
||||
[dijit.form._FormWidget, dijit._Container],
|
||||
// summary
|
||||
// Wrapper widget to a text edit widget.
|
||||
// The text is displayed on the page using normal user-styling.
|
||||
// When clicked, the text is hidden, and the edit widget is
|
||||
// visible, allowing the text to be updated. Optionally,
|
||||
// Save and Cancel button are displayed below the edit widget.
|
||||
// When Save is clicked, the text is pulled from the edit
|
||||
// widget and redisplayed and the edit widget is again hidden.
|
||||
// Currently all textboxes that inherit from dijit.form.TextBox
|
||||
// are supported edit widgets.
|
||||
// An edit widget must support the following API to be used:
|
||||
// String getTextValue() OR String getValue()
|
||||
// void setTextValue(String) OR void setValue(String)
|
||||
// void focus()
|
||||
// It must also be able to initialize with style="display:none;" set.
|
||||
{
|
||||
templateString:"<span\n\t><span class='dijitInlineValue' tabIndex=\"0\" dojoAttachPoint=\"editable,focusNode\" style=\"\" waiRole=\"button\"\n\t\tdojoAttachEvent=\"onkeypress:_onKeyPress,onclick:_onClick,onmouseout:_onMouseOut,onmouseover:_onMouseOver,onfocus:_onMouseOver,onblur:_onMouseOut\"></span\n\t><fieldset style=\"display:none;\" dojoAttachPoint=\"editNode\" class=\"dijitInlineEditor\"\n\t\t><div dojoAttachPoint=\"containerNode\" dojoAttachEvent=\"onkeypress:_onEditWidgetKeyPress\"></div\n\t\t><span dojoAttachPoint=\"buttonSpan\"\n\t\t\t><button class='saveButton' dojoAttachPoint=\"saveButton\" dojoType=\"dijit.form.Button\" dojoAttachEvent=\"onClick:save\">${buttonSave}</button\n\t\t\t><button class='cancelButton' dojoAttachPoint=\"cancelButton\" dojoType=\"dijit.form.Button\" dojoAttachEvent=\"onClick:cancel\">${buttonCancel}</button\n\t\t</span\n\t></fieldset\n></span>\n",
|
||||
|
||||
// editing: Boolean
|
||||
// Is the node currently in edit mode?
|
||||
editing: false,
|
||||
|
||||
// autoSave: Boolean
|
||||
// Changing the value automatically saves it, don't have to push save button
|
||||
autoSave: true,
|
||||
|
||||
// buttonSave: String
|
||||
// Save button label
|
||||
buttonSave: "",
|
||||
|
||||
// buttonCancel: String
|
||||
// Cancel button label
|
||||
buttonCancel: "",
|
||||
|
||||
// renderAsHtml: Boolean
|
||||
// should text render as HTML(true) or plain text(false)
|
||||
renderAsHtml: false,
|
||||
|
||||
widgetsInTemplate: true,
|
||||
|
||||
// _display: String
|
||||
// srcNodeRef display style
|
||||
_display:"",
|
||||
|
||||
startup: function(){
|
||||
// look for the input widget as a child of the containerNode
|
||||
if(!this._started){
|
||||
|
||||
if(this.editWidget){
|
||||
this.containerNode.appendChild(this.editWidget.domNode);
|
||||
}else{
|
||||
this.editWidget = this.getChildren()[0];
|
||||
}
|
||||
// #3209: copy the style from the source
|
||||
// don't copy ALL properties though, just the necessary/applicable ones
|
||||
dojo.forEach(["fontSize","fontFamily","fontWeight"], function(prop){
|
||||
this.editWidget.focusNode.style[prop]=this._srcStyle[prop];
|
||||
this.editable.style[prop]=this._srcStyle[prop];
|
||||
}, this);
|
||||
this._setEditValue = dojo.hitch(this.editWidget,this.editWidget.setDisplayedValue||this.editWidget.setValue);
|
||||
this._getEditValue = dojo.hitch(this.editWidget,this.editWidget.getDisplayedValue||this.editWidget.getValue);
|
||||
this._setEditFocus = dojo.hitch(this.editWidget,this.editWidget.focus);
|
||||
this.editWidget.onChange = dojo.hitch(this, "_onChange");
|
||||
|
||||
if(!this.autoSave){ // take over the setValue method so we can know when the value changes
|
||||
this._oldSetValue = this.editWidget.setValue;
|
||||
var _this = this;
|
||||
this.editWidget.setValue = dojo.hitch(this, function(value){
|
||||
_this._oldSetValue.apply(_this.editWidget, arguments);
|
||||
_this._onEditWidgetKeyPress(null); // check the Save button
|
||||
});
|
||||
}
|
||||
this._showText();
|
||||
|
||||
this._started = true;
|
||||
}
|
||||
},
|
||||
|
||||
postCreate: function(){
|
||||
if(this.autoSave){
|
||||
this.buttonSpan.style.display="none";
|
||||
}
|
||||
},
|
||||
|
||||
postMixInProperties: function(){
|
||||
this._srcStyle=dojo.getComputedStyle(this.srcNodeRef);
|
||||
// getComputedStyle is not good until after onLoad is called
|
||||
var srcNodeStyle = this.srcNodeRef.style;
|
||||
this._display="";
|
||||
if(srcNodeStyle && srcNodeStyle.display){ this._display=srcNodeStyle.display; }
|
||||
dijit.form.InlineEditBox.superclass.postMixInProperties.apply(this, arguments);
|
||||
this.messages = dojo.i18n.getLocalization("dijit", "common", this.lang);
|
||||
dojo.forEach(["buttonSave", "buttonCancel"], function(prop){
|
||||
if(!this[prop]){ this[prop] = this.messages[prop]; }
|
||||
}, this);
|
||||
},
|
||||
|
||||
_onKeyPress: function(e){
|
||||
// summary: handle keypress when edit box is not open
|
||||
if(this.disabled || e.altKey || e.ctrlKey){ return; }
|
||||
if(e.charCode == dojo.keys.SPACE || e.keyCode == dojo.keys.ENTER){
|
||||
dojo.stopEvent(e);
|
||||
this._onClick(e);
|
||||
}
|
||||
},
|
||||
|
||||
_onMouseOver: function(){
|
||||
if(!this.editing){
|
||||
var classname = this.disabled ? "dijitDisabledClickableRegion" : "dijitClickableRegion";
|
||||
dojo.addClass(this.editable, classname);
|
||||
}
|
||||
},
|
||||
|
||||
_onMouseOut: function(){
|
||||
if(!this.editing){
|
||||
var classStr = this.disabled ? "dijitDisabledClickableRegion" : "dijitClickableRegion";
|
||||
dojo.removeClass(this.editable, classStr);
|
||||
}
|
||||
},
|
||||
|
||||
_onClick: function(e){
|
||||
// summary
|
||||
// When user clicks the text, then start editing.
|
||||
// Hide the text and display the form instead.
|
||||
|
||||
if(this.editing || this.disabled){ return; }
|
||||
this._onMouseOut();
|
||||
this.editing = true;
|
||||
|
||||
// show the edit form and hide the read only version of the text
|
||||
this._setEditValue(this._isEmpty ? '' : (this.renderAsHtml ? this.editable.innerHTML : this.editable.innerHTML.replace(/\s*\r?\n\s*/g,"").replace(/<br\/?>/gi, "\n").replace(/>/g,">").replace(/</g,"<").replace(/&/g,"&")));
|
||||
this._initialText = this._getEditValue();
|
||||
this._visualize();
|
||||
// Before changing the focus, give the browser time to render.
|
||||
setTimeout(dojo.hitch(this, function(){
|
||||
this._setEditFocus();
|
||||
this.saveButton.setDisabled(true);
|
||||
}), 1);
|
||||
},
|
||||
|
||||
_visualize: function(){
|
||||
dojo.style(this.editNode, "display", this.editing ? this._display : "none");
|
||||
// #3749: try to set focus now to fix missing caret
|
||||
// #3997: call right before this.editable disappears
|
||||
if(this.editing){this._setEditFocus();}
|
||||
dojo.style(this.editable, "display", this.editing ? "none" : this._display);
|
||||
},
|
||||
|
||||
_showText: function(){
|
||||
var value = "" + this._getEditValue(); // "" is to make sure its a string
|
||||
dijit.form.InlineEditBox.superclass.setValue.call(this, value);
|
||||
// whitespace is really hard to click so show a ?
|
||||
// TODO: show user defined message in gray
|
||||
if(/^\s*$/.test(value)){ value = "?"; this._isEmpty = true; }
|
||||
else { this._isEmpty = false; }
|
||||
if(this.renderAsHtml){
|
||||
this.editable.innerHTML = value;
|
||||
}else{
|
||||
this.editable.innerHTML = "";
|
||||
if(value.split){
|
||||
var _this=this;
|
||||
var isFirst = true;
|
||||
dojo.forEach(value.split("\n"), function(line){
|
||||
if(isFirst){ isFirst = false; }
|
||||
else {
|
||||
_this.editable.appendChild(document.createElement("BR")); // preserve line breaks
|
||||
}
|
||||
_this.editable.appendChild(document.createTextNode(line)); // use text nodes so that imbedded tags can be edited
|
||||
});
|
||||
}else{
|
||||
this.editable.appendChild(document.createTextNode(value));
|
||||
}
|
||||
}
|
||||
this._visualize();
|
||||
},
|
||||
|
||||
save: function(e){
|
||||
// summary: Callback when user presses "Save" button or it's simulated.
|
||||
// e is passed in if click on save button or user presses Enter. It's not
|
||||
// passed in when called by _onBlur.
|
||||
if(e){ dojo.stopEvent(e); }
|
||||
this.editing = false;
|
||||
this._showText();
|
||||
// If save button pressed on non-autoSave widget or Enter pressed on autoSave
|
||||
// widget, restore focus to the inline text.
|
||||
if(e){ dijit.focus(this.focusNode); }
|
||||
|
||||
if(this._lastValue != this._lastValueReported){
|
||||
this.onChange(this._lastValue); // tell the world that we have changed
|
||||
}
|
||||
},
|
||||
|
||||
cancel: function(e){
|
||||
// summary: Callback when user presses "Cancel" button or it's simulated.
|
||||
// e is passed in if click on cancel button or user presses Esc. It's not
|
||||
// passed in when called by _onBlur.
|
||||
if(e){ dojo.stopEvent(e); }
|
||||
this.editing = false;
|
||||
this._visualize();
|
||||
// If cancel button pressed on non-autoSave widget or Esc pressed on autoSave
|
||||
// widget, restore focus to the inline text.
|
||||
if(e){ dijit.focus(this.focusNode); }
|
||||
},
|
||||
|
||||
setValue: function(/*String*/ value){
|
||||
// sets the text without informing the server
|
||||
this._setEditValue(value);
|
||||
this.editing = false;
|
||||
this._showText();
|
||||
},
|
||||
|
||||
_onEditWidgetKeyPress: function(e){
|
||||
// summary:
|
||||
// Callback when keypress in the edit box (see template).
|
||||
// For autoSave widgets, if Esc/Enter, call cancel/save.
|
||||
// For non-autoSave widgets, enable save button if the text value is
|
||||
// different than the original value.
|
||||
if(!this.editing){ return; }
|
||||
if(this.autoSave){
|
||||
// If Enter/Esc pressed, treat as save/cancel.
|
||||
if(e.keyCode == dojo.keys.ESCAPE){
|
||||
this.cancel(e);
|
||||
}else if(e.keyCode == dojo.keys.ENTER){
|
||||
this.save(e);
|
||||
}
|
||||
}else{
|
||||
var _this = this;
|
||||
setTimeout(
|
||||
function(){
|
||||
_this.saveButton.setDisabled(_this._getEditValue() == _this._initialText); // ignore the tab key
|
||||
}, 100); // the delay gives the browser a chance to update the textarea
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
_onBlur: function(){
|
||||
// summary:
|
||||
// Called by the focus manager in focus.js when focus moves outside of the
|
||||
// InlineEditBox widget (or it's descendants).
|
||||
if(this.autoSave && this.editing){
|
||||
if(this._getEditValue() == this._initialText){
|
||||
this.cancel();
|
||||
}else{
|
||||
this.save();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_onChange: function(){
|
||||
// summary:
|
||||
// This is called when the underlying widget fires an onChange event,
|
||||
// which means that the user has finished entering the value
|
||||
if(!this.editing){
|
||||
this._showText(); // asynchronous update made famous by ComboBox/FilteringSelect
|
||||
}else if(this.autoSave){
|
||||
this.save();
|
||||
}else{
|
||||
// #3752
|
||||
// if the keypress does not bubble up to the div, (iframe in TextArea blocks it for example)
|
||||
// make sure the save button gets enabled
|
||||
this.saveButton.setDisabled(this._getEditValue() == this._initialText);
|
||||
}
|
||||
},
|
||||
|
||||
setDisabled: function(/*Boolean*/ disabled){
|
||||
this.saveButton.setDisabled(disabled);
|
||||
this.cancelButton.setDisabled(disabled);
|
||||
this.editable.disabled = disabled;
|
||||
this.editWidget.setDisabled(disabled);
|
||||
this.inherited('setDisabled', arguments);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
if(!dojo._hasResource["dijit.form.NumberSpinner"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.form.NumberSpinner"] = true;
|
||||
dojo.provide("dijit.form.NumberSpinner");
|
||||
|
||||
dojo.require("dijit.form._Spinner");
|
||||
dojo.require("dijit.form.NumberTextBox");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.form.NumberSpinner",
|
||||
[dijit.form._Spinner, dijit.form.NumberTextBoxMixin],
|
||||
{
|
||||
// summary: Number Spinner
|
||||
// description: This widget is the same as NumberTextBox but with up/down arrows added
|
||||
|
||||
required: true,
|
||||
|
||||
adjust: function(/* Object */ val, /*Number*/ delta){
|
||||
// summary: change Number val by the given amount
|
||||
var newval = val+delta;
|
||||
if(isNaN(val) || isNaN(newval)){ return val; }
|
||||
if((typeof this.constraints.max == "number") && (newval > this.constraints.max)){
|
||||
newval = this.constraints.max;
|
||||
}
|
||||
if((typeof this.constraints.min == "number") && (newval < this.constraints.min)){
|
||||
newval = this.constraints.min;
|
||||
}
|
||||
return newval;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
if(!dojo._hasResource["dijit.form.NumberTextBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.form.NumberTextBox"] = true;
|
||||
dojo.provide("dijit.form.NumberTextBox");
|
||||
|
||||
dojo.require("dijit.form.ValidationTextBox");
|
||||
dojo.require("dojo.number");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.form.NumberTextBoxMixin",
|
||||
null,
|
||||
{
|
||||
// summary:
|
||||
// A mixin for all number textboxes
|
||||
regExpGen: dojo.number.regexp,
|
||||
format: function(/*Number*/ value, /*Object*/ constraints){
|
||||
if(isNaN(value)){ return null; }
|
||||
return dojo.number.format(value, constraints);
|
||||
},
|
||||
serialize: function(/*Number*/ value){
|
||||
if(isNaN(value)){ return null; }
|
||||
return this.inherited('serialize', arguments);
|
||||
},
|
||||
parse: dojo.number.parse,
|
||||
value: NaN
|
||||
}
|
||||
);
|
||||
|
||||
dojo.declare(
|
||||
"dijit.form.NumberTextBox",
|
||||
[dijit.form.RangeBoundTextBox,dijit.form.NumberTextBoxMixin],
|
||||
{
|
||||
// summary:
|
||||
// A validating, serializable, range-bound text box.
|
||||
// constraints object: min, max, places
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
347
spring-faces/src/main/java/META-INF/dijit/form/Slider.js
Normal file
347
spring-faces/src/main/java/META-INF/dijit/form/Slider.js
Normal file
@@ -0,0 +1,347 @@
|
||||
if(!dojo._hasResource["dijit.form.Slider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.form.Slider"] = true;
|
||||
dojo.provide("dijit.form.Slider");
|
||||
|
||||
dojo.require("dijit.form._FormWidget");
|
||||
dojo.require("dijit._Container");
|
||||
dojo.require("dojo.dnd.move");
|
||||
dojo.require("dijit.form.Button");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.form.HorizontalSlider",
|
||||
[dijit.form._FormWidget, dijit._Container],
|
||||
{
|
||||
// summary
|
||||
// A form widget that allows one to select a value with a horizontally draggable image
|
||||
|
||||
templateString:"<table class=\"dijit dijitReset dijitSlider\" cellspacing=0 cellpadding=0 border=0 rules=none id=\"${id}\"\n\t><tr class=\"dijitReset\"\n\t\t><td class=\"dijitReset\" colspan=2></td\n\t\t><td dojoAttachPoint=\"containerNode,topDecoration\" class=\"dijitReset\" style=\"text-align:center;width:100%;\"></td\n\t\t><td class=\"dijitReset\" colspan=2></td\n\t></tr\n\t><tr class=\"dijitReset\"\n\t\t><td class=\"dijitReset dijitSliderButtonContainer dijitHorizontalSliderButtonContainer\"\n\t\t\t><button dojoType=\"dijit.form.Button\" tabIndex=\"-1\" alt=\"-\" style=\"display:none\" dojoAttachPoint=\"decrementButton\" dojoAttachEvent=\"onClick: decrement\">-</button\n\t\t></td\n\t\t><td class=\"dijitReset\"\n\t\t\t><div class=\"dijitSliderBar dijitSliderBumper dijitHorizontalSliderBumper dijitSliderLeftBumper dijitHorizontalSliderLeftBumper\"></div\n\t\t></td\n\t\t><td class=\"dijitReset\"\n\t\t\t><input dojoAttachPoint=\"valueNode\" name=\"${name}\" type=\"hidden\"\n\t\t\t><div style=\"position:relative;\" dojoAttachPoint=\"sliderBarContainer\"\n\t\t\t\t><div dojoAttachPoint=\"progressBar\" class=\"dijitSliderBar dijitHorizontalSliderBar dijitSliderProgressBar dijitHorizontalSliderProgressBar\" dojoAttachEvent=\"onclick:_onBarClick\"\n\t\t\t\t\t><div tabIndex=\"${tabIndex}\" dojoAttachPoint=\"sliderHandle,focusNode\" class=\"dijitSliderMoveable dijitHorizontalSliderMoveable\" dojoAttachEvent=\"onkeypress:_onKeyPress,onclick:_onHandleClick\" waiRole=\"slider\" valuemin=\"${minimum}\" valuemax=\"${maximum}\"\n\t\t\t\t\t\t><div class=\"dijitSliderImageHandle dijitHorizontalSliderImageHandle\"></div\n\t\t\t\t\t></div\n\t\t\t\t></div\n\t\t\t\t><div dojoAttachPoint=\"remainingBar\" class=\"dijitSliderBar dijitHorizontalSliderBar dijitSliderRemainingBar dijitHorizontalSliderRemainingBar\" dojoAttachEvent=\"onclick:_onBarClick\"></div\n\t\t\t></div\n\t\t></td\n\t\t><td class=\"dijitReset\"\n\t\t\t><div class=\"dijitSliderBar dijitSliderBumper dijitHorizontalSliderBumper dijitSliderRightBumper dijitHorizontalSliderRightBumper\"></div\n\t\t></td\n\t\t><td class=\"dijitReset dijitSliderButtonContainer dijitHorizontalSliderButtonContainer\" style=\"right:0px;\"\n\t\t\t><button dojoType=\"dijit.form.Button\" tabIndex=\"-1\" alt=\"+\" style=\"display:none\" dojoAttachPoint=\"incrementButton\" dojoAttachEvent=\"onClick: increment\">+</button\n\t\t></td\n\t></tr\n\t><tr class=\"dijitReset\"\n\t\t><td class=\"dijitReset\" colspan=2></td\n\t\t><td dojoAttachPoint=\"containerNode,bottomDecoration\" class=\"dijitReset\" style=\"text-align:center;\"></td\n\t\t><td class=\"dijitReset\" colspan=2></td\n\t></tr\n></table>\n",
|
||||
value: 0,
|
||||
|
||||
// showButtons: boolean
|
||||
// Show increment/decrement buttons at the ends of the slider?
|
||||
showButtons: true,
|
||||
|
||||
// minimum:: integer
|
||||
// The minimum value allowed.
|
||||
minimum: 0,
|
||||
|
||||
// maximum: integer
|
||||
// The maximum allowed value.
|
||||
maximum: 100,
|
||||
|
||||
// discreteValues: integer
|
||||
// The maximum allowed values dispersed evenly between minimum and maximum (inclusive).
|
||||
discreteValues: Infinity,
|
||||
|
||||
// pageIncrement: integer
|
||||
// The amount of change with shift+arrow
|
||||
pageIncrement: 2,
|
||||
|
||||
// clickSelect: boolean
|
||||
// If clicking the progress bar changes the value or not
|
||||
clickSelect: true,
|
||||
|
||||
widgetsInTemplate: true,
|
||||
|
||||
_mousePixelCoord: "pageX",
|
||||
_pixelCount: "w",
|
||||
_startingPixelCoord: "x",
|
||||
_startingPixelCount: "l",
|
||||
_handleOffsetCoord: "left",
|
||||
_progressPixelSize: "width",
|
||||
_upsideDown: false,
|
||||
|
||||
setDisabled: function(/*Boolean*/ disabled){
|
||||
if(this.showButtons){
|
||||
this.incrementButton.disabled = disabled;
|
||||
this.decrementButton.disabled = disabled;
|
||||
}
|
||||
dijit.form.HorizontalSlider.superclass.setDisabled.apply(this, arguments);
|
||||
},
|
||||
|
||||
_onKeyPress: function(/*Event*/ e){
|
||||
if(this.disabled || e.altKey || e.ctrlKey){ return; }
|
||||
switch(e.keyCode){
|
||||
case dojo.keys.HOME:
|
||||
this.setValue(this.minimum);
|
||||
break;
|
||||
case dojo.keys.END:
|
||||
this.setValue(this.maximum);
|
||||
break;
|
||||
case dojo.keys.UP_ARROW:
|
||||
case dojo.keys.RIGHT_ARROW:
|
||||
case dojo.keys.PAGE_UP:
|
||||
this.increment(e);
|
||||
break;
|
||||
case dojo.keys.DOWN_ARROW:
|
||||
case dojo.keys.LEFT_ARROW:
|
||||
case dojo.keys.PAGE_DOWN:
|
||||
this.decrement(e);
|
||||
break;
|
||||
default:
|
||||
this.inherited("_onKeyPress", arguments);
|
||||
return;
|
||||
}
|
||||
dojo.stopEvent(e);
|
||||
},
|
||||
|
||||
_onHandleClick: function(e){
|
||||
if(this.disabled){ return; }
|
||||
dijit.focus(this.sliderHandle);
|
||||
dojo.stopEvent(e);
|
||||
},
|
||||
|
||||
_onBarClick: function(e){
|
||||
if(this.disabled || !this.clickSelect){ return; }
|
||||
dojo.stopEvent(e);
|
||||
var abspos = dojo.coords(this.sliderBarContainer, true);
|
||||
var pixelValue = e[this._mousePixelCoord] - abspos[this._startingPixelCoord];
|
||||
this._setPixelValue(this._upsideDown ? (abspos[this._pixelCount] - pixelValue) : pixelValue, abspos[this._pixelCount], true);
|
||||
},
|
||||
|
||||
_setPixelValue: function(/*Number*/ pixelValue, /*Number*/ maxPixels, /*Boolean, optional*/ priorityChange){
|
||||
pixelValue = pixelValue < 0 ? 0 : maxPixels < pixelValue ? maxPixels : pixelValue;
|
||||
var count = this.discreteValues;
|
||||
if(count > maxPixels || count <= 1){ count = maxPixels; }
|
||||
count--;
|
||||
var pixelsPerValue = maxPixels / count;
|
||||
var wholeIncrements = Math.round(pixelValue / pixelsPerValue);
|
||||
this.setValue((this.maximum-this.minimum)*wholeIncrements/count + this.minimum, priorityChange);
|
||||
},
|
||||
|
||||
setValue: function(/*Number*/ value, /*Boolean, optional*/ priorityChange){
|
||||
this.valueNode.value = this.value = value;
|
||||
this.inherited('setValue', arguments);
|
||||
var percent = (value - this.minimum) / (this.maximum - this.minimum);
|
||||
this.progressBar.style[this._progressPixelSize] = (percent*100) + "%";
|
||||
this.remainingBar.style[this._progressPixelSize] = ((1-percent)*100) + "%";
|
||||
},
|
||||
|
||||
_bumpValue: function(signedChange){
|
||||
var s = dojo.getComputedStyle(this.sliderBarContainer);
|
||||
var c = dojo._getContentBox(this.sliderBarContainer, s);
|
||||
var count = this.discreteValues;
|
||||
if(count > c[this._pixelCount] || count <= 1){ count = c[this._pixelCount]; }
|
||||
count--;
|
||||
var value = (this.value - this.minimum) * count / (this.maximum - this.minimum) + signedChange;
|
||||
if(value < 0){ value = 0; }
|
||||
if(value > count){ value = count; }
|
||||
value = value * (this.maximum - this.minimum) / count + this.minimum;
|
||||
this.setValue(value);
|
||||
},
|
||||
|
||||
decrement: function(e){
|
||||
// summary
|
||||
// decrement slider by 1 unit
|
||||
this._bumpValue(e.keyCode == dojo.keys.PAGE_DOWN?-this.pageIncrement:-1);
|
||||
},
|
||||
|
||||
increment: function(e){
|
||||
// summary
|
||||
// increment slider by 1 unit
|
||||
this._bumpValue(e.keyCode == dojo.keys.PAGE_UP?this.pageIncrement:1);
|
||||
},
|
||||
|
||||
_mouseWheeled: function(/*Event*/ evt){
|
||||
dojo.stopEvent(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.increment(evt);
|
||||
}else if(scrollAmount < 0){
|
||||
this.decrement(evt);
|
||||
}
|
||||
},
|
||||
|
||||
startup: function(){
|
||||
dojo.forEach(this.getChildren(), function(child){
|
||||
if(this[child.container] != this.containerNode){
|
||||
this[child.container].appendChild(child.domNode);
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
|
||||
_onBlur: function(){
|
||||
dijit.form.HorizontalSlider.superclass.setValue.call(this, this.value, true);
|
||||
},
|
||||
|
||||
postCreate: function(){
|
||||
if(this.showButtons){
|
||||
this.incrementButton.domNode.style.display="";
|
||||
this.decrementButton.domNode.style.display="";
|
||||
}
|
||||
this.connect(this.domNode, dojo.isIE ? "onmousewheel" : 'DOMMouseScroll', "_mouseWheeled");
|
||||
|
||||
// define a custom constructor for a SliderMover that points back to me
|
||||
var _self = this;
|
||||
var mover = function(node, e){
|
||||
dijit.form._SliderMover.call(this, node, e);
|
||||
this.widget = _self;
|
||||
};
|
||||
dojo.extend(mover, dijit.form._SliderMover.prototype);
|
||||
|
||||
|
||||
this._movable = new dojo.dnd.Moveable(this.sliderHandle, {mover: mover});
|
||||
this.inherited('postCreate', arguments);
|
||||
},
|
||||
|
||||
destroy: function(){
|
||||
this._movable.destroy();
|
||||
dijit.form.HorizontalSlider.superclass.destroy.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
dojo.declare(
|
||||
"dijit.form.VerticalSlider",
|
||||
dijit.form.HorizontalSlider,
|
||||
{
|
||||
// summary
|
||||
// A form widget that allows one to select a value with a vertically draggable image
|
||||
|
||||
templateString:"<table class=\"dijitReset dijitSlider\" cellspacing=0 cellpadding=0 border=0 rules=none id=\"${id}\"\n><tbody class=\"dijitReset\"\n\t><tr class=\"dijitReset\"\n\t\t><td class=\"dijitReset\"></td\n\t\t><td class=\"dijitReset dijitSliderButtonContainer dijitVerticalSliderButtonContainer\"\n\t\t\t><button dojoType=\"dijit.form.Button\" tabIndex=-1 alt=\"+\" style=\"display:none\" dojoAttachPoint=\"incrementButton\" dojoAttachEvent=\"onClick: increment\">+</button\n\t\t></td\n\t\t><td class=\"dijitReset\"></td\n\t></tr\n\t><tr class=\"dijitReset\"\n\t\t><td class=\"dijitReset\"></td\n\t\t><td class=\"dijitReset\"\n\t\t\t><center><div class=\"dijitSliderBar dijitSliderBumper dijitVerticalSliderBumper dijitSliderTopBumper dijitVerticalSliderTopBumper\"></div></center\n\t\t></td\n\t\t><td class=\"dijitReset\"></td\n\t></tr\n\t><tr class=\"dijitReset\"\n\t\t><td dojoAttachPoint=\"leftDecoration\" class=\"dijitReset\" style=\"text-align:center;height:100%;\"></td\n\t\t><td class=\"dijitReset\" style=\"height:100%;\"\n\t\t\t><input dojoAttachPoint=\"valueNode\" type=\"hidden\" name=\"${name}\"\n\t\t\t><center style=\"position:relative;height:100%;\" dojoAttachPoint=\"sliderBarContainer\"\n\t\t\t\t><div dojoAttachPoint=\"remainingBar\" class=\"dijitSliderBar dijitVerticalSliderBar dijitSliderRemainingBar dijitVerticalSliderRemainingBar\" dojoAttachEvent=\"onclick:_onBarClick\"></div\n\t\t\t\t><div dojoAttachPoint=\"progressBar\" class=\"dijitSliderBar dijitVerticalSliderBar dijitSliderProgressBar dijitVerticalSliderProgressBar\" dojoAttachEvent=\"onclick:_onBarClick\"\n\t\t\t\t\t><div tabIndex=\"${tabIndex}\" dojoAttachPoint=\"sliderHandle,focusNode\" class=\"dijitSliderMoveable\" dojoAttachEvent=\"onkeypress:_onKeyPress,onclick:_onHandleClick\" style=\"vertical-align:top;\" waiRole=\"slider\" valuemin=\"${minimum}\" valuemax=\"${maximum}\"\n\t\t\t\t\t\t><div class=\"dijitSliderImageHandle dijitVerticalSliderImageHandle\"></div\n\t\t\t\t\t></div\n\t\t\t\t></div\n\t\t\t></center\n\t\t></td\n\t\t><td dojoAttachPoint=\"containerNode,rightDecoration\" class=\"dijitReset\" style=\"text-align:center;height:100%;\"></td\n\t></tr\n\t><tr class=\"dijitReset\"\n\t\t><td class=\"dijitReset\"></td\n\t\t><td class=\"dijitReset\"\n\t\t\t><center><div class=\"dijitSliderBar dijitSliderBumper dijitVerticalSliderBumper dijitSliderBottomBumper dijitVerticalSliderBottomBumper\"></div></center\n\t\t></td\n\t\t><td class=\"dijitReset\"></td\n\t></tr\n\t><tr class=\"dijitReset\"\n\t\t><td class=\"dijitReset\"></td\n\t\t><td class=\"dijitReset dijitSliderButtonContainer dijitVerticalSliderButtonContainer\"\n\t\t\t><button dojoType=\"dijit.form.Button\" tabIndex=-1 alt=\"-\" style=\"display:none\" dojoAttachPoint=\"decrementButton\" dojoAttachEvent=\"onClick: decrement\">-</button\n\t\t></td\n\t\t><td class=\"dijitReset\"></td\n\t></tr\n></tbody></table>\n",
|
||||
_mousePixelCoord: "pageY",
|
||||
_pixelCount: "h",
|
||||
_startingPixelCoord: "y",
|
||||
_startingPixelCount: "t",
|
||||
_handleOffsetCoord: "top",
|
||||
_progressPixelSize: "height",
|
||||
_upsideDown: true
|
||||
});
|
||||
|
||||
dojo.declare("dijit.form._SliderMover",
|
||||
dojo.dnd.Mover,
|
||||
{
|
||||
onMouseMove: function(e){
|
||||
var widget = this.widget;
|
||||
var c = this.constraintBox;
|
||||
if(!c){
|
||||
var container = widget.sliderBarContainer;
|
||||
var s = dojo.getComputedStyle(container);
|
||||
var c = dojo._getContentBox(container, s);
|
||||
c[widget._startingPixelCount] = 0;
|
||||
this.constraintBox = c;
|
||||
}
|
||||
var m = this.marginBox;
|
||||
var pixelValue = m[widget._startingPixelCount] + e[widget._mousePixelCoord];
|
||||
dojo.hitch(widget, "_setPixelValue")(widget._upsideDown? (c[widget._pixelCount]-pixelValue) : pixelValue, c[widget._pixelCount]);
|
||||
},
|
||||
|
||||
destroy: function(e){
|
||||
var widget = this.widget;
|
||||
widget.setValue(widget.value, true);
|
||||
dojo.dnd.Mover.prototype.destroy.call(this);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
dojo.declare("dijit.form.HorizontalRule", [dijit._Widget, dijit._Templated],
|
||||
{
|
||||
// Summary:
|
||||
// Create hash marks for the Horizontal slider
|
||||
templateString: '<div class="RuleContainer HorizontalRuleContainer"></div>',
|
||||
|
||||
// count: Integer
|
||||
// Number of hash marks to generate
|
||||
count: 3,
|
||||
|
||||
// container: Node
|
||||
// If this is a child widget, connect it to this parent node
|
||||
container: "containerNode",
|
||||
|
||||
// ruleStyle: String
|
||||
// CSS style to apply to individual hash marks
|
||||
ruleStyle: "",
|
||||
|
||||
_positionPrefix: '<div class="RuleMark HorizontalRuleMark" style="left:',
|
||||
_positionSuffix: '%;',
|
||||
_suffix: '"></div>',
|
||||
|
||||
_genHTML: function(pos, ndx){
|
||||
return this._positionPrefix + pos + this._positionSuffix + this.ruleStyle + this._suffix;
|
||||
},
|
||||
|
||||
postCreate: function(){
|
||||
if(this.count==1){
|
||||
var innerHTML = this._genHTML(50, 0);
|
||||
}else{
|
||||
var innerHTML = this._genHTML(0, 0);
|
||||
var interval = 100 / (this.count-1);
|
||||
for(var i=1; i < this.count-1; i++){
|
||||
innerHTML += this._genHTML(interval*i, i);
|
||||
}
|
||||
innerHTML += this._genHTML(100, this.count-1);
|
||||
}
|
||||
this.domNode.innerHTML = innerHTML;
|
||||
}
|
||||
});
|
||||
|
||||
dojo.declare("dijit.form.VerticalRule", dijit.form.HorizontalRule,
|
||||
{
|
||||
// Summary:
|
||||
// Create hash marks for the Vertical slider
|
||||
templateString: '<div class="RuleContainer VerticalRuleContainer"></div>',
|
||||
_positionPrefix: '<div class="RuleMark VerticalRuleMark" style="top:'
|
||||
});
|
||||
|
||||
dojo.declare("dijit.form.HorizontalRuleLabels", dijit.form.HorizontalRule,
|
||||
{
|
||||
// Summary:
|
||||
// Create labels for the Horizontal slider
|
||||
templateString: '<div class="RuleContainer HorizontalRuleContainer"></div>',
|
||||
|
||||
// labelStyle: String
|
||||
// CSS style to apply to individual text labels
|
||||
labelStyle: "",
|
||||
|
||||
// labels: Array
|
||||
// Array of text labels to render - evenly spaced from left-to-right or bottom-to-top
|
||||
labels: [],
|
||||
|
||||
_positionPrefix: '<div class="RuleLabelContainer HorizontalRuleLabelContainer" style="left:',
|
||||
_labelPrefix: '"><span class="RuleLabel HorizontalRuleLabel">',
|
||||
_suffix: '</span></div>',
|
||||
|
||||
_calcPosition: function(pos){
|
||||
return pos;
|
||||
},
|
||||
|
||||
_genHTML: function(pos, ndx){
|
||||
return this._positionPrefix + this._calcPosition(pos) + this._positionSuffix + this.labelStyle + this._labelPrefix + this.labels[ndx] + this._suffix;
|
||||
},
|
||||
|
||||
postMixInProperties: function(){
|
||||
dijit.form.HorizontalRuleLabels.superclass.postMixInProperties.apply(this);
|
||||
if(!this.labels.length){
|
||||
// for markup creation, labels are specified as child elements
|
||||
this.labels = dojo.query("> li", this.srcNodeRef).map(function(node){
|
||||
return String(node.innerHTML);
|
||||
});
|
||||
}
|
||||
this.srcNodeRef.innerHTML="";
|
||||
},
|
||||
|
||||
postCreate: function(){
|
||||
this.count = this.labels.length;
|
||||
dijit.form.HorizontalRuleLabels.superclass.postCreate.apply(this);
|
||||
}
|
||||
});
|
||||
|
||||
dojo.declare("dijit.form.VerticalRuleLabels", dijit.form.HorizontalRuleLabels,
|
||||
{
|
||||
// Summary:
|
||||
// Create labels for the Vertical slider
|
||||
templateString: '<div class="RuleContainer VerticalRuleContainer"></div>',
|
||||
|
||||
_positionPrefix: '<div class="RuleLabelContainer VerticalRuleLabelContainer" style="top:',
|
||||
_labelPrefix: '"><span class="RuleLabel VerticalRuleLabel">',
|
||||
|
||||
_calcPosition: function(pos){
|
||||
return 100-pos;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
129
spring-faces/src/main/java/META-INF/dijit/form/TextBox.js
Normal file
129
spring-faces/src/main/java/META-INF/dijit/form/TextBox.js
Normal file
@@ -0,0 +1,129 @@
|
||||
if(!dojo._hasResource["dijit.form.TextBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.form.TextBox"] = true;
|
||||
dojo.provide("dijit.form.TextBox");
|
||||
|
||||
dojo.require("dijit.form._FormWidget");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.form.TextBox",
|
||||
dijit.form._FormWidget,
|
||||
{
|
||||
// summary:
|
||||
// A generic textbox field.
|
||||
// Serves as a base class to derive more specialized functionality in subclasses.
|
||||
|
||||
// trim: Boolean
|
||||
// Removes leading and trailing whitespace if true. Default is false.
|
||||
trim: false,
|
||||
|
||||
// uppercase: Boolean
|
||||
// Converts all characters to uppercase if true. Default is false.
|
||||
uppercase: false,
|
||||
|
||||
// lowercase: Boolean
|
||||
// Converts all characters to lowercase if true. Default is false.
|
||||
lowercase: false,
|
||||
|
||||
// propercase: Boolean
|
||||
// Converts the first character of each word to uppercase if true.
|
||||
propercase: false,
|
||||
|
||||
// size: String
|
||||
// HTML INPUT tag size declaration.
|
||||
size: "20",
|
||||
|
||||
// maxlength: String
|
||||
// HTML INPUT tag maxlength declaration.
|
||||
maxlength: "999999",
|
||||
|
||||
templateString:"<input dojoAttachPoint='textbox,focusNode' dojoAttachEvent='onfocus,onkeyup,onkeypress:_onKeyPress' autocomplete=\"off\"\n\tid='${id}' name='${name}' class=\"dijitInputField\" type='${type}' size='${size}' maxlength='${maxlength}' tabIndex='${tabIndex}'>\n",
|
||||
|
||||
getTextValue: function(){
|
||||
return this.filter(this.textbox.value);
|
||||
},
|
||||
|
||||
getValue: function(){
|
||||
return this.parse(this.getTextValue(), this.constraints);
|
||||
},
|
||||
|
||||
setValue: function(value, /*Boolean, optional*/ priorityChange, /*String, optional*/ formattedValue){
|
||||
if(value == null){ value = ""; }
|
||||
value = this.filter(value);
|
||||
if(typeof formattedValue == "undefined" ){
|
||||
formattedValue = (typeof value == "undefined" || value == null || value == NaN) ? null : this.format(value, this.constraints);
|
||||
}
|
||||
if(formattedValue != null){
|
||||
var _this = this;
|
||||
// synchronous value set needed for InlineEditBox
|
||||
this.textbox.value = formattedValue;
|
||||
}
|
||||
dijit.form.TextBox.superclass.setValue.call(this, value, priorityChange);
|
||||
},
|
||||
|
||||
forWaiValuenow: function(){
|
||||
return this.getTextValue();
|
||||
},
|
||||
|
||||
format: function(/* String */ value, /* Object */ constraints){
|
||||
// summary: Replacable function to convert a value to a properly formatted string
|
||||
return value;
|
||||
},
|
||||
|
||||
parse: function(/* String */ value, /* Object */ constraints){
|
||||
// summary: Replacable function to convert a formatted string to a value
|
||||
return value;
|
||||
},
|
||||
|
||||
postCreate: function(){
|
||||
// get the node for which the background color will be updated
|
||||
if(typeof this.nodeWithBorder != "object"){
|
||||
this.nodeWithBorder = this.textbox;
|
||||
}
|
||||
// setting the value here is needed since value="" in the template causes "undefined"
|
||||
// and setting in the DOM (instead of the JS object) helps with form reset actions
|
||||
this.textbox.setAttribute("value", this.getTextValue());
|
||||
this.inherited('postCreate', arguments);
|
||||
},
|
||||
|
||||
filter: function(val){
|
||||
// summary: Apply various filters to textbox value
|
||||
if(val == null){ return null; }
|
||||
if(this.trim){
|
||||
val = dojo.trim(val);
|
||||
}
|
||||
if(this.uppercase){
|
||||
val = val.toUpperCase();
|
||||
}
|
||||
if(this.lowercase){
|
||||
val = val.toLowerCase();
|
||||
}
|
||||
if(this.propercase){
|
||||
val = val.replace(/[^\s]+/g, function(word){
|
||||
return word.substring(0,1).toUpperCase() + word.substring(1);
|
||||
});
|
||||
}
|
||||
return val;
|
||||
},
|
||||
|
||||
// event handlers, you can over-ride these in your own subclasses
|
||||
// TODO: this should be _onFocus (and onfocus removed from the template)
|
||||
onfocus: function(){
|
||||
dojo.addClass(this.nodeWithBorder, "dijitInputFieldFocused");
|
||||
},
|
||||
|
||||
_onBlur: function(){
|
||||
dojo.removeClass(this.nodeWithBorder, "dijitInputFieldFocused");
|
||||
|
||||
this.setValue(this.getValue(), true);
|
||||
},
|
||||
|
||||
onkeyup: function(){
|
||||
// TODO: it would be nice to massage the value (ie: automatic uppercase, etc) as the user types
|
||||
// but this messes up the cursor position if you are typing into the middle of a word, and
|
||||
// also trimming doesn't work correctly (it prevents spaces between words too!)
|
||||
// this.setValue(this.getValue());
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
220
spring-faces/src/main/java/META-INF/dijit/form/Textarea.js
Normal file
220
spring-faces/src/main/java/META-INF/dijit/form/Textarea.js
Normal file
@@ -0,0 +1,220 @@
|
||||
if(!dojo._hasResource["dijit.form.Textarea"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.form.Textarea"] = true;
|
||||
dojo.provide("dijit.form.Textarea");
|
||||
|
||||
dojo.require("dijit.form._FormWidget");
|
||||
dojo.require("dojo.i18n");
|
||||
dojo.requireLocalization("dijit.form", "Textarea", null, "ROOT");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.form.Textarea",
|
||||
dijit.form._FormWidget,
|
||||
{
|
||||
// summary
|
||||
// A textarea that resizes vertically to contain the data.
|
||||
// Takes nearly all the parameters (name, value, etc.) that a vanilla textarea takes.
|
||||
// Cols is not supported and the width should be specified with style width.
|
||||
// Rows is not supported since this widget adjusts the height.
|
||||
// usage:
|
||||
// <textarea dojoType="dijit.form.TextArea">...</textarea>
|
||||
templateString: (dojo.isIE || dojo.isSafari || dojo.isMozilla) ?
|
||||
((dojo.isIE || dojo.isSafari) ? '<fieldset id="${id}" class="dijitInlineBox dijitInputField dijitTextArea"><div dojoAttachPoint="editNode" waiRole="textarea" tabIndex="${tabIndex}" style="text-decoration:none;_padding-bottom:16px;display:block;overflow:auto;" contentEditable="true"></div>'
|
||||
: '<span id="${id}" class="dijitReset"><iframe dojoAttachPoint="iframe, styleNode" dojoAttachEvent="onblur:_onIframeBlur" src="javascript:void(0)" class="dijitInlineBox dijitInputField dijitTextArea"></iframe>')
|
||||
+ '<textarea name="${name}" value="${value}" dojoAttachPoint="formValueNode" style="display:none;"></textarea>'
|
||||
+ ((dojo.isIE || dojo.isSafari) ? '</fieldset>':'</span>')
|
||||
: '<textarea id="${id}" name="${name}" value="${value}" dojoAttachPoint="formValueNode,editNode" class="dijitInputField dijitTextArea"></textarea>',
|
||||
|
||||
_nlsResources: null, // Needed for screen readers on FF2
|
||||
|
||||
focus: function(){
|
||||
// summary: Received focus, needed for the InlineEditBox widget
|
||||
if(!this.disabled){
|
||||
this._changing(); // set initial height
|
||||
}
|
||||
if(dojo.isMozilla){
|
||||
dijit.focus(this.iframe);
|
||||
}else{
|
||||
dijit.focus(this.focusNode);
|
||||
}
|
||||
},
|
||||
|
||||
setValue: function(/*String*/ value, /*Boolean, optional*/ priorityChange){
|
||||
var editNode = this.editNode;
|
||||
if(typeof value == "string"){
|
||||
editNode.innerHTML = ""; // wipe out old nodes
|
||||
if(value.split){
|
||||
var _this=this;
|
||||
var isFirst = true;
|
||||
dojo.forEach(value.split("\n"), function(line){
|
||||
if(isFirst){ isFirst = false; }
|
||||
else {
|
||||
editNode.appendChild(document.createElement("BR")); // preserve line breaks
|
||||
}
|
||||
editNode.appendChild(document.createTextNode(line)); // use text nodes so that imbedded tags can be edited
|
||||
});
|
||||
}else{
|
||||
editNode.appendChild(document.createTextNode(value));
|
||||
}
|
||||
if(this.iframe){
|
||||
this.sizeNode = document.createElement('div');
|
||||
editNode.appendChild(this.sizeNode);
|
||||
}
|
||||
}else{
|
||||
// blah<BR>blah --> blah\nblah
|
||||
// <P>blah</P><P>blah</P> --> blah\nblah
|
||||
// <DIV>blah</DIV><DIV>blah</DIV> --> blah\nblah
|
||||
// &<> -->&< >
|
||||
value = editNode.innerHTML;
|
||||
if(this.iframe){ // strip sizeNode
|
||||
value = value.replace(/<div><\/div>\r?\n?$/i,"");
|
||||
}
|
||||
value = value.replace(/\s*\r?\n|^\s+|\s+$| /g,"").replace(/>\s+</g,"><").replace(/<\/(p|div)>$|^<(p|div)[^>]*>/gi,"").replace(/([^>])<div>/g,"$1\n").replace(/<\/p>\s*<p[^>]*>|<br[^>]*>/gi,"\n").replace(/<[^>]*>/g,"").replace(/&/gi,"\&").replace(/</gi,"<").replace(/>/gi,">");
|
||||
}
|
||||
this.formValueNode.value = value;
|
||||
if(this.iframe){
|
||||
var newHeight = this.sizeNode.offsetTop;
|
||||
if(editNode.scrollWidth > editNode.clientWidth){ newHeight+=16; } // scrollbar space needed?
|
||||
if(this.lastHeight != newHeight){ // cache size so that we don't get a resize event because of a resize event
|
||||
if(newHeight == 0){ newHeight = 16; } // height = 0 causes the browser to not set scrollHeight
|
||||
dojo.contentBox(this.iframe, {h: newHeight});
|
||||
this.lastHeight = newHeight;
|
||||
}
|
||||
}
|
||||
dijit.form.Textarea.superclass.setValue.call(this, value, priorityChange);
|
||||
},
|
||||
|
||||
getValue: function(){
|
||||
return this.formValueNode.value;
|
||||
},
|
||||
|
||||
postMixInProperties: function(){
|
||||
dijit.form.Textarea.superclass.postMixInProperties.apply(this,arguments);
|
||||
// don't let the source text be converted to a DOM structure since we just want raw text
|
||||
if(this.srcNodeRef && this.srcNodeRef.innerHTML != ""){
|
||||
this.value = this.srcNodeRef.innerHTML;
|
||||
this.srcNodeRef.innerHTML = "";
|
||||
}
|
||||
if((!this.value || this.value == "") && this.srcNodeRef && this.srcNodeRef.value){
|
||||
this.value = this.srcNodeRef.value;
|
||||
}
|
||||
if(!this.value){ this.value = ""; }
|
||||
this.value = this.value.replace(/\r\n/g,"\n").replace(/>/g,">").replace(/</g,"<").replace(/&/g,"&");
|
||||
},
|
||||
|
||||
postCreate: function(){
|
||||
if(dojo.isIE || dojo.isSafari){
|
||||
this.domNode.style.overflowY = 'hidden';
|
||||
this.eventNode = this.focusNode = this.editNode;
|
||||
this.connect(this.eventNode, "oncut", this._changing);
|
||||
this.connect(this.eventNode, "onpaste", this._changing);
|
||||
}else if(dojo.isMozilla){
|
||||
var w = this.iframe.contentWindow;
|
||||
var d = w.document;
|
||||
// In the case of Firefox an iframe is used and when the text gets focus,
|
||||
// focus is fired from the document object. There isn't a way to put a
|
||||
// waiRole on the document object and as a result screen readers don't
|
||||
// announce the role. As a result screen reader users are lost.
|
||||
//
|
||||
// An additional problem is that the browser gives the document object a
|
||||
// very cryptic accessible name, e.g.
|
||||
// wyciwyg://13/http://archive.dojotoolkit.org/nightly/dojotoolkit/dijit/tests/form/test_InlineEditBox.html
|
||||
// When focus is fired from the document object, the screen reader speaks
|
||||
// the accessible name. The cyptic accessile name is confusing.
|
||||
//
|
||||
// A workaround for both of these problems is to give the iframe's
|
||||
// document a title, the name of which is similar to a role name, i.e.
|
||||
// "edit area". This will be used as the accessible name which will replace
|
||||
// the cryptic name and will also convey the role information to the user.
|
||||
// Because it is read directly to the user, the string must be localized.
|
||||
this._nlsResources = dojo.i18n.getLocalization("dijit.form", "Textarea");
|
||||
d.open();
|
||||
d.write('<html><head><title>' +
|
||||
this._nlsResources.iframeTitle1 + // "edit area"
|
||||
'</title></head><body style="margin:0px;padding:0px;border:0px;"></body></html>');
|
||||
// body > br style is to remove the <br> that gets added by FF
|
||||
d.close();
|
||||
this.editNode = d.body;
|
||||
this.iframe.style.overflowY = 'hidden';
|
||||
// resize is a method of window, not document
|
||||
this.eventNode = d;
|
||||
this.focusNode = this.editNode;
|
||||
this.connect(w, "resize", this._changed); // resize is only on the window object
|
||||
}else{
|
||||
this.focusNode = this.domNode;
|
||||
}
|
||||
if(this.eventNode){
|
||||
this.connect(this.eventNode, "keypress", this._onKeyPress);
|
||||
this.connect(this.eventNode, "mousemove", this._changed);
|
||||
this.connect(this.eventNode, "focus", this._focused);
|
||||
this.connect(this.eventNode, "blur", this._blurred);
|
||||
}
|
||||
if(this.editNode){
|
||||
this.connect(this.editNode, "change", this._changed); // needed for mouse paste events per #3479
|
||||
}
|
||||
this.inherited('postCreate', arguments);
|
||||
},
|
||||
|
||||
// event handlers, you can over-ride these in your own subclasses
|
||||
_focused: function(e){
|
||||
dojo.addClass(this.iframe||this.domNode, "dijitInputFieldFocused");
|
||||
this._changed(e);
|
||||
},
|
||||
|
||||
_blurred: function(e){
|
||||
dojo.removeClass(this.iframe||this.domNode, "dijitInputFieldFocused");
|
||||
this._changed(e, true);
|
||||
},
|
||||
|
||||
_onIframeBlur: function(){
|
||||
// Reset the title back to "edit area".
|
||||
this.iframe.contentDocument.title = this._nlsResources.iframeTitle1;
|
||||
},
|
||||
|
||||
_onKeyPress: function(e){
|
||||
if(e.keyCode == dojo.keys.TAB && !e.shiftKey && !e.ctrlKey && !e.altKey && this.iframe){
|
||||
// Pressing the tab key in the iframe (with designMode on) will cause the
|
||||
// entry of a tab character so we have to trap that here. Since we don't
|
||||
// know the next focusable object we put focus on the iframe and then the
|
||||
// user has to press tab again (which then does the expected thing).
|
||||
// A problem with that is that the screen reader user hears "edit area"
|
||||
// announced twice which causes confusion. By setting the
|
||||
// contentDocument's title to "edit area frame" the confusion should be
|
||||
// eliminated.
|
||||
this.iframe.contentDocument.title = this._nlsResources.iframeTitle2;
|
||||
// Place focus on the iframe. A subsequent tab or shift tab will put focus
|
||||
// on the correct control.
|
||||
// Note: Can't use this.focus() because that results in a call to
|
||||
// dijit.focus and if that receives an iframe target it will set focus
|
||||
// on the iframe's contentWindow.
|
||||
this.iframe.focus(); // this.focus(); won't work
|
||||
dojo.stopEvent(e);
|
||||
}else if(e.keyCode == dojo.keys.ENTER){
|
||||
e.stopPropagation();
|
||||
}else if(this.inherited("_onKeyPress", arguments) && this.iframe){
|
||||
// #3752:
|
||||
// The key press will not make it past the iframe.
|
||||
// If a widget is listening outside of the iframe, (like InlineEditBox)
|
||||
// it will not hear anything.
|
||||
// Create an equivalent event so everyone else knows what is going on.
|
||||
var te = document.createEvent("KeyEvents");
|
||||
te.initKeyEvent("keypress", true, true, null, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.keyCode, e.charCode);
|
||||
this.iframe.dispatchEvent(te);
|
||||
}
|
||||
this._changing();
|
||||
},
|
||||
|
||||
_changing: function(e){
|
||||
// summary: event handler for when a change is imminent
|
||||
setTimeout(dojo.hitch(this, "_changed", e, false), 1);
|
||||
},
|
||||
|
||||
_changed: function(e, priorityChange){
|
||||
// summary: event handler for when a change has already happened
|
||||
if(this.iframe && this.iframe.contentDocument.designMode != "on"){
|
||||
this.iframe.contentDocument.designMode="on"; // in case this failed on init due to being hidden
|
||||
}
|
||||
this.setValue(null, priorityChange);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
112
spring-faces/src/main/java/META-INF/dijit/form/TimeTextBox.js
Normal file
112
spring-faces/src/main/java/META-INF/dijit/form/TimeTextBox.js
Normal file
@@ -0,0 +1,112 @@
|
||||
if(!dojo._hasResource["dijit.form.TimeTextBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.form.TimeTextBox"] = true;
|
||||
dojo.provide("dijit.form.TimeTextBox");
|
||||
|
||||
dojo.require("dojo.date");
|
||||
dojo.require("dojo.date.locale");
|
||||
dojo.require("dojo.date.stamp");
|
||||
dojo.require("dijit.form._TimePicker");
|
||||
dojo.require("dijit.form.ValidationTextBox");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.form.TimeTextBox",
|
||||
dijit.form.RangeBoundTextBox,
|
||||
{
|
||||
// summary:
|
||||
// A validating, serializable, range-bound date text box.
|
||||
|
||||
// constraints object: min, max
|
||||
regExpGen: dojo.date.locale.regexp,
|
||||
compare: dojo.date.compare,
|
||||
format: function(/*Date*/ value, /*Object*/ constraints){
|
||||
if(!value || value.toString() == this._invalid){ return null; }
|
||||
return dojo.date.locale.format(value, constraints);
|
||||
},
|
||||
parse: dojo.date.locale.parse,
|
||||
serialize: dojo.date.stamp.toISOString,
|
||||
|
||||
value: new Date(""), // NaN
|
||||
_invalid: (new Date("")).toString(), // NaN
|
||||
|
||||
_popupClass: "dijit.form._TimePicker",
|
||||
|
||||
postMixInProperties: function(){
|
||||
dijit.form.RangeBoundTextBox.prototype.postMixInProperties.apply(this, arguments);
|
||||
|
||||
var constraints = this.constraints;
|
||||
constraints.selector = 'time';
|
||||
if(typeof constraints.min == "string"){ constraints.min = dojo.date.stamp.fromISOString(constraints.min); }
|
||||
if(typeof constraints.max == "string"){ constraints.max = dojo.date.stamp.fromISOString(constraints.max); }
|
||||
},
|
||||
|
||||
_onFocus: function(/*Event*/ evt){
|
||||
// open the calendar
|
||||
this._open();
|
||||
},
|
||||
|
||||
setValue: function(/*Date*/ value, /*Boolean, optional*/ priorityChange){
|
||||
// summary:
|
||||
// Sets the date on this textbox
|
||||
this.inherited('setValue', arguments);
|
||||
if(this._picker){
|
||||
// #3948: fix blank date on popup only
|
||||
if(!value || value.toString() == this._invalid){value=new Date();}
|
||||
this._picker.setValue(value);
|
||||
}
|
||||
},
|
||||
|
||||
_open: function(){
|
||||
// summary:
|
||||
// opens the Calendar, and sets the onValueSelected for the Calendar
|
||||
var self = this;
|
||||
|
||||
if(!this._picker){
|
||||
var popupProto=dojo.getObject(this._popupClass, false);
|
||||
this._picker = new popupProto({
|
||||
onValueSelected: function(value){
|
||||
|
||||
self.focus(); // focus the textbox before the popup closes to avoid reopening the popup
|
||||
setTimeout(dijit.popup.close, 1); // allow focus time to take
|
||||
|
||||
// this will cause InlineEditBox and other handlers to do stuff so make sure it's last
|
||||
dijit.form.TimeTextBox.superclass.setValue.call(self, value, true);
|
||||
},
|
||||
lang: this.lang,
|
||||
constraints:this.constraints,
|
||||
isDisabledDate: function(/*Date*/ date){
|
||||
// summary:
|
||||
// disables dates outside of the min/max of the TimeTextBox
|
||||
return self.constraints && (dojo.date.compare(self.constraints.min,date) > 0 || dojo.date.compare(self.constraints.max,date) < 0);
|
||||
}
|
||||
});
|
||||
this._picker.setValue(this.getValue() || new Date());
|
||||
}
|
||||
if(!this._opened){
|
||||
dijit.popup.open({
|
||||
parent: this,
|
||||
popup: this._picker,
|
||||
around: this.domNode,
|
||||
onClose: function(){ self._opened=false; }
|
||||
});
|
||||
this._opened=true;
|
||||
}
|
||||
},
|
||||
|
||||
_onBlur: function(){
|
||||
// summary: called magically when focus has shifted away from this widget and it's dropdown
|
||||
dijit.popup.closeAll();
|
||||
this.inherited('_onBlur', arguments);
|
||||
// don't focus on <input>. the user has explicitly focused on something else.
|
||||
},
|
||||
|
||||
getDisplayedValue:function(){
|
||||
return this.textbox.value;
|
||||
},
|
||||
|
||||
setDisplayedValue:function(/*String*/ value){
|
||||
this.textbox.value=value;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
if(!dojo._hasResource["dijit.form.ValidationTextBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.form.ValidationTextBox"] = true;
|
||||
dojo.provide("dijit.form.ValidationTextBox");
|
||||
|
||||
dojo.require("dojo.i18n");
|
||||
|
||||
dojo.require("dijit.form.TextBox");
|
||||
dojo.require("dijit.Tooltip");
|
||||
|
||||
dojo.requireLocalization("dijit.form", "validate", null, "zh-cn,ja,it,ROOT,fr,de");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.form.ValidationTextBox",
|
||||
dijit.form.TextBox,
|
||||
{
|
||||
// summary:
|
||||
// A subclass of TextBox.
|
||||
// Over-ride isValid in subclasses to perform specific kinds of validation.
|
||||
|
||||
// default values for new subclass properties
|
||||
// required: Boolean
|
||||
// Can be true or false, default is false.
|
||||
required: false,
|
||||
// promptMessage: String
|
||||
// Hint string
|
||||
promptMessage: "",
|
||||
// invalidMessage: String
|
||||
// The message to display if value is invalid.
|
||||
invalidMessage: "",
|
||||
// constraints: Object
|
||||
// user-defined object needed to pass parameters to the validator functions
|
||||
constraints: {},
|
||||
// regExp: String
|
||||
// regular expression string used to validate the input
|
||||
// Do not specify both regExp and regExpGen
|
||||
regExp: ".*",
|
||||
// regExpGen: Function
|
||||
// user replaceable function used to generate regExp when dependent on constraints
|
||||
// Do not specify both regExp and regExpGen
|
||||
regExpGen: function(constraints){ return this.regExp; },
|
||||
|
||||
setValue: function(){
|
||||
this.inherited('setValue', arguments);
|
||||
this.validate(false);
|
||||
},
|
||||
|
||||
validator: function(value,constraints){
|
||||
// summary: user replaceable function used to validate the text input against the regular expression.
|
||||
return (new RegExp("^(" + this.regExpGen(constraints) + ")"+(this.required?"":"?")+"$")).test(value)&&(!this.required||!this._isEmpty(value));
|
||||
},
|
||||
|
||||
isValid: function(/* Boolean*/ isFocused){
|
||||
// summary: Need to over-ride with your own validation code in subclasses
|
||||
return this.validator(this.textbox.value, this.constraints);
|
||||
},
|
||||
|
||||
_isEmpty: function(value){
|
||||
// summary: Checks for whitespace
|
||||
return /^\s*$/.test(value); // Boolean
|
||||
},
|
||||
|
||||
getErrorMessage: function(/* Boolean*/ isFocused){
|
||||
// summary: return an error message to show if appropriate
|
||||
return this.invalidMessage;
|
||||
},
|
||||
|
||||
getPromptMessage: function(/* Boolean*/ isFocused){
|
||||
// summary: return a hint to show if appropriate
|
||||
return this.promptMessage;
|
||||
},
|
||||
|
||||
validate: function(/* Boolean*/ isFocused){
|
||||
// summary:
|
||||
// Called by oninit, onblur, and onkeypress.
|
||||
// description:
|
||||
// Show missing or invalid messages if appropriate, and highlight textbox field.
|
||||
var message = "";
|
||||
var isValid = this.isValid(isFocused);
|
||||
var className = isValid ? "Normal" : "Error";
|
||||
if(!dojo.hasClass(this.nodeWithBorder, "dijitInputFieldValidation"+className)){
|
||||
dojo.removeClass(this.nodeWithBorder, "dijitInputFieldValidation"+((className=="Normal")?"Error":"Normal"));
|
||||
dojo.addClass(this.nodeWithBorder, "dijitInputFieldValidation"+className);
|
||||
}
|
||||
dijit.wai.setAttr(this.focusNode, "waiState", "invalid", (isValid? "false" : "true"));
|
||||
if(isFocused){
|
||||
if(this._isEmpty(this.textbox.value)){
|
||||
message = this.getPromptMessage(true);
|
||||
}
|
||||
if(!message && !isValid){
|
||||
message = this.getErrorMessage(true);
|
||||
}
|
||||
}
|
||||
this._displayMessage(message);
|
||||
},
|
||||
|
||||
// currently displayed message
|
||||
_message: "",
|
||||
|
||||
_displayMessage: function(/*String*/ message){
|
||||
if(this._message == message){ return; }
|
||||
this._message = message;
|
||||
this.displayMessage(message);
|
||||
},
|
||||
|
||||
displayMessage: function(/*String*/ message){
|
||||
// summary:
|
||||
// User overridable method to display validation errors/hints.
|
||||
// By default uses a tooltip.
|
||||
if(message){
|
||||
dijit.MasterTooltip.show(message, this.domNode);
|
||||
}else{
|
||||
dijit.MasterTooltip.hide();
|
||||
}
|
||||
},
|
||||
|
||||
_onBlur: function(evt){
|
||||
this.validate(false);
|
||||
this.inherited('_onBlur', arguments);
|
||||
},
|
||||
|
||||
onfocus: function(evt){
|
||||
this.inherited('onfocus', arguments);
|
||||
this.validate(true);
|
||||
},
|
||||
|
||||
onkeyup: function(evt){
|
||||
this.onfocus(evt);
|
||||
},
|
||||
|
||||
postMixInProperties: function(){
|
||||
if(this.constraints == dijit.form.ValidationTextBox.prototype.constraints){
|
||||
this.constraints = {};
|
||||
}
|
||||
this.inherited('postMixInProperties', arguments);
|
||||
this.constraints.locale=this.lang;
|
||||
this.messages = dojo.i18n.getLocalization("dijit.form", "validate", this.lang);
|
||||
dojo.forEach(["invalidMessage", "missingMessage"], function(prop){
|
||||
if(!this[prop]){ this[prop] = this.messages[prop]; }
|
||||
}, this);
|
||||
var p = this.regExpGen(this.constraints);
|
||||
this.regExp = p;
|
||||
// make value a string for all types so that form reset works well
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
dojo.declare(
|
||||
"dijit.form.MappedTextBox",
|
||||
dijit.form.ValidationTextBox,
|
||||
{
|
||||
// summary:
|
||||
// A subclass of ValidationTextBox.
|
||||
// Provides a hidden input field and a serialize method to override
|
||||
|
||||
serialize: function(val){
|
||||
// summary: user replaceable function used to convert the getValue() result to a String
|
||||
return val.toString();
|
||||
},
|
||||
|
||||
toString: function(){
|
||||
// summary: display the widget as a printable string using the widget's value
|
||||
var val = this.getValue();
|
||||
return (val!=null) ? ((typeof val == "string") ? val : this.serialize(val, this.constraints)) : "";
|
||||
},
|
||||
|
||||
validate: function(){
|
||||
this.valueNode.value = this.toString();
|
||||
this.inherited('validate', arguments);
|
||||
},
|
||||
|
||||
postCreate: function(){
|
||||
var textbox = this.textbox;
|
||||
var valueNode = (this.valueNode = document.createElement("input"));
|
||||
valueNode.setAttribute("type", textbox.type);
|
||||
valueNode.setAttribute("value", this.toString());
|
||||
dojo.style(valueNode, "display", "none");
|
||||
valueNode.name = this.textbox.name;
|
||||
this.textbox.removeAttribute("name");
|
||||
|
||||
dojo.place(valueNode, textbox, "after");
|
||||
|
||||
this.inherited('postCreate', arguments);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
dojo.declare(
|
||||
"dijit.form.RangeBoundTextBox",
|
||||
dijit.form.MappedTextBox,
|
||||
{
|
||||
// summary:
|
||||
// A subclass of MappedTextBox.
|
||||
// Tests for a value out-of-range
|
||||
/*===== contraints object:
|
||||
// min: Number
|
||||
// Minimum signed value. Default is -Infinity
|
||||
min: undefined,
|
||||
// max: Number
|
||||
// Maximum signed value. Default is +Infinity
|
||||
max: undefined,
|
||||
=====*/
|
||||
|
||||
// rangeMessage: String
|
||||
// The message to display if value is out-of-range
|
||||
rangeMessage: "",
|
||||
|
||||
compare: function(val1, val2){
|
||||
// summary: compare 2 values
|
||||
return val1 - val2;
|
||||
},
|
||||
|
||||
rangeCheck: function(/* Number */ primitive, /* Object */ constraints){
|
||||
// summary: user replaceable function used to validate the range of the numeric input value
|
||||
var isMin = (typeof constraints.min != "undefined");
|
||||
var isMax = (typeof constraints.max != "undefined");
|
||||
if(isMin || isMax){
|
||||
return (!isMin || this.compare(primitive,constraints.min) >= 0) &&
|
||||
(!isMax || this.compare(primitive,constraints.max) <= 0);
|
||||
}else{ return true; }
|
||||
},
|
||||
|
||||
isInRange: function(/* Boolean*/ isFocused){
|
||||
// summary: Need to over-ride with your own validation code in subclasses
|
||||
return this.rangeCheck(this.getValue(), this.constraints);
|
||||
},
|
||||
|
||||
isValid: function(/* Boolean*/ isFocused){
|
||||
return this.inherited('isValid', arguments) &&
|
||||
((this._isEmpty(this.textbox.value) && !this.required) || this.isInRange(isFocused));
|
||||
},
|
||||
|
||||
getErrorMessage: function(/* Boolean*/ isFocused){
|
||||
if(dijit.form.RangeBoundTextBox.superclass.isValid.call(this, false) && !this.isInRange(isFocused)){ return this.rangeMessage; }
|
||||
else{ return this.inherited('getErrorMessage', arguments); }
|
||||
},
|
||||
|
||||
postMixInProperties: function(){
|
||||
this.inherited('postMixInProperties', arguments);
|
||||
if(!this.rangeMessage){
|
||||
this.messages = dojo.i18n.getLocalization("dijit.form", "validate", this.lang);
|
||||
this.rangeMessage = this.messages.rangeMessage;
|
||||
}
|
||||
},
|
||||
|
||||
postCreate: function(){
|
||||
this.inherited('postCreate', arguments);
|
||||
if(typeof this.constraints.min != "undefined"){
|
||||
dijit.wai.setAttr(this.domNode, "waiState", "valuemin", this.constraints.min);
|
||||
}
|
||||
if(typeof this.constraints.max != "undefined"){
|
||||
dijit.wai.setAttr(this.domNode, "waiState", "valuemax", this.constraints.max);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
if(!dojo._hasResource["dijit.form._DropDownTextBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.form._DropDownTextBox"] = true;
|
||||
dojo.provide("dijit.form._DropDownTextBox");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.form._DropDownTextBox",
|
||||
null,
|
||||
{
|
||||
// summary:
|
||||
// Mixin text box with drop down
|
||||
|
||||
templateString:"<table class=\"dijit dijitReset dijitInline dijitLeft\" baseClass=\"${baseClass}\" cellspacing=\"0\" cellpadding=\"0\"\n\tid=\"widget_${id}\" name=\"${name}\" dojoAttachEvent=\"onmouseover:_onMouse,onmouseout:_onMouse\" waiRole=\"presentation\"\n\t><tr\n\t\t><td class='dijitReset dijitStretch dijitComboBoxInput'\n\t\t\t><input class='XdijitInputField' type=\"text\" autocomplete=\"off\" name=\"${name}\"\n\t\t\tdojoAttachEvent=\"onkeypress, onkeyup, onfocus, onblur, compositionend\"\n\t\t\tdojoAttachPoint=\"textbox,focusNode\" id='${id}'\n\t\t\ttabIndex='${tabIndex}' size='${size}' maxlength='${maxlength}'\n\t\t\twaiRole=\"combobox\"\n\t\t></td\n\t\t><td class='dijitReset dijitRight dijitButtonNode dijitDownArrowButton'\n\t\t\tdojoAttachPoint=\"downArrowNode\"\n\t\t\tdojoAttachEvent=\"ondijitclick:_onArrowClick,onmousedown:_onMouse,onmouseup:_onMouse,onmouseover:_onMouse,onmouseout:_onMouse\"\n\t\t><div class=\"dijitDownArrowButtonInner\" waiRole=\"presentation\" tabIndex=\"-1\">\n\t\t\t<div class=\"dijit_a11y dijitDownArrowButtonChar\">▼</div>\n\t\t</div>\n\t</td></tr>\n</table>\n",
|
||||
|
||||
baseClass:"dijitComboBox",
|
||||
|
||||
// hasDownArrow: Boolean
|
||||
// Set this textbox to have a down arrow button
|
||||
// Defaults to true
|
||||
hasDownArrow:true,
|
||||
|
||||
// _popupWidget: Widget
|
||||
// link to the popup widget created by makePopop
|
||||
_popupWidget:null,
|
||||
|
||||
// _hasMasterPopup: Boolean
|
||||
// Flag that determines if this widget should share one popup per widget prototype,
|
||||
// or create one popup per widget instance.
|
||||
// If true, then makePopup() creates one popup per widget prototype.
|
||||
// If false, then makePopup() creates one popup per widget instance.
|
||||
_hasMasterPopup:false,
|
||||
|
||||
// _popupClass: String
|
||||
// Class of master popup (dijit.form._ComboBoxMenu)
|
||||
_popupClass:"",
|
||||
|
||||
// _popupArgs: Object
|
||||
// Object to pass to popup widget on initialization
|
||||
_popupArgs:{},
|
||||
|
||||
// _hasFocus: Boolean
|
||||
// Represents focus state of the textbox
|
||||
_hasFocus:false,
|
||||
|
||||
_arrowPressed: function(){
|
||||
if(!this.disabled&&this.hasDownArrow){
|
||||
dojo.addClass(this.downArrowNode, "dijitArrowButtonActive");
|
||||
}
|
||||
},
|
||||
|
||||
_arrowIdle: function(){
|
||||
if(!this.disabled&&this.hasDownArrow){
|
||||
dojo.removeClass(this.downArrowNode, "dojoArrowButtonPushed");
|
||||
}
|
||||
},
|
||||
|
||||
makePopup: function(){
|
||||
// summary:
|
||||
// create popup widget on demand
|
||||
var _this=this;
|
||||
function _createNewPopup(){
|
||||
// common code from makePopup
|
||||
var node=document.createElement("div");
|
||||
document.body.appendChild(node);
|
||||
var popupProto=dojo.getObject(_this._popupClass, false);
|
||||
return new popupProto(_this._popupArgs, node);
|
||||
}
|
||||
// this code only runs if there is no popup reference
|
||||
if(!this._popupWidget){
|
||||
// does this widget have one "master" popup?
|
||||
if(this._hasMasterPopup){
|
||||
// does the master popup not exist yet?
|
||||
var parentClass = dojo.getObject(this.declaredClass, false);
|
||||
if(!parentClass.prototype._popupWidget){
|
||||
// create the master popup for the first time
|
||||
parentClass.prototype._popupWidget=_createNewPopup();
|
||||
}
|
||||
// assign master popup to local link
|
||||
this._popupWidget=parentClass.prototype._popupWidget;
|
||||
}else{
|
||||
// if master popup is not being used, create one popup per widget instance
|
||||
this._popupWidget=_createNewPopup();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_onArrowClick: function(){
|
||||
// summary: callback when arrow is clicked
|
||||
if(this.disabled){
|
||||
return;
|
||||
}
|
||||
this.focus();
|
||||
this.makePopup();
|
||||
if(this._isShowingNow){
|
||||
this._hideResultList();
|
||||
}else{
|
||||
// forces full population of results, if they click
|
||||
// on the arrow it means they want to see more options
|
||||
this._openResultList();
|
||||
}
|
||||
},
|
||||
|
||||
_hideResultList: function(){
|
||||
if(this._isShowingNow){
|
||||
dijit.popup.close();
|
||||
this._arrowIdle();
|
||||
this._isShowingNow=false;
|
||||
}
|
||||
},
|
||||
|
||||
_openResultList:function(){
|
||||
// summary:
|
||||
// any code that needs to happen before the popup appears.
|
||||
// creating the popupWidget contents etc.
|
||||
this._showResultList();
|
||||
},
|
||||
|
||||
onfocus:function(){
|
||||
this._hasFocus=true;
|
||||
},
|
||||
|
||||
onblur:function(){
|
||||
this._arrowIdle();
|
||||
this._hasFocus=false;
|
||||
// removeClass dijitInputFieldFocused
|
||||
dojo.removeClass(this.nodeWithBorder, "dijitInputFieldFocused");
|
||||
// hide the Tooltip
|
||||
this.validate(false);
|
||||
},
|
||||
|
||||
onkeypress: function(/*Event*/ evt){
|
||||
// summary: generic handler for popup keyboard events
|
||||
if(evt.ctrlKey || evt.altKey){
|
||||
return;
|
||||
}
|
||||
switch(evt.keyCode){
|
||||
case dojo.keys.PAGE_DOWN:
|
||||
case dojo.keys.DOWN_ARROW:
|
||||
if(!this._isShowingNow||this._prev_key_esc){
|
||||
this.makePopup();
|
||||
this._arrowPressed();
|
||||
this._openResultList();
|
||||
}
|
||||
dojo.stopEvent(evt);
|
||||
this._prev_key_backspace = false;
|
||||
this._prev_key_esc = false;
|
||||
break;
|
||||
|
||||
case dojo.keys.PAGE_UP:
|
||||
case dojo.keys.UP_ARROW:
|
||||
case dojo.keys.ENTER:
|
||||
// prevent default actions
|
||||
dojo.stopEvent(evt);
|
||||
// fall through
|
||||
case dojo.keys.ESCAPE:
|
||||
case dojo.keys.TAB:
|
||||
if(this._isShowingNow){
|
||||
this._prev_key_backspace = false;
|
||||
this._prev_key_esc = (evt.keyCode==dojo.keys.ESCAPE);
|
||||
this._hideResultList();
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
compositionend: function(/*Event*/ evt){
|
||||
// summary: When inputting characters using an input method, such as Asian
|
||||
// languages, it will generate this event instead of onKeyDown event
|
||||
this.onkeypress({charCode:-1});
|
||||
},
|
||||
|
||||
_showResultList: function(){
|
||||
// Our dear friend IE doesnt take max-height so we need to calculate that on our own every time
|
||||
this._hideResultList();
|
||||
var childs = this._popupWidget.getListLength ? this._popupWidget.getItems() : [this._popupWidget.domNode];
|
||||
|
||||
if(childs.length){
|
||||
var visibleCount = Math.min(childs.length,this.maxListLength);
|
||||
with(this._popupWidget.domNode.style){
|
||||
// trick to get the dimensions of the popup
|
||||
// TODO: doesn't dijit.popup.open() do this automatically?
|
||||
display="";
|
||||
width="";
|
||||
height="";
|
||||
}
|
||||
this._arrowPressed();
|
||||
// hide the tooltip
|
||||
this._displayMessage("");
|
||||
var best=this.open();
|
||||
// #3212: only set auto scroll bars if necessary
|
||||
// prevents issues with scroll bars appearing when they shouldn't when node is made wider (fractional pixels cause this)
|
||||
var popupbox=dojo.marginBox(this._popupWidget.domNode);
|
||||
this._popupWidget.domNode.style.overflow=((best.h==popupbox.h)&&(best.w==popupbox.w))?"hidden":"auto";
|
||||
dojo.marginBox(this._popupWidget.domNode, {h:best.h,w:Math.max(best.w,this.domNode.offsetWidth)});
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
getDisplayedValue:function(){
|
||||
return this.textbox.value;
|
||||
},
|
||||
|
||||
setDisplayedValue:function(/*String*/ value){
|
||||
this.textbox.value=value;
|
||||
},
|
||||
|
||||
uninitialize:function(){
|
||||
if(this._popupWidget){
|
||||
this._hideResultList();
|
||||
this._popupWidget.destroy()
|
||||
};
|
||||
},
|
||||
|
||||
open:function(){
|
||||
this.makePopup();
|
||||
var self=this;
|
||||
self._isShowingNow=true;
|
||||
return dijit.popup.open({
|
||||
popup: this._popupWidget,
|
||||
around: this.domNode,
|
||||
parent: this
|
||||
});
|
||||
},
|
||||
|
||||
_onBlur: function(){
|
||||
// summary: called magically when focus has shifted away from this widget and it's dropdown
|
||||
this._hideResultList();
|
||||
},
|
||||
|
||||
postMixInProperties:function(){
|
||||
this.baseClass=this.hasDownArrow?this.baseClass:this.baseClass+"NoArrow";
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
240
spring-faces/src/main/java/META-INF/dijit/form/_FormWidget.js
Normal file
240
spring-faces/src/main/java/META-INF/dijit/form/_FormWidget.js
Normal file
@@ -0,0 +1,240 @@
|
||||
if(!dojo._hasResource["dijit.form._FormWidget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.form._FormWidget"] = true;
|
||||
dojo.provide("dijit.form._FormWidget");
|
||||
|
||||
dojo.require("dijit._Widget");
|
||||
dojo.require("dijit._Templated");
|
||||
|
||||
dojo.declare("dijit.form._FormWidget", [dijit._Widget, dijit._Templated],
|
||||
{
|
||||
/*
|
||||
Summary:
|
||||
FormElement widgets correspond to native HTML elements such as <input> or <button> or <select>.
|
||||
Each FormElement represents a single input value, and has a (possibly hidden) <input> element,
|
||||
to which it serializes its input value, so that form submission (either normal submission or via FormBind?)
|
||||
works as expected.
|
||||
|
||||
All these widgets should have these attributes just like native HTML input elements.
|
||||
You can set them during widget construction, but after that they are read only.
|
||||
|
||||
They also share some common methods.
|
||||
*/
|
||||
|
||||
// baseClass: String
|
||||
// Used to add CSS classes like FormElementDisabled
|
||||
// TODO: remove this in favor of this.domNode.baseClass?
|
||||
baseClass: "",
|
||||
|
||||
// value: String
|
||||
// Corresponds to the native HTML <input> element's attribute.
|
||||
value: "",
|
||||
|
||||
// name: String
|
||||
// Name used when submitting form; same as "name" attribute or plain HTML elements
|
||||
name: "",
|
||||
|
||||
// id: String
|
||||
// Corresponds to the native HTML <input> element's attribute.
|
||||
// Also becomes the id for the widget.
|
||||
id: "",
|
||||
|
||||
// alt: String
|
||||
// Corresponds to the native HTML <input> element's attribute.
|
||||
alt: "",
|
||||
|
||||
// type: String
|
||||
// Corresponds to the native HTML <input> element's attribute.
|
||||
type: "text",
|
||||
|
||||
// tabIndex: Integer
|
||||
// Order fields are traversed when user hits the tab key
|
||||
tabIndex: "0",
|
||||
|
||||
// disabled: Boolean
|
||||
// Should this widget respond to user input?
|
||||
// In markup, this is specified as "disabled='disabled'", or just "disabled".
|
||||
disabled: false,
|
||||
|
||||
// intermediateChanges: Boolean
|
||||
// Fires onChange for each value change or only on demand
|
||||
intermediateChanges: false,
|
||||
|
||||
setDisabled: function(/*Boolean*/ disabled){
|
||||
// summary:
|
||||
// Set disabled state of widget.
|
||||
|
||||
this.domNode.disabled = this.disabled = disabled;
|
||||
if(this.focusNode){
|
||||
this.focusNode.disabled = disabled;
|
||||
}
|
||||
if(disabled){
|
||||
//reset those, because after the domNode is disabled, we can no longer receive
|
||||
//mouse related events, see #4200
|
||||
this._hovering = false;
|
||||
this._active = false;
|
||||
}
|
||||
dijit.wai.setAttr(this.focusNode || this.domNode, "waiState", "disabled", disabled);
|
||||
this._setStateClass();
|
||||
},
|
||||
|
||||
|
||||
_onMouse : function(/*Event*/ event){
|
||||
// summary:
|
||||
// Sets _hovering, _active, and baseClass attributes depending on mouse state,
|
||||
// then calls setStateClass() to set appropriate CSS class for this.domNode.
|
||||
//
|
||||
// To get a different CSS class for hover, send onmouseover and onmouseout events to this method.
|
||||
// To get a different CSS class while mouse button is depressed, send onmousedown to this method.
|
||||
|
||||
var mouseNode = event.target;
|
||||
|
||||
if(!this.disabled){
|
||||
switch(event.type){
|
||||
case "mouseover" :
|
||||
this._hovering = true;
|
||||
var baseClass, node=mouseNode;
|
||||
while( node.nodeType===1 && !(baseClass=node.getAttribute("baseClass")) && node != this.domNode ){
|
||||
node=node.parentNode;
|
||||
}
|
||||
this.baseClass= baseClass || "dijit"+this.declaredClass.replace(/.*\./g,"");
|
||||
break;
|
||||
|
||||
case "mouseout" :
|
||||
this._hovering = false;
|
||||
this.baseClass=null;
|
||||
break;
|
||||
|
||||
case "mousedown" :
|
||||
this._active = true;
|
||||
// set a global event to handle mouseup, so it fires properly
|
||||
// even if the cursor leaves the button
|
||||
var self = this;
|
||||
// #2685: use this.connect and disconnect so destroy works properly
|
||||
var mouseUpConnector = this.connect(dojo.body(), "onmouseup", function(){
|
||||
self._active = false;
|
||||
self._setStateClass();
|
||||
self.disconnect(mouseUpConnector);
|
||||
});
|
||||
break;
|
||||
}
|
||||
this._setStateClass();
|
||||
}
|
||||
},
|
||||
|
||||
focus: function(){
|
||||
dijit.focus(this.focusNode);
|
||||
},
|
||||
|
||||
_setStateClass: function(/*String*/ base){
|
||||
// summary:
|
||||
// Update the visual state of the widget by changing the css class on the domnode
|
||||
// according to widget state.
|
||||
//
|
||||
// State will be one of:
|
||||
// <baseClass>
|
||||
// <baseClass> + "Disabled" - if the widget is disabled
|
||||
// <baseClass> + "Active" - if the mouse (or space/enter key?) is being pressed down
|
||||
// <baseClass> + "Hover" - if the mouse is over the widget
|
||||
// <baseClass> + "Focused" - if the widget has focus
|
||||
//
|
||||
// Note: if you don't want to change the way the widget looks on hover, then don't call
|
||||
// this routine on hover. Similarly for mousedown --> active
|
||||
//
|
||||
// For widgets which can be in a checked state (like checkbox or radio),
|
||||
// in addition to the above classes...
|
||||
// <baseClass> + "Checked"
|
||||
// <baseClass> + "CheckedDisabled" - if the widget is disabled
|
||||
// <baseClass> + "CheckedActive" - if the mouse is being pressed down
|
||||
// <baseClass> + "CheckedHover" - if the mouse is over the widget
|
||||
// <baseClass> + "CheckedFocused" - if the widget has focus
|
||||
|
||||
// get original class (non state related) specified in template
|
||||
var origClass = (this.styleNode||this.domNode).className;
|
||||
|
||||
// compute list of classname representing the states of the widget
|
||||
var base = this.baseClass || this.domNode.getAttribute("baseClass") || "dijitFormWidget";
|
||||
origClass = origClass.replace(new RegExp("\\b"+base+"(Checked)?(Selected)?(Disabled|Active|Focused|Hover)?\\b\\s*", "g"), "");
|
||||
var classes = [ base ];
|
||||
|
||||
function multiply(modifier){
|
||||
classes=classes.concat(dojo.map(classes, function(c){ return c+modifier; }));
|
||||
}
|
||||
|
||||
if(this.checked){
|
||||
multiply("Checked");
|
||||
}
|
||||
if(this.selected){
|
||||
multiply("Selected");
|
||||
}
|
||||
|
||||
// Only one of these four can be applied.
|
||||
// Active trumps Focused, Focused trumps Hover, and Disabled trumps all.
|
||||
if(this.disabled){
|
||||
multiply("Disabled");
|
||||
}else if(this._active){
|
||||
multiply("Active");
|
||||
}else if(this._focused){
|
||||
multiply("Focused");
|
||||
}else if(this._hovering){
|
||||
multiply("Hover");
|
||||
}
|
||||
|
||||
(this.styleNode || this.domNode).className = origClass + " " + classes.join(" ");
|
||||
},
|
||||
|
||||
onChange: function(newValue){
|
||||
// summary: callback when value is changed
|
||||
},
|
||||
|
||||
postCreate: function(){
|
||||
this.setValue(this.value, true);
|
||||
this.setDisabled(this.disabled);
|
||||
this._setStateClass();
|
||||
},
|
||||
|
||||
setValue: function(/*anything*/ newValue, /*Boolean, optional*/ priorityChange){
|
||||
// summary: set the value of the widget.
|
||||
this._lastValue = newValue;
|
||||
dijit.wai.setAttr(this.focusNode || this.domNode, "waiState", "valuenow", this.forWaiValuenow());
|
||||
if((this.intermediateChanges || priorityChange) && newValue != this._lastValueReported){
|
||||
this._lastValueReported = newValue;
|
||||
this.onChange(newValue);
|
||||
}
|
||||
},
|
||||
|
||||
getValue: function(){
|
||||
// summary: get the value of the widget.
|
||||
return this._lastValue;
|
||||
},
|
||||
|
||||
undo: function(){
|
||||
// summary: restore the value to the last value passed to onChange
|
||||
this.setValue(this._lastValueReported, false);
|
||||
},
|
||||
|
||||
_onKeyPress: function(e){
|
||||
if(e.keyCode == dojo.keys.ESCAPE && !e.shiftKey && !e.ctrlKey && !e.altKey){
|
||||
var v = this.getValue();
|
||||
var lv = this._lastValueReported;
|
||||
// Equality comparison of objects such as dates are done by reference so
|
||||
// two distinct objects are != even if they have the same data. So use
|
||||
// toStrings in case the values are objects.
|
||||
if(lv != undefined && v.toString() != lv.toString()){
|
||||
this.undo();
|
||||
dojo.stopEvent(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
forWaiValuenow: function(){
|
||||
// summary: returns a value, reflecting the current state of the widget,
|
||||
// to be used for the ARIA valuenow.
|
||||
// This method may be overridden by subclasses that want
|
||||
// to use something other than this.getValue() for valuenow
|
||||
return this.getValue();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
109
spring-faces/src/main/java/META-INF/dijit/form/_Spinner.js
Normal file
109
spring-faces/src/main/java/META-INF/dijit/form/_Spinner.js
Normal file
@@ -0,0 +1,109 @@
|
||||
if(!dojo._hasResource["dijit.form._Spinner"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.form._Spinner"] = true;
|
||||
dojo.provide("dijit.form._Spinner");
|
||||
|
||||
dojo.require("dijit.form.ValidationTextBox");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.form._Spinner",
|
||||
dijit.form.RangeBoundTextBox,
|
||||
{
|
||||
|
||||
// summary: Mixin for validation widgets with a spinner
|
||||
// description: This class basically (conceptually) extends dijit.form.ValidationTextBox.
|
||||
// It modifies the template to have up/down arrows, and provides related handling code.
|
||||
|
||||
// defaultTimeout: Number
|
||||
// number of milliseconds before a held key or button becomes typematic
|
||||
defaultTimeout: 500,
|
||||
|
||||
// timeoutChangeRate: Number
|
||||
// fraction of time used to change the typematic timer between events
|
||||
// 1.0 means that each typematic event fires at defaultTimeout intervals
|
||||
// < 1.0 means that each typematic event fires at an increasing faster rate
|
||||
timeoutChangeRate: 0.90,
|
||||
|
||||
// smallDelta: Number
|
||||
// adjust the value by this much when spinning using the arrow keys/buttons
|
||||
smallDelta: 1,
|
||||
// largeDelta: Number
|
||||
// adjust the value by this much when spinning using the PgUp/Dn keys
|
||||
largeDelta: 10,
|
||||
|
||||
templateString:"<table class=\"dijit dijitReset dijitInline dijitLeft dijitSpinner\" baseClass=\"dijitSpinner\" cellspacing=\"0\" cellpadding=\"0\"\n\tid=\"widget_${id}\" name=\"${name}\"\n\tdojoAttachEvent=\"onmouseover:_onMouse,onmouseout:_onMouse,onkeypress:_onKeyPress\"\n\twaiRole=\"presentation\">\n\t<tr class=\"dijitReset\">\n\t\t<td rowspan=\"2\" class=\"dijitReset dijitStretch dijitSpinnerInput\">\n\t\t\t<input dojoAttachPoint=\"textbox,focusNode\" type=\"${type}\" dojoAttachEvent=\"onfocus,onkeyup\"\n\t\t\t\tvalue=\"${value}\" name=\"${name}\" size=\"${size}\" maxlength=\"${maxlength}\"\n\t\t\t\twaiRole=\"spinbutton\" autocomplete=\"off\" tabIndex=\"${tabIndex}\" id=\"${id}\"\n\t\t\t></td>\n\t\t<td class=\"dijitReset dijitRight dijitButtonNode dijitUpArrowButton\" \n\t\t\t\tdojoAttachPoint=\"upArrowNode\"\n\t\t\t\tdojoAttachEvent=\"onmousedown:_handleUpArrowEvent,onmouseup:_handleUpArrowEvent,onmouseover:_handleUpArrowEvent,onmouseout:_handleUpArrowEvent\"\n\t\t\t\tbaseClass=\"dijitSpinnerUpArrow\"\n\t\t\t><div class=\"dijitA11yUpArrow\" waiRole=\"presentation\" tabIndex=\"-1\">▲</div></td>\n\t</tr><tr class=\"dijitReset\">\n\t\t<td class=\"dijitReset dijitRight dijitButtonNode dijitDownArrowButton\" \n\t\t\t\tdojoAttachPoint=\"downArrowNode\"\n\t\t\t\tdojoAttachEvent=\"onmousedown:_handleDownArrowEvent,onmouseup:_handleDownArrowEvent,onmouseover:_handleDownArrowEvent,onmouseout:_handleDownArrowEvent\"\n\t\t\t\tbaseClass=\"dijitSpinnerDownArrow\"\n\t\t\t><div class=\"dijitA11yDownArrow\" waiRole=\"presentation\" tabIndex=\"-1\">▼</div></td>\n\t</tr>\n</table>\n\n",
|
||||
|
||||
adjust: function(/* Object */ val, /*Number*/ delta){
|
||||
// summary: user replaceable function used to adjust a primitive value(Number/Date/...) by the delta amount specified
|
||||
// the val is adjusted in a way that makes sense to the object type
|
||||
return val;
|
||||
},
|
||||
|
||||
_handleUpArrowEvent : function(/*Event*/ e){
|
||||
this._onMouse(e, this.upArrowNode);
|
||||
},
|
||||
|
||||
_handleDownArrowEvent : function(/*Event*/ e){
|
||||
this._onMouse(e, this.downArrowNode);
|
||||
},
|
||||
|
||||
|
||||
_arrowPressed: function(/*Node*/ nodePressed, /*Number*/ direction){
|
||||
if(this.disabled){ return; }
|
||||
dojo.addClass(nodePressed, "dijitSpinnerButtonActive");
|
||||
this.setValue(this.adjust(this.getValue(), direction*this.smallDelta));
|
||||
},
|
||||
|
||||
_arrowReleased: function(/*Node*/ node){
|
||||
if(this.disabled){ return; }
|
||||
this._wheelTimer = null;
|
||||
dijit.focus(this.textbox);
|
||||
dojo.removeClass(node, "dijitSpinnerButtonActive");
|
||||
},
|
||||
|
||||
_typematicCallback: function(/*Number*/ count, /*DOMNode*/ node, /*Event*/ evt){
|
||||
if(node == this.textbox){ node = (evt.keyCode == dojo.keys.UP_ARROW) ? this.upArrowNode : this.downArrowNode; }
|
||||
if(count == -1){ this._arrowReleased(node); }
|
||||
else{ this._arrowPressed(node, (node == this.upArrowNode) ? 1 : -1); }
|
||||
},
|
||||
|
||||
_wheelTimer: null,
|
||||
_mouseWheeled: function(/*Event*/ evt){
|
||||
dojo.stopEvent(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){
|
||||
var node = this.upArrowNode;
|
||||
var dir = +1;
|
||||
}else if(scrollAmount < 0){
|
||||
var node = this.downArrowNode;
|
||||
var dir = -1;
|
||||
}else{ return; }
|
||||
this._arrowPressed(node, dir);
|
||||
if(this._wheelTimer != null){
|
||||
clearTimeout(this._wheelTimer);
|
||||
}
|
||||
var _this = this;
|
||||
this._wheelTimer = setTimeout(function(){_this._arrowReleased(node);}, 50);
|
||||
},
|
||||
|
||||
postCreate: function(){
|
||||
this.inherited('postCreate', arguments);
|
||||
|
||||
// textbox and domNode get the same style but the css separates the 2 using !important
|
||||
if(this.srcNodeRef){
|
||||
dojo.style(this.textbox, "cssText", this.srcNodeRef.style.cssText);
|
||||
this.textbox.className += " " + this.srcNodeRef.className;
|
||||
}
|
||||
|
||||
// extra listeners
|
||||
this.connect(this.textbox, dojo.isIE ? "onmousewheel" : 'DOMMouseScroll', "_mouseWheeled");
|
||||
dijit.typematic.addListener(this.upArrowNode, this.textbox, {keyCode:dojo.keys.UP_ARROW,ctrlKey:false,altKey:false,shiftKey:false}, this, "_typematicCallback", this.timeoutChangeRate, this.defaultTimeout);
|
||||
dijit.typematic.addListener(this.downArrowNode, this.textbox, {keyCode:dojo.keys.DOWN_ARROW,ctrlKey:false,altKey:false,shiftKey:false}, this, "_typematicCallback", this.timeoutChangeRate, this.defaultTimeout);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
211
spring-faces/src/main/java/META-INF/dijit/form/_TimePicker.js
Normal file
211
spring-faces/src/main/java/META-INF/dijit/form/_TimePicker.js
Normal file
@@ -0,0 +1,211 @@
|
||||
if(!dojo._hasResource["dijit.form._TimePicker"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.form._TimePicker"] = true;
|
||||
dojo.provide("dijit.form._TimePicker");
|
||||
|
||||
dojo.require("dijit.form._FormWidget");
|
||||
dojo.require("dojo.date.locale");
|
||||
|
||||
dojo.declare("dijit.form._TimePicker",
|
||||
[dijit._Widget, dijit._Templated],
|
||||
{
|
||||
// summary:
|
||||
// A graphical time picker that TimeTextBox pops up
|
||||
// It is functionally modeled after the Java applet at http://java.arcadevillage.com/applets/timepica.htm
|
||||
// See ticket #599
|
||||
|
||||
templateString:"<fieldset id=\"widget_${id}\" baseClass=\"dijitTimePicker\" class=\"dijitMenu\"\n><div dojoAttachPoint=\"upArrow\" class=\"dijitButtonNode\">▲</div\n><div dojoAttachPoint=\"timeMenu\" dojoAttachEvent=\"onclick:_onOptionSelected,onmouseover,onmouseout\"\n></div\n><div dojoAttachPoint=\"downArrow\" class=\"dijitButtonNode\">▼</div\n></fieldset>\n",
|
||||
|
||||
// clickableIncrement: String
|
||||
// ISO-8601 string representing the amount by which
|
||||
// every clickable element in the time picker increases
|
||||
// Set in non-Zulu time, without a time zone
|
||||
// Example: "T00:15:00" creates 15 minute increments
|
||||
// Must divide visibleIncrement evenly
|
||||
clickableIncrement: "T00:15:00",
|
||||
|
||||
// visibleIncrement: String
|
||||
// ISO-8601 string representing the amount by which
|
||||
// every element with a visible time in the time picker increases
|
||||
// Set in non Zulu time, without a time zone
|
||||
// Example: "T01:00:00" creates text in every 1 hour increment
|
||||
visibleIncrement: "T01:00:00",
|
||||
|
||||
// visibleRange: String
|
||||
// ISO-8601 string representing the range of this TimePicker
|
||||
// The TimePicker will only display times in this range
|
||||
// Example: "T05:00:00" displays 5 hours of options
|
||||
visibleRange: "T05:00:00",
|
||||
|
||||
// value: String
|
||||
// Date to display.
|
||||
// Defaults to current time and date.
|
||||
// Can be a Date object or an ISO-8601 string
|
||||
// If you specify the GMT time zone ("-01:00"),
|
||||
// the time will be converted to the local time in the local time zone.
|
||||
// Otherwise, the time is considered to be in the local time zone.
|
||||
// If you specify the date and isDate is true, the date is used.
|
||||
// Example: if your local time zone is GMT -05:00,
|
||||
// "T10:00:00" becomes "T10:00:00-05:00" (considered to be local time),
|
||||
// "T10:00:00-01:00" becomes "T06:00:00-05:00" (4 hour difference),
|
||||
// "T10:00:00Z" becomes "T05:00:00-05:00" (5 hour difference between Zulu and local time)
|
||||
// "yyyy-mm-ddThh:mm:ss" is the format to set the date and time
|
||||
// Example: "2007-06-01T09:00:00"
|
||||
value: new Date(),
|
||||
|
||||
_refdate: null,
|
||||
_visibleIncrement:2,
|
||||
_clickableIncrement:1,
|
||||
_totalIncrements:10,
|
||||
constraints:{},
|
||||
|
||||
serialize: dojo.date.stamp.toISOString,
|
||||
|
||||
setValue:function(/*Date*/ date, /*Boolean*/ priority){
|
||||
// summary:
|
||||
// Set the value of the TimePicker
|
||||
// Redraws the TimePicker around the new date
|
||||
//dijit.form._TimePicker.superclass.setValue.apply(this, arguments);
|
||||
this.value=date;
|
||||
this._showText();
|
||||
},
|
||||
|
||||
isDisabledDate: function(/*Date*/dateObject, /*String?*/locale){
|
||||
// summary:
|
||||
// May be overridden to disable certain dates in the TimePicker e.g. isDisabledDate=dojo.date.locale.isWeekend
|
||||
return false; // Boolean
|
||||
},
|
||||
|
||||
_showText:function(){
|
||||
this.timeMenu.innerHTML="";
|
||||
var fromIso = dojo.date.stamp.fromISOString;
|
||||
this._clickableIncrementDate=fromIso(this.clickableIncrement);
|
||||
this._visibleIncrementDate=fromIso(this.visibleIncrement);
|
||||
this._visibleRangeDate=fromIso(this.visibleRange);
|
||||
// get the value of the increments and the range in seconds (since 00:00:00) to find out how many divs to create
|
||||
var clickableIncrementSeconds=this._toSeconds(this._clickableIncrementDate);
|
||||
var visibleIncrementSeconds=this._toSeconds(this._visibleIncrementDate);
|
||||
var visibleRangeSeconds=this._toSeconds(this._visibleRangeDate);
|
||||
|
||||
// round reference date to previous visible increment
|
||||
this._refdate=this._roundTime(this.value, visibleIncrementSeconds);
|
||||
|
||||
// assume clickable increment is the smallest unit
|
||||
this._clickableIncrement=1;
|
||||
// divide the visible range by the clickable increment to get the number of divs to create
|
||||
// example: 10:00:00/00:15:00 -> display 40 divs
|
||||
this._totalIncrements=visibleRangeSeconds/clickableIncrementSeconds;
|
||||
// divide the visible increments by the clickable increments to get how often to display the time inline
|
||||
// example: 01:00:00/00:15:00 -> display the time every 4 divs
|
||||
this._visibleIncrement=visibleIncrementSeconds/clickableIncrementSeconds;
|
||||
for(var i=-this._totalIncrements/2; i<=this._totalIncrements/2; i+=this._clickableIncrement){
|
||||
var div=this._createOption(i);
|
||||
this.timeMenu.appendChild(div);
|
||||
}
|
||||
},
|
||||
|
||||
postCreate:function(){
|
||||
// instantiate constraints
|
||||
if(this.constraints===dijit.form._TimePicker.prototype.constraints){
|
||||
this.constraints={};
|
||||
}
|
||||
// dojo.date.locale needs the lang in the constraints as locale
|
||||
if(!this.constraints.locale){
|
||||
this.constraints.locale=this.lang;
|
||||
}
|
||||
// assign typematic mouse listeners to the arrow buttons
|
||||
dijit.typematic.addMouseListener(this.upArrow,this,this._onArrowUp, 0.8, 500);
|
||||
dijit.typematic.addMouseListener(this.downArrow,this,this._onArrowDown, 0.8, 500);
|
||||
dijit.form._TimePicker.superclass.postCreate.apply(this, arguments);
|
||||
this.setValue(this.value);
|
||||
},
|
||||
|
||||
_roundTime:function(/*Date*/ date, incrementSeconds){
|
||||
// summary:
|
||||
// Return a time that is nearest to the previous clickable increment, as defined by:
|
||||
// new time=old time - oldtime%clickableincrement
|
||||
|
||||
// find the new time in seconds
|
||||
var oldtime=this._toSeconds(date);
|
||||
var newtime=oldtime-oldtime%incrementSeconds;
|
||||
// convert back to a date
|
||||
var newdate=new Date();
|
||||
newdate.setYear(date.getFullYear());
|
||||
newdate.setMonth(date.getMonth());
|
||||
newdate.setDate(date.getDate());
|
||||
newdate.setHours(0);
|
||||
newdate.setMinutes(0);
|
||||
newdate.setSeconds(newtime);
|
||||
console.debug("Time was: "+date+". Rounding UI to: "+newdate);
|
||||
return newdate;
|
||||
},
|
||||
|
||||
_toSeconds:function(/*Date*/ date){
|
||||
// summmary:
|
||||
// Convert a date time to the number of seconds since 00:00:00
|
||||
return date.getHours()*60*60+date.getMinutes()*60+date.getSeconds();
|
||||
},
|
||||
|
||||
_createOption:function(/*Number*/ index){
|
||||
// summary:
|
||||
// creates a clickable time option
|
||||
var div=document.createElement("div");
|
||||
div.date=new Date(this._refdate);
|
||||
div.index=index;
|
||||
div.date.setSeconds(div.date.getSeconds()+this._clickableIncrementDate.getSeconds()*index);
|
||||
div.date.setMinutes(div.date.getMinutes()+this._clickableIncrementDate.getMinutes()*index);
|
||||
div.date.setHours(div.date.getHours()+this._clickableIncrementDate.getHours()*index);
|
||||
if(index%this._visibleIncrement<1&&index%this._visibleIncrement>-1){
|
||||
div.innerHTML=dojo.date.locale.format(div.date, this.constraints);
|
||||
dojo.addClass(div, "dijitTimePickerItem");
|
||||
}else if(index%this._clickableIncrement==0){
|
||||
div.innerHTML=" "
|
||||
dojo.addClass(div, "dijitTimePickerItemSmall");
|
||||
}
|
||||
if(this.isDisabledDate(div.date)){
|
||||
// set disabled
|
||||
dojo.addClass(div, "dijitTimePickerItemDisabled");
|
||||
}
|
||||
return div;
|
||||
},
|
||||
|
||||
_onOptionSelected:function(/*Object*/ tgt){
|
||||
if(!tgt.target.date||this.isDisabledDate(tgt.target.date)){return;}
|
||||
this.setValue(tgt.target.date);
|
||||
this.onValueSelected(tgt.target.date);
|
||||
},
|
||||
|
||||
onValueSelected:function(value){
|
||||
},
|
||||
|
||||
onmouseover:function(/*Event*/ evt){
|
||||
if(evt.target === this.timeMenu){ return; }
|
||||
this._highlighted_option=evt.target;
|
||||
dojo.addClass(evt.target, "dijitMenuItemHover");
|
||||
},
|
||||
|
||||
onmouseout:function(/*Event*/ evt){
|
||||
if(evt.target === this.timeMenu||this._highlighted_option==null){ return; }
|
||||
dojo.removeClass(this._highlighted_option, "dijitMenuItemHover");
|
||||
},
|
||||
|
||||
_onArrowUp:function(){
|
||||
// remove the bottom time and add one to the top
|
||||
// TODO: Typematic
|
||||
var index=this.timeMenu.childNodes[0].index-1;
|
||||
var div=this._createOption(index);
|
||||
this.timeMenu.removeChild(this.timeMenu.childNodes[this.timeMenu.childNodes.length-1]);
|
||||
this.timeMenu.insertBefore(div, this.timeMenu.childNodes[0]);
|
||||
},
|
||||
|
||||
_onArrowDown:function(){
|
||||
// remove the top time and add one to the bottom
|
||||
// TODO: Typematic
|
||||
var index=this.timeMenu.childNodes[this.timeMenu.childNodes.length-1].index+1;
|
||||
var div=this._createOption(index);
|
||||
this.timeMenu.removeChild(this.timeMenu.childNodes[0]);
|
||||
this.timeMenu.appendChild(div);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
({"previousMessage": "Previous choices", "nextMessage": "More choices"})
|
||||
@@ -0,0 +1 @@
|
||||
({"iframeTitle1": "edit area", "iframeTitle2": "edit area frame"})
|
||||
@@ -0,0 +1 @@
|
||||
({"rangeMessage": "* Der Wert liegt außerhalb des gültigen Bereichs.", "invalidMessage": "* Der eingegebene Wert ist ungültig.", "missingMessage": "* Der Wert wird benötigt."})
|
||||
@@ -0,0 +1 @@
|
||||
({"rangeMessage": "* Cette valeur est hors limites.", "invalidMessage": "* La valeur saisie est incorrecte.", "missingMessage": "* Cette valeur est obligatoire."})
|
||||
@@ -0,0 +1 @@
|
||||
({"rangeMessage": "* Questo valore è al di fuori dell'intervallo consentito", "invalidMessage": "* Il valore inserito non è valido.", "missingMessage": "* Questo valore è obbligatorio."})
|
||||
@@ -0,0 +1 @@
|
||||
({"rangeMessage": "* 入力した数値は選択範囲外です。", "invalidMessage": "* 入力したデータに該当するものがありません。", "missingMessage": "* 入力が必須です。"})
|
||||
@@ -0,0 +1 @@
|
||||
({"rangeMessage": "* This value is out of range.", "invalidMessage": "* The value entered is not valid.", "missingMessage": "* This value is required."})
|
||||
@@ -0,0 +1 @@
|
||||
({"rangeMessage": "* 输入数据超出值域。", "invalidMessage": "* 非法的输入值。", "missingMessage": "* 此值是必须的。"})
|
||||
@@ -0,0 +1,9 @@
|
||||
<div class="dijit dijitLeft dijitInline dijitButton" baseClass="${baseClass}"
|
||||
dojoAttachEvent="onclick:_onButtonClick,onmouseover:_onMouse,onmouseout:_onMouse,onmousedown:_onMouse"
|
||||
><div class='dijitRight'
|
||||
><button class="dijitStretch dijitButtonNode dijitButtonContents" dojoAttachPoint="focusNode,titleNode"
|
||||
tabIndex="${tabIndex}" type="${type}" id="${id}" name="${name}" waiRole="button" waiState="labelledby-${id}_label"
|
||||
><div class="dijitInline ${iconClass}"></div
|
||||
><span class="dijitButtonText" id="${id}_label" dojoAttachPoint="containerNode">${label}</span
|
||||
></button
|
||||
></div></div>
|
||||
@@ -0,0 +1,7 @@
|
||||
<span class="${baseClass}" baseClass="${baseClass}"
|
||||
><input
|
||||
id="${id}" tabIndex="${tabIndex}" type="${_type}" name="${name}" value="${value}"
|
||||
class="dijitCheckBoxInput"
|
||||
dojoAttachPoint="inputNode,focusNode"
|
||||
dojoAttachEvent="onmouseover:_onMouse,onmouseout:_onMouse,onclick:onClick"
|
||||
></span>
|
||||
@@ -0,0 +1,18 @@
|
||||
<table class="dijit dijitReset dijitInline dijitLeft" baseClass="${baseClass}" cellspacing="0" cellpadding="0"
|
||||
id="widget_${id}" name="${name}" dojoAttachEvent="onmouseover:_onMouse,onmouseout:_onMouse" waiRole="presentation"
|
||||
><tr
|
||||
><td class='dijitReset dijitStretch dijitComboBoxInput'
|
||||
><input class='XdijitInputField' type="text" autocomplete="off" name="${name}"
|
||||
dojoAttachEvent="onkeypress, onkeyup, onfocus, onblur, compositionend"
|
||||
dojoAttachPoint="textbox,focusNode" id='${id}'
|
||||
tabIndex='${tabIndex}' size='${size}' maxlength='${maxlength}'
|
||||
waiRole="combobox"
|
||||
></td
|
||||
><td class='dijitReset dijitRight dijitButtonNode dijitDownArrowButton'
|
||||
dojoAttachPoint="downArrowNode"
|
||||
dojoAttachEvent="ondijitclick:_onArrowClick,onmousedown:_onMouse,onmouseup:_onMouse,onmouseover:_onMouse,onmouseout:_onMouse"
|
||||
><div class="dijitDownArrowButtonInner" waiRole="presentation" tabIndex="-1">
|
||||
<div class="dijit_a11y dijitDownArrowButtonChar">▼</div>
|
||||
</div>
|
||||
</td></tr>
|
||||
</table>
|
||||
@@ -0,0 +1,21 @@
|
||||
<table class='dijit dijitReset dijitInline dijitLeft dijitComboButton' baseClass='dijitComboButton'
|
||||
id="${id}" name="${name}" cellspacing='0' cellpadding='0'
|
||||
dojoAttachEvent="onmouseover:_onMouse,onmouseout:_onMouse,onmousedown:_onMouse">
|
||||
<tr>
|
||||
<td class="dijitStretch dijitButtonContents dijitButtonNode"
|
||||
tabIndex="${tabIndex}"
|
||||
dojoAttachEvent="ondijitclick:_onButtonClick" dojoAttachPoint="titleNode"
|
||||
waiRole="button" waiState="labelledby-${id}_label">
|
||||
<div class="dijitInline ${iconClass}"></div>
|
||||
<span class="dijitButtonText" id="${id}_label" dojoAttachPoint="containerNode">${label}</span>
|
||||
</td>
|
||||
<td class='dijitReset dijitRight dijitButtonNode dijitDownArrowButton'
|
||||
dojoAttachPoint="popupStateNode,focusNode"
|
||||
dojoAttachEvent="onmouseover:_onMouse,onmouseout:_onMouse,onmousedown:_onMouse,ondijitclick:_onArrowClick, onkeypress:_onKey"
|
||||
baseClass="dijitComboButtonDownArrow"
|
||||
title="${optionsTitle}"
|
||||
tabIndex="${tabIndex}"
|
||||
waiRole="button" waiState="haspopup-true"
|
||||
><div waiRole="presentation">▼</div>
|
||||
</td></tr>
|
||||
</table>
|
||||
@@ -0,0 +1,11 @@
|
||||
<div class="dijit dijitLeft dijitInline dijitDropDownButton" baseClass="dijitDropDownButton"
|
||||
dojoAttachEvent="onmouseover:_onMouse,onmouseout:_onMouse,onmousedown:_onMouse,onclick:_onArrowClick,onkeypress:_onKey"
|
||||
><div class='dijitRight'>
|
||||
<button tabIndex="${tabIndex}" class="dijitStretch dijitButtonNode dijitButtonContents" type="${type}" id="${id}" name="${name}"
|
||||
dojoAttachPoint="focusNode,titleNode" waiRole="button" waiState="haspopup-true,labelledby-${id}_label"
|
||||
><div class="dijitInline ${iconClass}"></div
|
||||
><span class="dijitButtonText" dojoAttachPoint="containerNode,popupStateNode"
|
||||
id="${id}_label">${label}</span
|
||||
><span class='dijitA11yDownArrow'>▼</span>
|
||||
</button>
|
||||
</div></div>
|
||||
@@ -0,0 +1,37 @@
|
||||
<table class="dijit dijitReset dijitSlider" cellspacing=0 cellpadding=0 border=0 rules=none id="${id}"
|
||||
><tr class="dijitReset"
|
||||
><td class="dijitReset" colspan=2></td
|
||||
><td dojoAttachPoint="containerNode,topDecoration" class="dijitReset" style="text-align:center;width:100%;"></td
|
||||
><td class="dijitReset" colspan=2></td
|
||||
></tr
|
||||
><tr class="dijitReset"
|
||||
><td class="dijitReset dijitSliderButtonContainer dijitHorizontalSliderButtonContainer"
|
||||
><button dojoType="dijit.form.Button" tabIndex="-1" alt="-" style="display:none" dojoAttachPoint="decrementButton" dojoAttachEvent="onClick: decrement">-</button
|
||||
></td
|
||||
><td class="dijitReset"
|
||||
><div class="dijitSliderBar dijitSliderBumper dijitHorizontalSliderBumper dijitSliderLeftBumper dijitHorizontalSliderLeftBumper"></div
|
||||
></td
|
||||
><td class="dijitReset"
|
||||
><input dojoAttachPoint="valueNode" name="${name}" type="hidden"
|
||||
><div style="position:relative;" dojoAttachPoint="sliderBarContainer"
|
||||
><div dojoAttachPoint="progressBar" class="dijitSliderBar dijitHorizontalSliderBar dijitSliderProgressBar dijitHorizontalSliderProgressBar" dojoAttachEvent="onclick:_onBarClick"
|
||||
><div tabIndex="${tabIndex}" dojoAttachPoint="sliderHandle,focusNode" class="dijitSliderMoveable dijitHorizontalSliderMoveable" dojoAttachEvent="onkeypress:_onKeyPress,onclick:_onHandleClick" waiRole="slider" valuemin="${minimum}" valuemax="${maximum}"
|
||||
><div class="dijitSliderImageHandle dijitHorizontalSliderImageHandle"></div
|
||||
></div
|
||||
></div
|
||||
><div dojoAttachPoint="remainingBar" class="dijitSliderBar dijitHorizontalSliderBar dijitSliderRemainingBar dijitHorizontalSliderRemainingBar" dojoAttachEvent="onclick:_onBarClick"></div
|
||||
></div
|
||||
></td
|
||||
><td class="dijitReset"
|
||||
><div class="dijitSliderBar dijitSliderBumper dijitHorizontalSliderBumper dijitSliderRightBumper dijitHorizontalSliderRightBumper"></div
|
||||
></td
|
||||
><td class="dijitReset dijitSliderButtonContainer dijitHorizontalSliderButtonContainer" style="right:0px;"
|
||||
><button dojoType="dijit.form.Button" tabIndex="-1" alt="+" style="display:none" dojoAttachPoint="incrementButton" dojoAttachEvent="onClick: increment">+</button
|
||||
></td
|
||||
></tr
|
||||
><tr class="dijitReset"
|
||||
><td class="dijitReset" colspan=2></td
|
||||
><td dojoAttachPoint="containerNode,bottomDecoration" class="dijitReset" style="text-align:center;"></td
|
||||
><td class="dijitReset" colspan=2></td
|
||||
></tr
|
||||
></table>
|
||||
@@ -0,0 +1,11 @@
|
||||
<span
|
||||
><span class='dijitInlineValue' tabIndex="0" dojoAttachPoint="editable,focusNode" style="" waiRole="button"
|
||||
dojoAttachEvent="onkeypress:_onKeyPress,onclick:_onClick,onmouseout:_onMouseOut,onmouseover:_onMouseOver,onfocus:_onMouseOver,onblur:_onMouseOut"></span
|
||||
><fieldset style="display:none;" dojoAttachPoint="editNode" class="dijitInlineEditor"
|
||||
><div dojoAttachPoint="containerNode" dojoAttachEvent="onkeypress:_onEditWidgetKeyPress"></div
|
||||
><span dojoAttachPoint="buttonSpan"
|
||||
><button class='saveButton' dojoAttachPoint="saveButton" dojoType="dijit.form.Button" dojoAttachEvent="onClick:save">${buttonSave}</button
|
||||
><button class='cancelButton' dojoAttachPoint="cancelButton" dojoType="dijit.form.Button" dojoAttachEvent="onClick:cancel">${buttonCancel}</button
|
||||
</span
|
||||
></fieldset
|
||||
></span>
|
||||
@@ -0,0 +1,24 @@
|
||||
<table class="dijit dijitReset dijitInline dijitLeft dijitSpinner" baseClass="dijitSpinner" cellspacing="0" cellpadding="0"
|
||||
id="widget_${id}" name="${name}"
|
||||
dojoAttachEvent="onmouseover:_onMouse,onmouseout:_onMouse,onkeypress:_onKeyPress"
|
||||
waiRole="presentation">
|
||||
<tr class="dijitReset">
|
||||
<td rowspan="2" class="dijitReset dijitStretch dijitSpinnerInput">
|
||||
<input dojoAttachPoint="textbox,focusNode" type="${type}" dojoAttachEvent="onfocus,onkeyup"
|
||||
value="${value}" name="${name}" size="${size}" maxlength="${maxlength}"
|
||||
waiRole="spinbutton" autocomplete="off" tabIndex="${tabIndex}" id="${id}"
|
||||
></td>
|
||||
<td class="dijitReset dijitRight dijitButtonNode dijitUpArrowButton"
|
||||
dojoAttachPoint="upArrowNode"
|
||||
dojoAttachEvent="onmousedown:_handleUpArrowEvent,onmouseup:_handleUpArrowEvent,onmouseover:_handleUpArrowEvent,onmouseout:_handleUpArrowEvent"
|
||||
baseClass="dijitSpinnerUpArrow"
|
||||
><div class="dijitA11yUpArrow" waiRole="presentation" tabIndex="-1">▲</div></td>
|
||||
</tr><tr class="dijitReset">
|
||||
<td class="dijitReset dijitRight dijitButtonNode dijitDownArrowButton"
|
||||
dojoAttachPoint="downArrowNode"
|
||||
dojoAttachEvent="onmousedown:_handleDownArrowEvent,onmouseup:_handleDownArrowEvent,onmouseover:_handleDownArrowEvent,onmouseout:_handleDownArrowEvent"
|
||||
baseClass="dijitSpinnerDownArrow"
|
||||
><div class="dijitA11yDownArrow" waiRole="presentation" tabIndex="-1">▼</div></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
<input dojoAttachPoint='textbox,focusNode' dojoAttachEvent='onfocus,onkeyup,onkeypress:_onKeyPress' autocomplete="off"
|
||||
id='${id}' name='${name}' class="dijitInputField" type='${type}' size='${size}' maxlength='${maxlength}' tabIndex='${tabIndex}'>
|
||||
@@ -0,0 +1,6 @@
|
||||
<fieldset id="widget_${id}" baseClass="dijitTimePicker" class="dijitMenu"
|
||||
><div dojoAttachPoint="upArrow" class="dijitButtonNode">▲</div
|
||||
><div dojoAttachPoint="timeMenu" dojoAttachEvent="onclick:_onOptionSelected,onmouseover,onmouseout"
|
||||
></div
|
||||
><div dojoAttachPoint="downArrow" class="dijitButtonNode">▼</div
|
||||
></fieldset>
|
||||
@@ -0,0 +1,46 @@
|
||||
<table class="dijitReset dijitSlider" cellspacing=0 cellpadding=0 border=0 rules=none id="${id}"
|
||||
><tbody class="dijitReset"
|
||||
><tr class="dijitReset"
|
||||
><td class="dijitReset"></td
|
||||
><td class="dijitReset dijitSliderButtonContainer dijitVerticalSliderButtonContainer"
|
||||
><button dojoType="dijit.form.Button" tabIndex=-1 alt="+" style="display:none" dojoAttachPoint="incrementButton" dojoAttachEvent="onClick: increment">+</button
|
||||
></td
|
||||
><td class="dijitReset"></td
|
||||
></tr
|
||||
><tr class="dijitReset"
|
||||
><td class="dijitReset"></td
|
||||
><td class="dijitReset"
|
||||
><center><div class="dijitSliderBar dijitSliderBumper dijitVerticalSliderBumper dijitSliderTopBumper dijitVerticalSliderTopBumper"></div></center
|
||||
></td
|
||||
><td class="dijitReset"></td
|
||||
></tr
|
||||
><tr class="dijitReset"
|
||||
><td dojoAttachPoint="leftDecoration" class="dijitReset" style="text-align:center;height:100%;"></td
|
||||
><td class="dijitReset" style="height:100%;"
|
||||
><input dojoAttachPoint="valueNode" type="hidden" name="${name}"
|
||||
><center style="position:relative;height:100%;" dojoAttachPoint="sliderBarContainer"
|
||||
><div dojoAttachPoint="remainingBar" class="dijitSliderBar dijitVerticalSliderBar dijitSliderRemainingBar dijitVerticalSliderRemainingBar" dojoAttachEvent="onclick:_onBarClick"></div
|
||||
><div dojoAttachPoint="progressBar" class="dijitSliderBar dijitVerticalSliderBar dijitSliderProgressBar dijitVerticalSliderProgressBar" dojoAttachEvent="onclick:_onBarClick"
|
||||
><div tabIndex="${tabIndex}" dojoAttachPoint="sliderHandle,focusNode" class="dijitSliderMoveable" dojoAttachEvent="onkeypress:_onKeyPress,onclick:_onHandleClick" style="vertical-align:top;" waiRole="slider" valuemin="${minimum}" valuemax="${maximum}"
|
||||
><div class="dijitSliderImageHandle dijitVerticalSliderImageHandle"></div
|
||||
></div
|
||||
></div
|
||||
></center
|
||||
></td
|
||||
><td dojoAttachPoint="containerNode,rightDecoration" class="dijitReset" style="text-align:center;height:100%;"></td
|
||||
></tr
|
||||
><tr class="dijitReset"
|
||||
><td class="dijitReset"></td
|
||||
><td class="dijitReset"
|
||||
><center><div class="dijitSliderBar dijitSliderBumper dijitVerticalSliderBumper dijitSliderBottomBumper dijitVerticalSliderBottomBumper"></div></center
|
||||
></td
|
||||
><td class="dijitReset"></td
|
||||
></tr
|
||||
><tr class="dijitReset"
|
||||
><td class="dijitReset"></td
|
||||
><td class="dijitReset dijitSliderButtonContainer dijitVerticalSliderButtonContainer"
|
||||
><button dojoType="dijit.form.Button" tabIndex=-1 alt="-" style="display:none" dojoAttachPoint="decrementButton" dojoAttachEvent="onClick: decrement">-</button
|
||||
></td
|
||||
><td class="dijitReset"></td
|
||||
></tr
|
||||
></tbody></table>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 43 B |
@@ -0,0 +1,194 @@
|
||||
if(!dojo._hasResource["dijit.layout.AccordionContainer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.layout.AccordionContainer"] = true;
|
||||
dojo.provide("dijit.layout.AccordionContainer");
|
||||
|
||||
dojo.require("dojo.fx");
|
||||
|
||||
dojo.require("dijit._Container");
|
||||
dojo.require("dijit._Templated");
|
||||
dojo.require("dijit.layout.StackContainer");
|
||||
dojo.require("dijit.layout.ContentPane");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.layout.AccordionContainer",
|
||||
dijit.layout.StackContainer,
|
||||
{
|
||||
// summary:
|
||||
// Holds a set of panes where every pane's title is visible, but only one pane's content is visible at a time,
|
||||
// and switching between panes is visualized by sliding the other panes up/down.
|
||||
// usage:
|
||||
// <div dojoType="dijit.layout.AccordionContainer">
|
||||
// <div dojoType="dijit.layout.AccordionPane" title="pane 1">
|
||||
// <div dojoType="dijit.layout.ContentPane">...</div>
|
||||
// </div>
|
||||
// <div dojoType="dijit.layout.AccordionPane" title="pane 2">
|
||||
// <p>This is some text</p>
|
||||
// ...
|
||||
// </div>
|
||||
|
||||
// duration: Integer
|
||||
// Amount of time (in ms) it takes to slide panes
|
||||
duration: 250,
|
||||
|
||||
_verticalSpace: 0,
|
||||
|
||||
postCreate: function(){
|
||||
this.domNode.style.overflow="hidden";
|
||||
dijit.layout.AccordionContainer.superclass.postCreate.apply(this, arguments);
|
||||
},
|
||||
|
||||
startup: function(){
|
||||
if(this._started){ return; }
|
||||
dijit.layout.StackContainer.prototype.startup.apply(this, arguments);
|
||||
if(this.selectedChildWidget){
|
||||
var style = this.selectedChildWidget.containerNode.style;
|
||||
style.display = "";
|
||||
style.overflow = "auto";
|
||||
this.selectedChildWidget._setSelectedState(true);
|
||||
}
|
||||
},
|
||||
|
||||
layout: function(){
|
||||
// summary
|
||||
// Set the height of the open pane based on what room remains
|
||||
// get cumulative height of all the title bars, and figure out which pane is open
|
||||
var totalCollapsedHeight = 0;
|
||||
var openPane = this.selectedChildWidget;
|
||||
dojo.forEach(this.getChildren(), function(child){
|
||||
totalCollapsedHeight += child.getTitleHeight();
|
||||
});
|
||||
var mySize = this._contentBox;
|
||||
this._verticalSpace = (mySize.h - totalCollapsedHeight);
|
||||
if(openPane){
|
||||
openPane.containerNode.style.height = this._verticalSpace + "px";
|
||||
/***
|
||||
TODO: this is wrong. probably you wanted to call resize on the SplitContainer
|
||||
inside the AccordionPane??
|
||||
if(openPane.resize){
|
||||
openPane.resize({h: this._verticalSpace});
|
||||
}
|
||||
***/
|
||||
}
|
||||
},
|
||||
|
||||
_setupChild: function(/*Widget*/ page){
|
||||
// Summary: prepare the given child
|
||||
return page;
|
||||
},
|
||||
|
||||
_transition: function(/*Widget?*/newWidget, /*Widget?*/oldWidget){
|
||||
//TODO: should be able to replace this with calls to slideIn/slideOut
|
||||
var animations = [];
|
||||
var paneHeight = this._verticalSpace;
|
||||
if(newWidget){
|
||||
newWidget.setSelected(true);
|
||||
var newContents = newWidget.containerNode;
|
||||
newContents.style.display = "";
|
||||
|
||||
animations.push(dojo.animateProperty({
|
||||
node: newContents,
|
||||
duration: this.duration,
|
||||
properties: {
|
||||
height: { start: "1", end: paneHeight }
|
||||
},
|
||||
onEnd: function(){
|
||||
newContents.style.overflow = "auto";
|
||||
}
|
||||
}));
|
||||
}
|
||||
if(oldWidget){
|
||||
oldWidget.setSelected(false);
|
||||
var oldContents = oldWidget.containerNode;
|
||||
oldContents.style.overflow = "hidden";
|
||||
animations.push(dojo.animateProperty({
|
||||
node: oldContents,
|
||||
duration: this.duration,
|
||||
properties: {
|
||||
height: { start: paneHeight, end: "1" }
|
||||
},
|
||||
onEnd: function(){
|
||||
oldContents.style.display = "none";
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
dojo.fx.combine(animations).play();
|
||||
},
|
||||
|
||||
// note: we are treating the container as controller here
|
||||
processKey: function(/*Event*/ evt){
|
||||
if(this.disabled || evt.altKey || evt.shiftKey || evt.ctrlKey){
|
||||
return dijit.layout.AccordionContainer.superclass._onKeyPress.apply(this, arguments);
|
||||
}
|
||||
var forward = true;
|
||||
switch(evt.keyCode){
|
||||
case dojo.keys.LEFT_ARROW:
|
||||
case dojo.keys.UP_ARROW:
|
||||
forward = false;
|
||||
// fallthrough
|
||||
case dojo.keys.RIGHT_ARROW:
|
||||
case dojo.keys.DOWN_ARROW:
|
||||
// find currently focused button in children array
|
||||
var children = this.getChildren();
|
||||
var index = dojo.indexOf(children, evt._dijitWidget);
|
||||
// pick next button to focus on
|
||||
index += forward ? 1 : children.length - 1;
|
||||
var next = children[ index % children.length ];
|
||||
dojo.stopEvent(evt);
|
||||
next._onTitleClick();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
dojo.declare(
|
||||
"dijit.layout.AccordionPane",
|
||||
[dijit.layout.ContentPane, dijit._Templated, dijit._Contained],
|
||||
{
|
||||
// summary
|
||||
// AccordionPane is a box with a title that contains another widget (often a ContentPane).
|
||||
// It's a widget used internally by AccordionContainer.
|
||||
|
||||
templateString:"<div class='dijitAccordionPane'\n\t><div dojoAttachPoint='titleNode,focusNode' dojoAttachEvent='ondijitclick:_onTitleClick,onkeypress:_onKeyPress'\n\t\tclass='dijitAccordionTitle' wairole=\"tab\"\n\t\t><div class='dijitAccordionArrow'></div\n\t\t><div class='arrowTextUp' waiRole=\"presentation\">▲</div\n\t\t><div class='arrowTextDown' waiRole=\"presentation\">▼</div\n\t\t><span dojoAttachPoint='titleTextNode'>${title}</span></div\n\t><div><div dojoAttachPoint='containerNode' style='overflow: hidden; height: 1px; display: none'\n\t\tdojoAttachEvent='onkeypress:_onKeyPress'\n\t\tclass='dijitAccordionBody' waiRole=\"tabpanel\"\n\t></div></div>\n</div>\n",
|
||||
|
||||
postCreate: function(){
|
||||
dijit.layout.AccordionPane.superclass.postCreate.apply(this, arguments);
|
||||
dojo.setSelectable(this.titleNode, false);
|
||||
this.setSelected(this.selected);
|
||||
},
|
||||
|
||||
getTitleHeight: function(){
|
||||
// summary: returns the height of the title dom node
|
||||
return dojo.marginBox(this.titleNode).h; // Integer
|
||||
},
|
||||
|
||||
_onTitleClick: function(){
|
||||
// summary: callback when someone clicks my title
|
||||
var parent = this.getParent();
|
||||
parent.selectChild(this);
|
||||
dijit.focus(this.focusNode);
|
||||
},
|
||||
|
||||
_onKeyPress: function(/*Event*/ evt){
|
||||
evt._dijitWidget = this;
|
||||
return this.getParent().processKey(evt);
|
||||
},
|
||||
|
||||
_setSelectedState: function(/*Boolean*/ isSelected){
|
||||
this.selected = isSelected;
|
||||
(isSelected ? dojo.addClass : dojo.removeClass)(this.domNode, "dijitAccordionPane-selected");
|
||||
this.focusNode.setAttribute("tabIndex",(isSelected)? "0":"-1");
|
||||
},
|
||||
|
||||
setSelected: function(/*Boolean*/ isSelected){
|
||||
// summary: change the selected state on this pane
|
||||
this._setSelectedState(isSelected);
|
||||
if(isSelected){ this.onSelected(); }
|
||||
},
|
||||
|
||||
onSelected: function(){
|
||||
// summary: called when this pane is selected
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
371
spring-faces/src/main/java/META-INF/dijit/layout/ContentPane.js
Normal file
371
spring-faces/src/main/java/META-INF/dijit/layout/ContentPane.js
Normal file
@@ -0,0 +1,371 @@
|
||||
if(!dojo._hasResource["dijit.layout.ContentPane"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.layout.ContentPane"] = true;
|
||||
dojo.provide("dijit.layout.ContentPane");
|
||||
|
||||
dojo.require("dijit._Widget");
|
||||
dojo.require("dojo.parser");
|
||||
dojo.require("dojo.string");
|
||||
dojo.requireLocalization("dijit", "loading", null, "ROOT");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.layout.ContentPane",
|
||||
dijit._Widget,
|
||||
{
|
||||
// summary:
|
||||
// A widget that acts as a Container for other widgets, and includes a ajax interface
|
||||
// description:
|
||||
// A widget that can be used as a standalone widget
|
||||
// or as a baseclass for other widgets
|
||||
// Handles replacement of document fragment using either external uri or javascript
|
||||
// generated markup or DOM content, instantiating widgets within that content.
|
||||
// Don't confuse it with an iframe, it only needs/wants document fragments.
|
||||
// It's useful as a child of LayoutContainer, SplitContainer, or TabContainer.
|
||||
// But note that those classes can contain any widget as a child.
|
||||
// usage:
|
||||
// Some quick samples:
|
||||
// To change the innerHTML use .setContent('<b>new content</b>')
|
||||
//
|
||||
// Or you can send it a NodeList, .setContent(dojo.query('div [class=selected]', userSelection))
|
||||
// please note that the nodes in NodeList will copied, not moved
|
||||
//
|
||||
// To do a ajax update use .setHref('url')
|
||||
|
||||
// href: String
|
||||
// The href of the content that displays now.
|
||||
// Set this at construction if you want to load data externally when the
|
||||
// pane is shown. (Set preload=true to load it immediately.)
|
||||
// Changing href after creation doesn't have any effect; see setHref();
|
||||
href: "",
|
||||
|
||||
// extractContent: Boolean
|
||||
// Extract visible content from inside of <body> .... </body>
|
||||
extractContent: false,
|
||||
|
||||
// parseOnLoad: Boolean
|
||||
// parse content and create the widgets, if any
|
||||
parseOnLoad: true,
|
||||
|
||||
// preventCache: Boolean
|
||||
// Cache content retreived externally
|
||||
preventCache: false,
|
||||
|
||||
// preload: Boolean
|
||||
// Force load of data even if pane is hidden.
|
||||
preload: false,
|
||||
|
||||
// refreshOnShow: Boolean
|
||||
// Refresh (re-download) content when pane goes from hidden to shown
|
||||
refreshOnShow: false,
|
||||
|
||||
// loadingMessage: String
|
||||
// Message that shows while downloading
|
||||
loadingMessage: "<span class='dijitContentPaneLoading'>${loadingState}</span>", // TODO: consider a graphical representation for this state which does not require localization
|
||||
|
||||
// errorMessage: String
|
||||
// Message that shows if an error occurs
|
||||
errorMessage: "<span class='dijitContentPaneError'>${errorState}</span>", // TODO: consider a graphical representation for this state which does not require localization
|
||||
|
||||
// isLoaded: Boolean
|
||||
// Tells loading status see onLoad|onUnload for event hooks
|
||||
isLoaded: false,
|
||||
|
||||
// class: String
|
||||
// Class name to apply to ContentPane dom nodes
|
||||
"class": "dijitContentPane",
|
||||
|
||||
postCreate: function(){
|
||||
// remove the title attribute so it doesn't show up when i hover
|
||||
// over a node
|
||||
this.domNode.title = "";
|
||||
|
||||
if(this.preload){
|
||||
this._loadCheck();
|
||||
}
|
||||
|
||||
var messages = dojo.i18n.getLocalization("dijit", "loading", this.lang);
|
||||
this.loadingMessage = dojo.string.substitute(this.loadingMessage, messages);
|
||||
this.errorMessage = dojo.string.substitute(this.errorMessage, messages);
|
||||
|
||||
// for programatically created ContentPane (with <span> tag), need to muck w/CSS
|
||||
// or it's as though overflow:visible is set
|
||||
dojo.addClass(this.domNode, this["class"]);
|
||||
},
|
||||
|
||||
startup: function(){
|
||||
if(!this._started){
|
||||
this._loadCheck();
|
||||
this._started = true;
|
||||
}
|
||||
},
|
||||
|
||||
refresh: function(){
|
||||
// summary:
|
||||
// Force a refresh (re-download) of content, be sure to turn off cache
|
||||
|
||||
// we return result of _prepareLoad here to avoid code dup. in dojox.layout.ContentPane
|
||||
return this._prepareLoad(true);
|
||||
},
|
||||
|
||||
setHref: function(/*String|Uri*/ href){
|
||||
// summary:
|
||||
// Reset the (external defined) content of this pane and replace with new url
|
||||
// Note: It delays the download until widget is shown if preload is false
|
||||
// href:
|
||||
// url to the page you want to get, must be within the same domain as your mainpage
|
||||
this.href = href;
|
||||
|
||||
// we return result of _prepareLoad here to avoid code dup. in dojox.layout.ContentPane
|
||||
return this._prepareLoad();
|
||||
},
|
||||
|
||||
setContent: function(/*String|DomNode|Nodelist*/data){
|
||||
// summary:
|
||||
// Replaces old content with data content, include style classes from old content
|
||||
// data:
|
||||
// the new Content may be String, DomNode or NodeList
|
||||
//
|
||||
// if data is a NodeList (or an array of nodes) nodes are copied
|
||||
// so you can import nodes from another document implicitly
|
||||
|
||||
// clear href so we cant run refresh and clear content
|
||||
// refresh should only work if we downloaded the content
|
||||
if(!this._isDownloaded){
|
||||
this.href = "";
|
||||
this._onUnloadHandler();
|
||||
}
|
||||
|
||||
this._setContent(data || "");
|
||||
|
||||
this._isDownloaded = false; // must be set after _setContent(..), pathadjust in dojox.layout.ContentPane
|
||||
|
||||
if(this.parseOnLoad){
|
||||
this._createSubWidgets();
|
||||
}
|
||||
|
||||
this._onLoadHandler();
|
||||
},
|
||||
|
||||
cancel: function(){
|
||||
// summary
|
||||
// Cancels a inflight download of content
|
||||
if(this._xhrDfd && (this._xhrDfd.fired == -1)){
|
||||
this._xhrDfd.cancel();
|
||||
}
|
||||
|
||||
delete this._xhrDfd; // garbage collect
|
||||
},
|
||||
|
||||
destroy: function(){
|
||||
// if we have multiple controllers destroying us, bail after the first
|
||||
if(this._beingDestroyed){
|
||||
return;
|
||||
}
|
||||
// make sure we call onUnload
|
||||
this._onUnloadHandler();
|
||||
this._beingDestroyed = true;
|
||||
dijit.layout.ContentPane.superclass.destroy.call(this);
|
||||
},
|
||||
|
||||
resize: function(size){
|
||||
dojo.marginBox(this.domNode, size);
|
||||
},
|
||||
|
||||
_prepareLoad: function(forceLoad){
|
||||
// sets up for a xhrLoad, load is deferred until widget onShow
|
||||
// cancels a inflight download
|
||||
this.cancel();
|
||||
this.isLoaded = false;
|
||||
this._loadCheck(forceLoad);
|
||||
},
|
||||
|
||||
_loadCheck: function(forceLoad){
|
||||
// call this when you change onShow (onSelected) status when selected in parent container
|
||||
// it's used as a trigger for href download when this.domNode.display != 'none'
|
||||
|
||||
// sequence:
|
||||
// if no href -> bail
|
||||
// forceLoad -> always load
|
||||
// this.preload -> load when download not in progress, domNode display doesn't matter
|
||||
// this.refreshOnShow -> load when download in progress bails, domNode display !='none' AND
|
||||
// this.open !== false (undefined is ok), isLoaded doesn't matter
|
||||
// else -> load when download not in progress, if this.open !== false (undefined is ok) AND
|
||||
// domNode display != 'none', isLoaded must be false
|
||||
|
||||
var displayState = ((this.open !== false) && (this.domNode.style.display != 'none'));
|
||||
|
||||
if(this.href &&
|
||||
(forceLoad ||
|
||||
(this.preload && !this._xhrDfd) ||
|
||||
(this.refreshOnShow && displayState && !this._xhrDfd) ||
|
||||
(!this.isLoaded && displayState && !this._xhrDfd)
|
||||
)
|
||||
){
|
||||
this._downloadExternalContent();
|
||||
}
|
||||
},
|
||||
|
||||
_downloadExternalContent: function(){
|
||||
this._onUnloadHandler();
|
||||
|
||||
// display loading message
|
||||
// TODO: maybe we should just set a css class with a loading image as background?
|
||||
this._setContent(
|
||||
this.onDownloadStart.call(this)
|
||||
);
|
||||
|
||||
var self = this;
|
||||
var getArgs = {
|
||||
preventCache: (this.preventCache || this.refreshOnShow),
|
||||
url: this.href,
|
||||
handleAs: "text"
|
||||
};
|
||||
if(dojo.isObject(this.ioArgs)){
|
||||
dojo.mixin(getArgs, this.ioArgs);
|
||||
}
|
||||
|
||||
var hand = this._xhrDfd = (this.ioMethod || dojo.xhrGet)(getArgs);
|
||||
|
||||
hand.addCallback(function(html){
|
||||
try{
|
||||
self.onDownloadEnd.call(self);
|
||||
self._isDownloaded = true;
|
||||
self.setContent.call(self, html); // onload event is called from here
|
||||
}catch(err){
|
||||
self._onError.call(self, 'Content', err); // onContentError
|
||||
}
|
||||
delete self._xhrDfd;
|
||||
return html;
|
||||
});
|
||||
|
||||
hand.addErrback(function(err){
|
||||
if(!hand.cancelled){
|
||||
// show error message in the pane
|
||||
self._onError.call(self, 'Download', err); // onDownloadError
|
||||
}
|
||||
delete self._xhrDfd;
|
||||
return err;
|
||||
});
|
||||
},
|
||||
|
||||
_onLoadHandler: function(){
|
||||
this.isLoaded = true;
|
||||
try{
|
||||
this.onLoad.call(this);
|
||||
}catch(e){
|
||||
console.error('Error '+this.widgetId+' running custom onLoad code');
|
||||
}
|
||||
},
|
||||
|
||||
_onUnloadHandler: function(){
|
||||
this.isLoaded = false;
|
||||
this.cancel();
|
||||
try{
|
||||
this.onUnload.call(this);
|
||||
}catch(e){
|
||||
console.error('Error '+this.widgetId+' running custom onUnload code');
|
||||
}
|
||||
},
|
||||
|
||||
_setContent: function(cont){
|
||||
this.destroyDescendants();
|
||||
|
||||
try{
|
||||
var node = this.containerNode || this.domNode;
|
||||
while(node.firstChild){
|
||||
dojo._destroyElement(node.firstChild);
|
||||
}
|
||||
if(typeof cont == "string"){
|
||||
// dijit.ContentPane does only minimal fixes,
|
||||
// No pathAdjustments, script retrieval, style clean etc
|
||||
// some of these should be available in the dojox.layout.ContentPane
|
||||
if(this.extractContent){
|
||||
match = cont.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
|
||||
if(match){ cont = match[1]; }
|
||||
}
|
||||
node.innerHTML = cont;
|
||||
}else{
|
||||
// domNode or NodeList
|
||||
if(cont.nodeType){ // domNode (htmlNode 1 or textNode 3)
|
||||
node.appendChild(cont);
|
||||
}else{// nodelist or array such as dojo.Nodelist
|
||||
dojo.forEach(cont, function(n){
|
||||
node.appendChild(n.cloneNode(true));
|
||||
});
|
||||
}
|
||||
}
|
||||
}catch(e){
|
||||
// check if a domfault occurs when we are appending this.errorMessage
|
||||
// like for instance if domNode is a UL and we try append a DIV
|
||||
var errMess = this.onContentError(e);
|
||||
try{
|
||||
node.innerHTML = errMess;
|
||||
}catch(e){
|
||||
console.error('Fatal '+this.id+' could not change content due to '+e.message, e);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_onError: function(type, err, consoleText){
|
||||
// shows user the string that is returned by on[type]Error
|
||||
// overide on[type]Error and return your own string to customize
|
||||
var errText = this['on' + type + 'Error'].call(this, err);
|
||||
if(consoleText){
|
||||
console.error(consoleText, err);
|
||||
}else if(errText){// a empty string won't change current content
|
||||
this._setContent.call(this, errText);
|
||||
}
|
||||
},
|
||||
|
||||
_createSubWidgets: function(){
|
||||
// summary: scan my contents and create subwidgets
|
||||
var rootNode = this.containerNode || this.domNode;
|
||||
try{
|
||||
dojo.parser.parse(rootNode, true);
|
||||
}catch(e){
|
||||
this._onError('Content', e, "Couldn't create widgets in "+this.id
|
||||
+(this.href ? " from "+this.href : ""));
|
||||
}
|
||||
},
|
||||
|
||||
// EVENT's, should be overide-able
|
||||
onLoad: function(e){
|
||||
// summary:
|
||||
// Event hook, is called after everything is loaded and widgetified
|
||||
},
|
||||
|
||||
onUnload: function(e){
|
||||
// summary:
|
||||
// Event hook, is called before old content is cleared
|
||||
},
|
||||
|
||||
onDownloadStart: function(){
|
||||
// summary:
|
||||
// called before download starts
|
||||
// the string returned by this function will be the html
|
||||
// that tells the user we are loading something
|
||||
// override with your own function if you want to change text
|
||||
return this.loadingMessage;
|
||||
},
|
||||
|
||||
onContentError: function(/*Error*/ error){
|
||||
// summary:
|
||||
// called on DOM faults, require fault etc in content
|
||||
// default is to display errormessage inside pane
|
||||
},
|
||||
|
||||
onDownloadError: function(/*Error*/ error){
|
||||
// summary:
|
||||
// Called when download error occurs, default is to display
|
||||
// errormessage inside pane. Overide function to change that.
|
||||
// The string returned by this function will be the html
|
||||
// that tells the user a error happend
|
||||
return this.errorMessage;
|
||||
},
|
||||
|
||||
onDownloadEnd: function(){
|
||||
// summary:
|
||||
// called when download is finished
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
if(!dojo._hasResource["dijit.layout.LayoutContainer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.layout.LayoutContainer"] = true;
|
||||
dojo.provide("dijit.layout.LayoutContainer");
|
||||
|
||||
dojo.require("dijit.layout._LayoutWidget");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.layout.LayoutContainer",
|
||||
dijit.layout._LayoutWidget,
|
||||
{
|
||||
// summary
|
||||
// Provides Delphi-style panel layout semantics.
|
||||
//
|
||||
// details
|
||||
// A LayoutContainer is a box with a specified size (like style="width: 500px; height: 500px;"),
|
||||
// that contains children widgets marked with "layoutAlign" of "left", "right", "bottom", "top", and "client".
|
||||
// It takes it's children marked as left/top/bottom/right, and lays them out along the edges of the box,
|
||||
// and then it takes the child marked "client" and puts it into the remaining space in the middle.
|
||||
//
|
||||
// Left/right positioning is similar to CSS's "float: left" and "float: right",
|
||||
// and top/bottom positioning would be similar to "float: top" and "float: bottom", if there were such
|
||||
// CSS.
|
||||
//
|
||||
// Note that there can only be one client element, but there can be multiple left, right, top,
|
||||
// or bottom elements.
|
||||
//
|
||||
// usage
|
||||
// <style>
|
||||
// html, body{ height: 100%; width: 100%; }
|
||||
// </style>
|
||||
// <div dojoType="LayoutContainer" style="width: 100%; height: 100%">
|
||||
// <div dojoType="ContentPane" layoutAlign="top">header text</div>
|
||||
// <div dojoType="ContentPane" layoutAlign="left" style="width: 200px;">table of contents</div>
|
||||
// <div dojoType="ContentPane" layoutAlign="client">client area</div>
|
||||
// </div>
|
||||
//
|
||||
// Lays out each child in the natural order the children occur in.
|
||||
// Basically each child is laid out into the "remaining space", where "remaining space" is initially
|
||||
// the content area of this widget, but is reduced to a smaller rectangle each time a child is added.
|
||||
//
|
||||
|
||||
layout: function(){
|
||||
dijit.layout.layoutChildren(this.domNode, this._contentBox, this.getChildren());
|
||||
},
|
||||
|
||||
addChild: function(/*Widget*/ child, /*Integer?*/ insertIndex){
|
||||
dijit._Container.prototype.addChild.apply(this, arguments);
|
||||
if(this._started){
|
||||
dijit.layout.layoutChildren(this.domNode, this._contentBox, this.getChildren());
|
||||
}
|
||||
},
|
||||
|
||||
removeChild: function(/*Widget*/ widget){
|
||||
dijit._Container.prototype.removeChild.apply(this, arguments);
|
||||
if(this._started){
|
||||
dijit.layout.layoutChildren(this.domNode, this._contentBox, this.getChildren());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// This argument can be specified for the children of a LayoutContainer.
|
||||
// Since any widget can be specified as a LayoutContainer child, mix it
|
||||
// into the base widget class. (This is a hack, but it's effective.)
|
||||
dojo.extend(dijit._Widget, {
|
||||
// layoutAlign: String
|
||||
// "none", "left", "right", "bottom", "top", and "client".
|
||||
// See the LayoutContainer description for details on this parameter.
|
||||
layoutAlign: 'none'
|
||||
});
|
||||
|
||||
}
|
||||
36
spring-faces/src/main/java/META-INF/dijit/layout/LinkPane.js
Normal file
36
spring-faces/src/main/java/META-INF/dijit/layout/LinkPane.js
Normal file
@@ -0,0 +1,36 @@
|
||||
if(!dojo._hasResource["dijit.layout.LinkPane"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.layout.LinkPane"] = true;
|
||||
dojo.provide("dijit.layout.LinkPane");
|
||||
|
||||
dojo.require("dijit.layout.ContentPane");
|
||||
dojo.require("dijit._Templated");
|
||||
|
||||
dojo.declare("dijit.layout.LinkPane",
|
||||
[dijit.layout.ContentPane, dijit._Templated],
|
||||
{
|
||||
// summary
|
||||
// LinkPane is just a ContentPane that loads data remotely (via the href attribute),
|
||||
// and has markup similar to an anchor. The anchor's body (the words between <a> and </a>)
|
||||
// become the title of the widget (used for TabContainer, AccordionContainer, etc.)
|
||||
// usage
|
||||
// <a href="foo.html">my title</a>
|
||||
|
||||
// I'm using a template because the user may specify the input as
|
||||
// <a href="foo.html">title</a>, in which case we need to get rid of the
|
||||
// <a> because we don't want a link.
|
||||
templateString: '<div class="dijitLinkPane"></div>',
|
||||
|
||||
postCreate: function(){
|
||||
|
||||
// If user has specified node contents, they become the title
|
||||
// (the link must be plain text)
|
||||
if(this.srcNodeRef){
|
||||
this.title += this.srcNodeRef.innerHTML;
|
||||
}
|
||||
|
||||
dijit.layout.LinkPane.superclass.postCreate.apply(this, arguments);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
@@ -0,0 +1,529 @@
|
||||
if(!dojo._hasResource["dijit.layout.SplitContainer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.layout.SplitContainer"] = true;
|
||||
dojo.provide("dijit.layout.SplitContainer");
|
||||
|
||||
//
|
||||
// TODO
|
||||
// make it prettier
|
||||
// active dragging upwards doesn't always shift other bars (direction calculation is wrong in this case)
|
||||
//
|
||||
|
||||
dojo.require("dojo.cookie");
|
||||
dojo.require("dijit.layout._LayoutWidget");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.layout.SplitContainer",
|
||||
dijit.layout._LayoutWidget,
|
||||
{
|
||||
// summary
|
||||
// Contains multiple children widgets, all of which are displayed side by side
|
||||
// (either horizontally or vertically); there's a bar between each of the children,
|
||||
// and you can adjust the relative size of each child by dragging the bars.
|
||||
//
|
||||
// You must specify a size (width and height) for the SplitContainer.
|
||||
|
||||
// activeSizing: Boolean
|
||||
// If true, the children's size changes as you drag the bar;
|
||||
// otherwise, the sizes don't change until you drop the bar (by mouse-up)
|
||||
activeSizing: false,
|
||||
|
||||
// sizerWidget: Integer
|
||||
// Size in pixels of the bar between each child
|
||||
// TODO: this should be a CSS attribute
|
||||
sizerWidth: 15,
|
||||
|
||||
// orientation: String
|
||||
// either 'horizontal' or vertical; indicates whether the children are
|
||||
// arranged side-by-side or up/down.
|
||||
orientation: 'horizontal',
|
||||
|
||||
// persist: Boolean
|
||||
// Save splitter positions in a cookie
|
||||
persist: true,
|
||||
|
||||
postMixInProperties: function(){
|
||||
dijit.layout.SplitContainer.superclass.postMixInProperties.apply(this, arguments);
|
||||
this.isHorizontal = (this.orientation == 'horizontal');
|
||||
},
|
||||
|
||||
postCreate: function(){
|
||||
dijit.layout.SplitContainer.superclass.postCreate.apply(this, arguments);
|
||||
this.sizers = [];
|
||||
dojo.addClass(this.domNode, "dijitSplitContainer");
|
||||
// overflow has to be explicitly hidden for splitContainers using gekko (trac #1435)
|
||||
// to keep other combined css classes from inadvertantly making the overflow visible
|
||||
if(dojo.isMozilla){
|
||||
this.domNode.style.overflow = '-moz-scrollbars-none'; // hidden doesn't work
|
||||
}
|
||||
|
||||
// create the fake dragger
|
||||
if(typeof this.sizerWidth == "object"){
|
||||
try{ //FIXME: do this without a try/catch
|
||||
this.sizerWidth = parseInt(this.sizerWidth.toString());
|
||||
}catch(e){ this.sizerWidth = 15; }
|
||||
}
|
||||
var sizer = this.virtualSizer = document.createElement('div');
|
||||
sizer.style.position = 'relative';
|
||||
|
||||
// #1681: work around the dreaded 'quirky percentages in IE' layout bug
|
||||
// If the splitcontainer's dimensions are specified in percentages, it
|
||||
// will be resized when the virtualsizer is displayed in _showSizingLine
|
||||
// (typically expanding its bounds unnecessarily). This happens because
|
||||
// we use position: relative for .dijitSplitContainer.
|
||||
// The workaround: instead of changing the display style attribute,
|
||||
// switch to changing the zIndex (bring to front/move to back)
|
||||
|
||||
sizer.style.zIndex = 10;
|
||||
sizer.className = this.isHorizontal ? 'dijitSplitContainerVirtualSizerH' : 'dijitSplitContainerVirtualSizerV';
|
||||
this.domNode.appendChild(sizer);
|
||||
dojo.setSelectable(sizer, false);
|
||||
},
|
||||
|
||||
startup: function(){
|
||||
if(this._started){ return; }
|
||||
dojo.forEach(this.getChildren(), function(child, i, children){
|
||||
// attach the children and create the draggers
|
||||
this._injectChild(child);
|
||||
|
||||
if(i < children.length-1){
|
||||
this._addSizer();
|
||||
}
|
||||
}, this);
|
||||
|
||||
if(this.persist){
|
||||
this._restoreState();
|
||||
}
|
||||
dijit.layout._LayoutWidget.prototype.startup.apply(this, arguments);
|
||||
this._started = true;
|
||||
},
|
||||
|
||||
_injectChild: function(child){
|
||||
child.domNode.style.position = "absolute";
|
||||
dojo.addClass(child.domNode, "dijitSplitPane");
|
||||
},
|
||||
|
||||
_addSizer: function(){
|
||||
var i = this.sizers.length;
|
||||
|
||||
// TODO: use a template for this!!!
|
||||
var sizer = this.sizers[i] = document.createElement('div');
|
||||
sizer.className = this.isHorizontal ? 'dijitSplitContainerSizerH' : 'dijitSplitContainerSizerV';
|
||||
|
||||
// add the thumb div
|
||||
var thumb = document.createElement('div');
|
||||
thumb.className = 'thumb';
|
||||
sizer.appendChild(thumb);
|
||||
|
||||
var self = this;
|
||||
var handler = (function(){ var sizer_i = i; return function(e){ self.beginSizing(e, sizer_i); } })();
|
||||
dojo.connect(sizer, "onmousedown", handler);
|
||||
|
||||
this.domNode.appendChild(sizer);
|
||||
dojo.setSelectable(sizer, false);
|
||||
},
|
||||
|
||||
removeChild: function(widget){
|
||||
// Remove sizer, but only if widget is really our child and
|
||||
// we have at least one sizer to throw away
|
||||
if(this.sizers.length && dojo.indexOf(this.getChildren(), widget) != -1){
|
||||
var i = this.sizers.length - 1;
|
||||
dojo._destroyElement(this.sizers[i]);
|
||||
this.sizers.length--;
|
||||
}
|
||||
|
||||
// Remove widget and repaint
|
||||
dijit._Container.prototype.removeChild.apply(this, arguments);
|
||||
if(this._started){
|
||||
this.layout();
|
||||
}
|
||||
},
|
||||
|
||||
addChild: function(/*Widget*/ child, /*Integer?*/ insertIndex){
|
||||
dijit._Container.prototype.addChild.apply(this, arguments);
|
||||
|
||||
if(this._started){
|
||||
// Do the stuff that startup() does for each widget
|
||||
this._injectChild(child);
|
||||
var children = this.getChildren();
|
||||
if(children.length > 1){
|
||||
this._addSizer();
|
||||
}
|
||||
|
||||
// and then reposition (ie, shrink) every pane to make room for the new guy
|
||||
this.layout();
|
||||
}
|
||||
},
|
||||
|
||||
layout: function(){
|
||||
// summary:
|
||||
// Do layout of panels
|
||||
|
||||
// base class defines this._contentBox on initial creation and also
|
||||
// on resize
|
||||
this.paneWidth = this._contentBox.w;
|
||||
this.paneHeight = this._contentBox.h;
|
||||
|
||||
var children = this.getChildren();
|
||||
if(!children.length){ return; }
|
||||
|
||||
//
|
||||
// calculate space
|
||||
//
|
||||
|
||||
var space = this.isHorizontal ? this.paneWidth : this.paneHeight;
|
||||
if(children.length > 1){
|
||||
space -= this.sizerWidth * (children.length - 1);
|
||||
}
|
||||
|
||||
//
|
||||
// calculate total of SizeShare values
|
||||
//
|
||||
var outOf = 0;
|
||||
dojo.forEach(children, function(child){
|
||||
outOf += child.sizeShare;
|
||||
});
|
||||
|
||||
//
|
||||
// work out actual pixels per sizeshare unit
|
||||
//
|
||||
var pixPerUnit = space / outOf;
|
||||
|
||||
//
|
||||
// set the SizeActual member of each pane
|
||||
//
|
||||
var totalSize = 0;
|
||||
dojo.forEach(children.slice(0, children.length - 1), function(child){
|
||||
var size = Math.round(pixPerUnit * child.sizeShare);
|
||||
child.sizeActual = size;
|
||||
totalSize += size;
|
||||
});
|
||||
|
||||
children[children.length-1].sizeActual = space - totalSize;
|
||||
|
||||
//
|
||||
// make sure the sizes are ok
|
||||
//
|
||||
this._checkSizes();
|
||||
|
||||
//
|
||||
// now loop, positioning each pane and letting children resize themselves
|
||||
//
|
||||
|
||||
var pos = 0;
|
||||
var size = children[0].sizeActual;
|
||||
this._movePanel(children[0], pos, size);
|
||||
children[0].position = pos;
|
||||
pos += size;
|
||||
|
||||
// if we don't have any sizers, our layout method hasn't been called yet
|
||||
// so bail until we are called..TODO: REVISIT: need to change the startup
|
||||
// algorithm to guaranteed the ordering of calls to layout method
|
||||
if(!this.sizers){
|
||||
return;
|
||||
}
|
||||
|
||||
dojo.some(children.slice(1), function(child, i){
|
||||
// error-checking
|
||||
if(!this.sizers[i]){
|
||||
return true;
|
||||
}
|
||||
// first we position the sizing handle before this pane
|
||||
this._moveSlider(this.sizers[i], pos, this.sizerWidth);
|
||||
this.sizers[i].position = pos;
|
||||
pos += this.sizerWidth;
|
||||
|
||||
size = child.sizeActual;
|
||||
this._movePanel(child, pos, size);
|
||||
child.position = pos;
|
||||
pos += size;
|
||||
}, this);
|
||||
},
|
||||
|
||||
_movePanel: function(panel, pos, size){
|
||||
if(this.isHorizontal){
|
||||
panel.domNode.style.left = pos + 'px'; // TODO: resize() takes l and t parameters too, don't need to set manually
|
||||
panel.domNode.style.top = 0;
|
||||
var box = {w: size, h: this.paneHeight};
|
||||
if(panel.resize){
|
||||
panel.resize(box);
|
||||
}else{
|
||||
dojo.marginBox(panel.domNode, box);
|
||||
}
|
||||
}else{
|
||||
panel.domNode.style.left = 0; // TODO: resize() takes l and t parameters too, don't need to set manually
|
||||
panel.domNode.style.top = pos + 'px';
|
||||
var box = {w: this.paneWidth, h: size};
|
||||
if(panel.resize){
|
||||
panel.resize(box);
|
||||
}else{
|
||||
dojo.marginBox(panel.domNode, box);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_moveSlider: function(slider, pos, size){
|
||||
if(this.isHorizontal){
|
||||
slider.style.left = pos + 'px';
|
||||
slider.style.top = 0;
|
||||
dojo.marginBox(slider, { w: size, h: this.paneHeight });
|
||||
}else{
|
||||
slider.style.left = 0;
|
||||
slider.style.top = pos + 'px';
|
||||
dojo.marginBox(slider, { w: this.paneWidth, h: size });
|
||||
}
|
||||
},
|
||||
|
||||
_growPane: function(growth, pane){
|
||||
if(growth > 0){
|
||||
if(pane.sizeActual > pane.sizeMin){
|
||||
if((pane.sizeActual - pane.sizeMin) > growth){
|
||||
|
||||
// stick all the growth in this pane
|
||||
pane.sizeActual = pane.sizeActual - growth;
|
||||
growth = 0;
|
||||
}else{
|
||||
// put as much growth in here as we can
|
||||
growth -= pane.sizeActual - pane.sizeMin;
|
||||
pane.sizeActual = pane.sizeMin;
|
||||
}
|
||||
}
|
||||
}
|
||||
return growth;
|
||||
},
|
||||
|
||||
_checkSizes: function(){
|
||||
|
||||
var totalMinSize = 0;
|
||||
var totalSize = 0;
|
||||
var children = this.getChildren();
|
||||
|
||||
dojo.forEach(children, function(child){
|
||||
totalSize += child.sizeActual;
|
||||
totalMinSize += child.sizeMin;
|
||||
});
|
||||
|
||||
// only make adjustments if we have enough space for all the minimums
|
||||
|
||||
if(totalMinSize <= totalSize){
|
||||
|
||||
var growth = 0;
|
||||
|
||||
dojo.forEach(children, function(child){
|
||||
if(child.sizeActual < child.sizeMin){
|
||||
growth += child.sizeMin - child.sizeActual;
|
||||
child.sizeActual = child.sizeMin;
|
||||
}
|
||||
});
|
||||
|
||||
if(growth > 0){
|
||||
var list = this.isDraggingLeft ? children.reverse() : children;
|
||||
dojo.forEach(list, function(child){
|
||||
growth = this._growPane(growth, child);
|
||||
}, this);
|
||||
}
|
||||
}else{
|
||||
dojo.forEach(children, function(child){
|
||||
child.sizeActual = Math.round(totalSize * (child.sizeMin / totalMinSize));
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
beginSizing: function(e, i){
|
||||
var children = this.getChildren();
|
||||
this.paneBefore = children[i];
|
||||
this.paneAfter = children[i+1];
|
||||
|
||||
this.isSizing = true;
|
||||
this.sizingSplitter = this.sizers[i];
|
||||
|
||||
if(!this.cover){
|
||||
this.cover = dojo.doc.createElement('div');
|
||||
this.domNode.appendChild(this.cover);
|
||||
var s = this.cover.style;
|
||||
s.position = 'absolute';
|
||||
s.zIndex = 1;
|
||||
s.top = 0;
|
||||
s.left = 0;
|
||||
s.width = "100%";
|
||||
s.height = "100%";
|
||||
}else{
|
||||
this.cover.style.zIndex = 1;
|
||||
}
|
||||
this.sizingSplitter.style.zIndex = 2;
|
||||
|
||||
// TODO: REVISIT - we want MARGIN_BOX and core hasn't exposed that yet
|
||||
this.originPos = dojo.coords(children[0].domNode, true);
|
||||
if(this.isHorizontal){
|
||||
var client = (e.layerX ? e.layerX : e.offsetX);
|
||||
var screen = e.pageX;
|
||||
this.originPos = this.originPos.x;
|
||||
}else{
|
||||
var client = (e.layerY ? e.layerY : e.offsetY);
|
||||
var screen = e.pageY;
|
||||
this.originPos = this.originPos.y;
|
||||
}
|
||||
this.startPoint = this.lastPoint = screen;
|
||||
this.screenToClientOffset = screen - client;
|
||||
this.dragOffset = this.lastPoint - this.paneBefore.sizeActual - this.originPos - this.paneBefore.position;
|
||||
|
||||
if(!this.activeSizing){
|
||||
this._showSizingLine();
|
||||
}
|
||||
|
||||
//
|
||||
// attach mouse events
|
||||
//
|
||||
this.connect(document.documentElement, "onmousemove", "changeSizing");
|
||||
this.connect(document.documentElement, "onmouseup", "endSizing");
|
||||
|
||||
dojo.stopEvent(e);
|
||||
},
|
||||
|
||||
changeSizing: function(e){
|
||||
if(!this.isSizing){ return; }
|
||||
this.lastPoint = this.isHorizontal ? e.pageX : e.pageY;
|
||||
this.movePoint();
|
||||
if(this.activeSizing){
|
||||
this._updateSize();
|
||||
}else{
|
||||
this._moveSizingLine();
|
||||
}
|
||||
dojo.stopEvent(e);
|
||||
},
|
||||
|
||||
endSizing: function(e){
|
||||
if(!this.isSizing){ return; }
|
||||
if(this.cover){
|
||||
this.cover.style.zIndex = -1;
|
||||
}
|
||||
if(!this.activeSizing){
|
||||
this._hideSizingLine();
|
||||
}
|
||||
|
||||
this._updateSize();
|
||||
|
||||
this.isSizing = false;
|
||||
|
||||
if(this.persist){
|
||||
this._saveState(this);
|
||||
}
|
||||
},
|
||||
|
||||
movePoint: function(){
|
||||
|
||||
// make sure lastPoint is a legal point to drag to
|
||||
var p = this.lastPoint - this.screenToClientOffset;
|
||||
|
||||
var a = p - this.dragOffset;
|
||||
a = this.legaliseSplitPoint(a);
|
||||
p = a + this.dragOffset;
|
||||
|
||||
this.lastPoint = p + this.screenToClientOffset;
|
||||
},
|
||||
|
||||
legaliseSplitPoint: function(a){
|
||||
|
||||
a += this.sizingSplitter.position;
|
||||
|
||||
this.isDraggingLeft = !!(a > 0);
|
||||
|
||||
if(!this.activeSizing){
|
||||
var min = this.paneBefore.position + this.paneBefore.sizeMin;
|
||||
if(a < min){
|
||||
a = min;
|
||||
}
|
||||
|
||||
var max = this.paneAfter.position + (this.paneAfter.sizeActual - (this.sizerWidth + this.paneAfter.sizeMin));
|
||||
if(a > max){
|
||||
a = max;
|
||||
}
|
||||
}
|
||||
|
||||
a -= this.sizingSplitter.position;
|
||||
|
||||
this._checkSizes();
|
||||
|
||||
return a;
|
||||
},
|
||||
|
||||
_updateSize: function(){
|
||||
//FIXME: sometimes this.lastPoint is NaN
|
||||
var pos = this.lastPoint - this.dragOffset - this.originPos;
|
||||
|
||||
var start_region = this.paneBefore.position;
|
||||
var end_region = this.paneAfter.position + this.paneAfter.sizeActual;
|
||||
|
||||
this.paneBefore.sizeActual = pos - start_region;
|
||||
this.paneAfter.position = pos + this.sizerWidth;
|
||||
this.paneAfter.sizeActual = end_region - this.paneAfter.position;
|
||||
|
||||
dojo.forEach(this.getChildren(), function(child){
|
||||
child.sizeShare = child.sizeActual;
|
||||
});
|
||||
|
||||
if(this._started){
|
||||
this.layout();
|
||||
}
|
||||
},
|
||||
|
||||
_showSizingLine: function(){
|
||||
|
||||
this._moveSizingLine();
|
||||
|
||||
dojo.marginBox(this.virtualSizer,
|
||||
this.isHorizontal ? { w: this.sizerWidth, h: this.paneHeight } : { w: this.paneWidth, h: this.sizerWidth });
|
||||
|
||||
this.virtualSizer.style.display = 'block';
|
||||
},
|
||||
|
||||
_hideSizingLine: function(){
|
||||
this.virtualSizer.style.display = 'none';
|
||||
},
|
||||
|
||||
_moveSizingLine: function(){
|
||||
var pos = (this.lastPoint - this.startPoint) + this.sizingSplitter.position;
|
||||
this.virtualSizer.style[ this.isHorizontal ? "left" : "top" ] = pos + 'px';
|
||||
},
|
||||
|
||||
_getCookieName: function(i){
|
||||
return this.id + "_" + i;
|
||||
},
|
||||
|
||||
_restoreState: function(){
|
||||
dojo.forEach(this.getChildren(), function(child, i){
|
||||
var cookieName = this._getCookieName(i);
|
||||
var cookieValue = dojo.cookie(cookieName);
|
||||
if(cookieValue){
|
||||
var pos = parseInt(cookieValue);
|
||||
if(typeof pos == "number"){
|
||||
child.sizeShare = pos;
|
||||
}
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
|
||||
_saveState: function(){
|
||||
dojo.forEach(this.getChildren(), function(child, i){
|
||||
dojo.cookie(this._getCookieName(i), child.sizeShare);
|
||||
}, this);
|
||||
}
|
||||
});
|
||||
|
||||
// These arguments can be specified for the children of a SplitContainer.
|
||||
// Since any widget can be specified as a SplitContainer child, mix them
|
||||
// into the base widget class. (This is a hack, but it's effective.)
|
||||
dojo.extend(dijit._Widget, {
|
||||
// sizeMin: Integer
|
||||
// Minimum size (width or height) of a child of a SplitContainer.
|
||||
// The value is relative to other children's sizeShare properties.
|
||||
sizeMin: 10,
|
||||
|
||||
// sizeShare: Integer
|
||||
// Size (width or height) of a child of a SplitContainer.
|
||||
// The value is relative to other children's sizeShare properties.
|
||||
// For example, if there are two children and each has sizeShare=10, then
|
||||
// each takes up 50% of the available space.
|
||||
sizeShare: 10
|
||||
});
|
||||
|
||||
}
|
||||
@@ -0,0 +1,436 @@
|
||||
if(!dojo._hasResource["dijit.layout.StackContainer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.layout.StackContainer"] = true;
|
||||
dojo.provide("dijit.layout.StackContainer");
|
||||
|
||||
dojo.require("dijit._Templated");
|
||||
dojo.require("dijit.layout._LayoutWidget");
|
||||
dojo.require("dijit.form.Button");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.layout.StackContainer",
|
||||
dijit.layout._LayoutWidget,
|
||||
|
||||
// summary
|
||||
// A container that has multiple children, but shows only
|
||||
// one child at a time (like looking at the pages in a book one by one).
|
||||
//
|
||||
// Publishes topics <widgetId>-addChild, <widgetId>-removeChild, and <widgetId>-selectChild
|
||||
//
|
||||
// Can be base class for container, Wizard, Show, etc.
|
||||
{
|
||||
// doLayout: Boolean
|
||||
// if true, change the size of my currently displayed child to match my size
|
||||
doLayout: true,
|
||||
|
||||
_started: false,
|
||||
|
||||
startup: function(){
|
||||
if(this._started){ return; }
|
||||
|
||||
var children = this.getChildren();
|
||||
|
||||
// Setup each page panel
|
||||
dojo.forEach(children, this._setupChild, this);
|
||||
|
||||
// Figure out which child to initially display
|
||||
dojo.some(children, function(child){
|
||||
if(child.selected){
|
||||
this.selectedChildWidget = child;
|
||||
}
|
||||
return child.selected;
|
||||
}, this);
|
||||
|
||||
// Default to the first child
|
||||
if(!this.selectedChildWidget && children[0]){
|
||||
this.selectedChildWidget = children[0];
|
||||
this.selectedChildWidget.selected = true;
|
||||
}
|
||||
if(this.selectedChildWidget){
|
||||
this._showChild(this.selectedChildWidget);
|
||||
}
|
||||
|
||||
// Now publish information about myself so any StackControllers can initialize..
|
||||
dojo.publish(this.id+"-startup", [{children: children, selected: this.selectedChildWidget}]);
|
||||
|
||||
dijit.layout._LayoutWidget.prototype.startup.apply(this, arguments);
|
||||
this._started = true;
|
||||
},
|
||||
|
||||
_setupChild: function(/*Widget*/ page){
|
||||
// Summary: prepare the given child
|
||||
|
||||
page.domNode.style.display = "none";
|
||||
|
||||
// since we are setting the width/height of the child elements, they need
|
||||
// to be position:relative, or IE has problems (See bug #2033)
|
||||
page.domNode.style.position = "relative";
|
||||
|
||||
return page;
|
||||
},
|
||||
|
||||
addChild: function(/*Widget*/ child, /*Integer?*/ insertIndex){
|
||||
dijit._Container.prototype.addChild.apply(this, arguments);
|
||||
child = this._setupChild(child);
|
||||
|
||||
if(this._started){
|
||||
// in case the tab titles have overflowed from one line to two lines
|
||||
this.layout();
|
||||
|
||||
dojo.publish(this.id+"-addChild", [child]);
|
||||
|
||||
// if this is the first child, then select it
|
||||
if(!this.selectedChildWidget){
|
||||
this.selectChild(child);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
removeChild: function(/*Widget*/ page){
|
||||
|
||||
dijit._Container.prototype.removeChild.apply(this, arguments);
|
||||
|
||||
// If we are being destroyed than don't run the code below (to select another page), because we are deleting
|
||||
// every page one by one
|
||||
if(this._beingDestroyed){ return; }
|
||||
|
||||
if(this._started){
|
||||
// this will notify any tablists to remove a button; do this first because it may affect sizing
|
||||
dojo.publish(this.id+"-removeChild", [page]);
|
||||
|
||||
// in case the tab titles now take up one line instead of two lines
|
||||
this.layout();
|
||||
}
|
||||
|
||||
if(this.selectedChildWidget === page){
|
||||
this.selectedChildWidget = undefined;
|
||||
if(this._started){
|
||||
var children = this.getChildren();
|
||||
if(children.length){
|
||||
this.selectChild(children[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
selectChild: function(/*Widget*/ page){
|
||||
// summary
|
||||
// Show the given widget (which must be one of my children)
|
||||
|
||||
page = dijit.byId(page);
|
||||
|
||||
if(this.selectedChildWidget != page){
|
||||
// Deselect old page and select new one
|
||||
this._transition(page, this.selectedChildWidget);
|
||||
this.selectedChildWidget = page;
|
||||
dojo.publish(this.id+"-selectChild", [page]);
|
||||
}
|
||||
},
|
||||
|
||||
_transition: function(/*Widget*/newWidget, /*Widget*/oldWidget){
|
||||
if(oldWidget){
|
||||
this._hideChild(oldWidget);
|
||||
}
|
||||
this._showChild(newWidget);
|
||||
|
||||
// Size the new widget, in case this is the first time it's being shown,
|
||||
// or I have been resized since the last time it was shown.
|
||||
// page must be visible for resizing to work
|
||||
if(this.doLayout && newWidget.resize){
|
||||
newWidget.resize(this._containerContentBox || this._contentBox);
|
||||
}
|
||||
},
|
||||
|
||||
forward: function(){
|
||||
// Summary: advance to next page
|
||||
var children = this.getChildren();
|
||||
var index = dojo.indexOf(children, this.selectedChildWidget);
|
||||
this.selectChild(children[ (index + 1) % children.length ]);
|
||||
},
|
||||
|
||||
back: function(){
|
||||
// Summary: go back to previous page
|
||||
var children = this.getChildren();
|
||||
var index = dojo.indexOf(children, this.selectedChildWidget);
|
||||
this.selectChild(children[ (index + children.length - 1) % children.length ]);
|
||||
},
|
||||
|
||||
// TODO: move this logic into controller?
|
||||
_onKeyPress: function(e){
|
||||
// summary
|
||||
// Keystroke handling for keystrokes on the tab panel itself (that were bubbled up to me)
|
||||
// Ctrl-w: close tab
|
||||
if (e.ctrlKey){
|
||||
switch(e.keyCode){
|
||||
case dojo.keys.PAGE_DOWN:
|
||||
case dojo.keys.PAGE_UP:
|
||||
case dojo.keys.TAB:
|
||||
if ((e.keyCode == dojo.keys.PAGE_DOWN) ||
|
||||
(e.keyCode == dojo.keys.TAB && !e.shiftKey)){
|
||||
this.forward();
|
||||
}else{
|
||||
this.back();
|
||||
}
|
||||
dijit.focus(this.selectedChildWidget.domNode);
|
||||
dojo.stopEvent(e);
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
if((e.keyChar == "w") &&
|
||||
(this.selectedChildWidget.closable)){
|
||||
this.closeChild(this.selectedChildWidget);
|
||||
dojo.stopEvent(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
layout: function(){
|
||||
// Summary: called when any page is shown, to make it fit the container correctly
|
||||
if(this.doLayout && this.selectedChildWidget && this.selectedChildWidget.resize){
|
||||
this.selectedChildWidget.resize(this._contentBox);
|
||||
}
|
||||
},
|
||||
|
||||
_showChild: function(/*Widget*/ page){
|
||||
var children = this.getChildren();
|
||||
page.isFirstChild = (page == children[0]);
|
||||
page.isLastChild = (page == children[children.length-1]);
|
||||
page.selected = true;
|
||||
|
||||
page.domNode.style.display="";
|
||||
if(page._loadCheck){
|
||||
page._loadCheck(); // trigger load in ContentPane
|
||||
}
|
||||
if(page.onShow){
|
||||
page.onShow();
|
||||
}
|
||||
},
|
||||
|
||||
_hideChild: function(/*Widget*/ page){
|
||||
page.selected=false;
|
||||
page.domNode.style.display="none";
|
||||
if(page.onHide){
|
||||
page.onHide();
|
||||
}
|
||||
},
|
||||
|
||||
closeChild: function(/*Widget*/ page){
|
||||
// summary
|
||||
// callback when user clicks the [X] to remove a page
|
||||
// if onClose() returns true then remove and destroy the childd
|
||||
var remove = page.onClose(this, page);
|
||||
if(remove){
|
||||
this.removeChild(page);
|
||||
// makes sure we can clean up executeScripts in ContentPane onUnLoad
|
||||
page.destroy();
|
||||
}
|
||||
},
|
||||
|
||||
destroy: function(){
|
||||
this._beingDestroyed = true;
|
||||
dijit.layout.StackContainer.superclass.destroy.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
dojo.declare(
|
||||
"dijit.layout.StackController",
|
||||
[dijit._Widget, dijit._Templated, dijit._Container],
|
||||
{
|
||||
// summary
|
||||
// Set of buttons to select a page in a page list.
|
||||
// Monitors the specified StackContainer, and whenever a page is
|
||||
// added, deleted, or selected, updates itself accordingly.
|
||||
|
||||
templateString: "<span wairole='tablist' dojoAttachEvent='onkeypress' class='dijitStackController'></span>",
|
||||
|
||||
// containerId: String
|
||||
// the id of the page container that I point to
|
||||
containerId: "",
|
||||
|
||||
// buttonWidget: String
|
||||
// the name of the button widget to create to correspond to each page
|
||||
buttonWidget: "dijit.layout._StackButton",
|
||||
|
||||
postCreate: function(){
|
||||
dijit.wai.setAttr(this.domNode, "waiRole", "role", "tablist");
|
||||
|
||||
this.pane2button = {}; // mapping from panes to buttons
|
||||
this._subscriptions=[
|
||||
dojo.subscribe(this.containerId+"-startup", this, "onStartup"),
|
||||
dojo.subscribe(this.containerId+"-addChild", this, "onAddChild"),
|
||||
dojo.subscribe(this.containerId+"-removeChild", this, "onRemoveChild"),
|
||||
dojo.subscribe(this.containerId+"-selectChild", this, "onSelectChild")
|
||||
];
|
||||
},
|
||||
|
||||
onStartup: function(/*Object*/ info){
|
||||
// summary: called after StackContainer has finished initializing
|
||||
dojo.forEach(info.children, this.onAddChild, this);
|
||||
this.onSelectChild(info.selected);
|
||||
},
|
||||
|
||||
destroy: function(){
|
||||
dojo.forEach(this._subscriptions, dojo.unsubscribe);
|
||||
dijit.layout.StackController.superclass.destroy.apply(this, arguments);
|
||||
},
|
||||
|
||||
onAddChild: function(/*Widget*/ page){
|
||||
// summary
|
||||
// Called whenever a page is added to the container.
|
||||
// Create button corresponding to the page.
|
||||
|
||||
// add a node that will be promoted to the button widget
|
||||
var refNode = document.createElement("span");
|
||||
this.domNode.appendChild(refNode);
|
||||
// create an instance of the button widget
|
||||
var cls = dojo.getObject(this.buttonWidget);
|
||||
var button = new cls({label: page.title, closeButton: page.closable}, refNode);
|
||||
this.addChild(button);
|
||||
this.pane2button[page] = button;
|
||||
page.controlButton = button; // this value might be overwritten if two tabs point to same container
|
||||
|
||||
var _this = this;
|
||||
dojo.connect(button, "onClick", function(){ _this.onButtonClick(page); });
|
||||
dojo.connect(button, "onClickCloseButton", function(){ _this.onCloseButtonClick(page); });
|
||||
if(!this._currentChild){ // put the first child into the tab order
|
||||
button.focusNode.setAttribute("tabIndex","0");
|
||||
this._currentChild = page;
|
||||
}
|
||||
},
|
||||
|
||||
onRemoveChild: function(/*Widget*/ page){
|
||||
// summary
|
||||
// Called whenever a page is removed from the container.
|
||||
// Remove the button corresponding to the page.
|
||||
if(this._currentChild === page){ this._currentChild = null; }
|
||||
var button = this.pane2button[page];
|
||||
if(button){
|
||||
// TODO? if current child { reassign }
|
||||
button.destroy();
|
||||
}
|
||||
this.pane2button[page] = null;
|
||||
},
|
||||
|
||||
onSelectChild: function(/*Widget*/ page){
|
||||
// Summary
|
||||
// Called when a page has been selected in the StackContainer, either by me or by another StackController
|
||||
|
||||
if(!page){ return; }
|
||||
|
||||
if(this._currentChild){
|
||||
var oldButton=this.pane2button[this._currentChild];
|
||||
oldButton.setChecked(false);
|
||||
oldButton.focusNode.setAttribute("tabIndex", "-1");
|
||||
}
|
||||
|
||||
var newButton=this.pane2button[page];
|
||||
newButton.setChecked(true);
|
||||
this._currentChild = page;
|
||||
newButton.focusNode.setAttribute("tabIndex", "0");
|
||||
},
|
||||
|
||||
onButtonClick: function(/*Widget*/ page){
|
||||
// summary
|
||||
// Called whenever one of my child buttons is pressed in an attempt to select a page
|
||||
var container = dijit.byId(this.containerId); // TODO: do this via topics?
|
||||
container.selectChild(page);
|
||||
},
|
||||
|
||||
onCloseButtonClick: function(/*Widget*/ page){
|
||||
// summary
|
||||
// Called whenever one of my child buttons [X] is pressed in an attempt to close a page
|
||||
var container = dijit.byId(this.containerId);
|
||||
container.closeChild(page);
|
||||
var b = this.pane2button[this._currentChild];
|
||||
if(b){
|
||||
dijit.focus(b.focusNode || b.domNode);
|
||||
}
|
||||
},
|
||||
|
||||
// TODO: this is a bit redundant with forward, back api in StackContainer
|
||||
adjacent: function(/*Boolean*/ forward){
|
||||
// find currently focused button in children array
|
||||
var children = this.getChildren();
|
||||
var current = dojo.indexOf(children, this.pane2button[this._currentChild]);
|
||||
// pick next button to focus on
|
||||
var offset = forward ? 1 : children.length - 1;
|
||||
return children[ (current + offset) % children.length ];
|
||||
},
|
||||
|
||||
onkeypress: function(/*Event*/ evt){
|
||||
// summary:
|
||||
// Handle keystrokes on the page list, for advancing to next/previous button
|
||||
// and closing the current page.
|
||||
|
||||
if(this.disabled || evt.altKey || evt.shiftKey || evt.ctrlKey){ return; }
|
||||
var forward = true;
|
||||
switch(evt.keyCode){
|
||||
case dojo.keys.LEFT_ARROW:
|
||||
case dojo.keys.UP_ARROW:
|
||||
forward=false;
|
||||
// fall through
|
||||
case dojo.keys.RIGHT_ARROW:
|
||||
case dojo.keys.DOWN_ARROW:
|
||||
this.adjacent(forward).onClick();
|
||||
dojo.stopEvent(evt);
|
||||
break;
|
||||
case dojo.keys.DELETE:
|
||||
if (this._currentChild.closable){
|
||||
this.onCloseButtonClick(this._currentChild);
|
||||
dojo.stopEvent(evt); // so we don't close a browser tab!
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
dojo.declare(
|
||||
"dijit.layout._StackButton",
|
||||
dijit.form.ToggleButton,
|
||||
{
|
||||
// summary
|
||||
// Internal widget used by StackContainer.
|
||||
// The button-like or tab-like object you click to select or delete a page
|
||||
|
||||
onClick: function(/*Event*/ evt) {
|
||||
// this is for TabContainer where the tabs are <span> rather than button,
|
||||
// so need to set focus explicitly (on some browsers)
|
||||
dijit.focus(this.focusNode);
|
||||
|
||||
// ... now let StackController catch the event and tell me what to do
|
||||
},
|
||||
|
||||
onClickCloseButton: function(/*Event*/ evt){
|
||||
// summary
|
||||
// StackContainer connects to this function; if your widget contains a close button
|
||||
// then clicking it should call this function.
|
||||
evt.stopPropagation();
|
||||
}
|
||||
});
|
||||
|
||||
// These arguments can be specified for the children of a StackContainer.
|
||||
// Since any widget can be specified as a StackContainer child, mix them
|
||||
// into the base widget class. (This is a hack, but it's effective.)
|
||||
dojo.extend(dijit._Widget, {
|
||||
// title: String
|
||||
// Title of this widget. Used by TabContainer to the name the tab, etc.
|
||||
title: "",
|
||||
|
||||
// selected: Boolean
|
||||
// Is this child currently selected?
|
||||
selected: false,
|
||||
|
||||
// closable: Boolean
|
||||
// True if user can close (destroy) this child, such as (for example) clicking the X on the tab.
|
||||
closable: false, // true if user can close this tab pane
|
||||
|
||||
onClose: function(){
|
||||
// summary: Callback if someone tries to close the child, child will be closed if func returns true
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
152
spring-faces/src/main/java/META-INF/dijit/layout/TabContainer.js
Normal file
152
spring-faces/src/main/java/META-INF/dijit/layout/TabContainer.js
Normal file
@@ -0,0 +1,152 @@
|
||||
if(!dojo._hasResource["dijit.layout.TabContainer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.layout.TabContainer"] = true;
|
||||
dojo.provide("dijit.layout.TabContainer");
|
||||
|
||||
dojo.require("dijit.layout.StackContainer");
|
||||
dojo.require("dijit._Templated");
|
||||
|
||||
dojo.declare(
|
||||
"dijit.layout.TabContainer",
|
||||
[dijit.layout.StackContainer, dijit._Templated],
|
||||
{
|
||||
// summary
|
||||
// A TabContainer is a container that has multiple panes, but shows only
|
||||
// one pane at a time. There are a set of tabs corresponding to each pane,
|
||||
// where each tab has the title (aka title) of the pane, and optionally a close button.
|
||||
//
|
||||
// Publishes topics <widgetId>-addChild, <widgetId>-removeChild, and <widgetId>-selectChild
|
||||
// (where <widgetId> is the id of the TabContainer itself.
|
||||
|
||||
// tabPosition: String
|
||||
// Defines where tabs go relative to tab content.
|
||||
// "top", "bottom", "left-h", "right-h"
|
||||
tabPosition: "top",
|
||||
|
||||
templateString: null, // override setting in StackContainer
|
||||
templateString:"<div class=\"dijitTabContainer\">\n\t<div dojoAttachPoint=\"tablistNode\"></div>\n\t<div class=\"dijitTabPaneWrapper\" dojoAttachPoint=\"containerNode\" dojoAttachEvent=\"onkeypress:_onKeyPress\" waiRole=\"tabpanel\"></div>\n</div>\n",
|
||||
|
||||
postCreate: function(){
|
||||
dijit.layout.TabContainer.superclass.postCreate.apply(this, arguments);
|
||||
// create the tab list that will have a tab (a.k.a. tab button) for each tab panel
|
||||
this.tablist = new dijit.layout.TabController(
|
||||
{
|
||||
id: this.id + "_tablist",
|
||||
tabPosition: this.tabPosition,
|
||||
doLayout: this.doLayout,
|
||||
containerId: this.id
|
||||
}, this.tablistNode);
|
||||
},
|
||||
|
||||
_setupChild: function(tab){
|
||||
dojo.addClass(tab.domNode, "dijitTabPane");
|
||||
dijit.layout.TabContainer.superclass._setupChild.apply(this, arguments);
|
||||
return tab;
|
||||
},
|
||||
|
||||
startup: function(){
|
||||
if(this._started){ return; }
|
||||
|
||||
// wire up the tablist and its tabs
|
||||
this.tablist.startup();
|
||||
dijit.layout.TabContainer.superclass.startup.apply(this, arguments);
|
||||
|
||||
if(dojo.isSafari){
|
||||
// sometimes safari 3.0.3 miscalculates the height of the tab labels, see #4058
|
||||
setTimeout(dojo.hitch(this, "layout"), 0);
|
||||
}
|
||||
},
|
||||
|
||||
layout: function(){
|
||||
// Summary: Configure the content pane to take up all the space except for where the tabs are
|
||||
if(!this.doLayout){ return; }
|
||||
|
||||
// position and size the titles and the container node
|
||||
var titleAlign=this.tabPosition.replace(/-h/,"");
|
||||
var children = [
|
||||
{domNode: this.tablist.domNode, layoutAlign: titleAlign},
|
||||
{domNode: this.containerNode, layoutAlign: "client"}
|
||||
];
|
||||
dijit.layout.layoutChildren(this.domNode, this._contentBox, children);
|
||||
|
||||
// Compute size to make each of my children.
|
||||
// children[1] is the margin-box size of this.containerNode, set by layoutChildren() call above
|
||||
this._containerContentBox = dijit.layout.marginBox2contentBox(this.containerNode, children[1]);
|
||||
|
||||
if(this.selectedChildWidget){
|
||||
this._showChild(this.selectedChildWidget);
|
||||
if(this.doLayout && this.selectedChildWidget.resize){
|
||||
this.selectedChildWidget.resize(this._containerContentBox);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
destroy: function(){
|
||||
this.tablist.destroy();
|
||||
dijit.layout.TabContainer.superclass.destroy.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
//TODO: make private?
|
||||
dojo.declare(
|
||||
"dijit.layout.TabController",
|
||||
dijit.layout.StackController,
|
||||
{
|
||||
// summary
|
||||
// Set of tabs (the things with titles and a close button, that you click to show a tab panel).
|
||||
// Lets the user select the currently shown pane in a TabContainer or StackContainer.
|
||||
// TabController also monitors the TabContainer, and whenever a pane is
|
||||
// added or deleted updates itself accordingly.
|
||||
|
||||
templateString: "<div wairole='tablist' dojoAttachEvent='onkeypress:onkeypress'></div>",
|
||||
|
||||
// tabPosition: String
|
||||
// Defines where tabs go relative to the content.
|
||||
// "top", "bottom", "left-h", "right-h"
|
||||
tabPosition: "top",
|
||||
|
||||
doLayout: true,
|
||||
|
||||
// buttonWidget: String
|
||||
// the name of the tab widget to create to correspond to each page
|
||||
buttonWidget: "dijit.layout._TabButton",
|
||||
|
||||
postMixInProperties: function(){
|
||||
this["class"] = "dijitTabLabels-" + this.tabPosition + (this.doLayout ? "" : " dijitTabNoLayout");
|
||||
dijit.layout.TabController.superclass.postMixInProperties.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
dojo.declare(
|
||||
"dijit.layout._TabButton", dijit.layout._StackButton,
|
||||
{
|
||||
// summary
|
||||
// A tab (the thing you click to select a pane).
|
||||
// Contains the title of the pane, and optionally a close-button to destroy the pane.
|
||||
// This is an internal widget and should not be instantiated directly.
|
||||
|
||||
baseClass: "dijitTab",
|
||||
|
||||
templateString: "<div baseClass='dijitTab' dojoAttachEvent='onclick:onClick,onmouseover:_onMouse,onmouseout:_onMouse'>"
|
||||
+"<div class='dijitTabInnerDiv' dojoAttachPoint='innerDiv'>"
|
||||
+"<span dojoAttachPoint='containerNode,focusNode' tabIndex='-1' waiRole='tab'>${!label}</span>"
|
||||
+"<span dojoAttachPoint='closeButtonNode' class='closeImage'"
|
||||
+" dojoAttachEvent='onmouseover:_onMouse, onmouseout:_onMouse, onclick:onClickCloseButton'"
|
||||
+" baseClass='dijitTabCloseButton'>"
|
||||
+"<span dojoAttachPoint='closeText' class='closeText'>x</span>"
|
||||
+"</span>"
|
||||
+"</div>"
|
||||
+"</div>",
|
||||
|
||||
postCreate: function(){
|
||||
if(this.closeButton){
|
||||
dojo.addClass(this.innerDiv, "dijitClosable");
|
||||
} else {
|
||||
this.closeButtonNode.style.display="none";
|
||||
}
|
||||
dijit.layout._TabButton.superclass.postCreate.apply(this, arguments);
|
||||
dojo.setSelectable(this.containerNode, false);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
if(!dojo._hasResource["dijit.layout._LayoutWidget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit.layout._LayoutWidget"] = true;
|
||||
dojo.provide("dijit.layout._LayoutWidget");
|
||||
|
||||
dojo.require("dijit._Widget");
|
||||
dojo.require("dijit._Container");
|
||||
|
||||
dojo.declare("dijit.layout._LayoutWidget",
|
||||
[dijit._Widget, dijit._Container, dijit._Contained],
|
||||
{
|
||||
// summary
|
||||
// Mixin for widgets that contain a list of children like SplitContainer.
|
||||
// Widgets which mixin this code must define layout() to lay out the children
|
||||
|
||||
isLayoutContainer: true,
|
||||
|
||||
postCreate: function(){
|
||||
dojo.addClass(this.domNode, "dijitContainer");
|
||||
},
|
||||
|
||||
startup: function(){
|
||||
// summary:
|
||||
// Called after all the widgets have been instantiated and their
|
||||
// dom nodes have been inserted somewhere under document.body.
|
||||
//
|
||||
// Widgets should override this method to do any initialization
|
||||
// dependent on other widgets existing, and then call
|
||||
// this superclass method to finish things off.
|
||||
//
|
||||
// startup() in subclasses shouldn't do anything
|
||||
// size related because the size of the widget hasn't been set yet.
|
||||
|
||||
if(this._started){ return; }
|
||||
this._started=true;
|
||||
|
||||
if(this.getChildren){
|
||||
dojo.forEach(this.getChildren(), function(child){ child.startup(); });
|
||||
}
|
||||
|
||||
// If I am a top level widget
|
||||
if(!this.getParent || !this.getParent()){
|
||||
// Do recursive sizing and layout of all my descendants
|
||||
// (passing in no argument to resize means that it has to glean the size itself)
|
||||
this.resize();
|
||||
|
||||
// since my parent isn't a layout container, and my style is width=height=100% (or something similar),
|
||||
// then I need to watch when the window resizes, and size myself accordingly
|
||||
// (passing in no argument to resize means that it has to glean the size itself)
|
||||
this.connect(window, 'onresize', function(){this.resize();});
|
||||
}
|
||||
},
|
||||
|
||||
resize: function(args){
|
||||
// summary:
|
||||
// Explicitly set this widget's size (in pixels),
|
||||
// and then call layout() to resize contents (and maybe adjust child widgets)
|
||||
//
|
||||
// args: Object?
|
||||
// {w: int, h: int, l: int, t: int}
|
||||
|
||||
var node = this.domNode;
|
||||
|
||||
// set margin box size, unless it wasn't specified, in which case use current size
|
||||
if(args){
|
||||
dojo.marginBox(node, args);
|
||||
|
||||
// set offset of the node
|
||||
if(args.t){ node.style.top = args.t + "px"; }
|
||||
if(args.l){ node.style.left = args.l + "px"; }
|
||||
}
|
||||
// If either height or width wasn't specified by the user, then query node for it.
|
||||
// But note that setting the margin box and then immediately querying dimensions may return
|
||||
// inaccurate results, so try not to depend on it.
|
||||
var mb = dojo.mixin(dojo.marginBox(node), args||{});
|
||||
|
||||
// Save the size of my content box.
|
||||
this._contentBox = dijit.layout.marginBox2contentBox(node, mb);
|
||||
|
||||
// Callback for widget to adjust size of it's children
|
||||
this.layout();
|
||||
},
|
||||
|
||||
layout: function(){
|
||||
// summary
|
||||
// Widgets override this method to size & position their contents/children.
|
||||
// When this is called this._contentBox is guaranteed to be set (see resize()).
|
||||
//
|
||||
// This is called after startup(), and also when the widget's size has been
|
||||
// changed.
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
dijit.layout.marginBox2contentBox = function(/*DomNode*/ node, /*Object*/ mb){
|
||||
// summary:
|
||||
// Given the margin-box size of a node, return it's content box size.
|
||||
// Functions like dojo.contentBox() but is more reliable since it doesn't have
|
||||
// to wait for the browser to compute sizes.
|
||||
var cs = dojo.getComputedStyle(node);
|
||||
var me=dojo._getMarginExtents(node, cs);
|
||||
var pb=dojo._getPadBorderExtents(node, cs);
|
||||
return {
|
||||
l: dojo._toPixelValue(node, cs.paddingLeft),
|
||||
t: dojo._toPixelValue(node, cs.paddingTop),
|
||||
w: mb.w - (me.w + pb.w),
|
||||
h: mb.h - (me.h + pb.h)
|
||||
};
|
||||
};
|
||||
|
||||
(function(){
|
||||
var capitalize = function(word){
|
||||
return word.substring(0,1).toUpperCase() + word.substring(1);
|
||||
};
|
||||
|
||||
var size = function(widget, dim){
|
||||
// size the child
|
||||
widget.resize ? widget.resize(dim) : dojo.marginBox(widget.domNode, dim);
|
||||
|
||||
// record child's size, but favor our own numbers when we have them.
|
||||
// the browser lies sometimes
|
||||
dojo.mixin(widget, dojo.marginBox(widget.domNode));
|
||||
dojo.mixin(widget, dim);
|
||||
};
|
||||
|
||||
dijit.layout.layoutChildren = function(/*DomNode*/ container, /*Object*/ dim, /*Object[]*/ children){
|
||||
/**
|
||||
* summary
|
||||
* Layout a bunch of child dom nodes within a parent dom node
|
||||
* container:
|
||||
* parent node
|
||||
* dim:
|
||||
* {l, t, w, h} object specifying dimensions of container into which to place children
|
||||
* children:
|
||||
* an array like [ {domNode: foo, layoutAlign: "bottom" }, {domNode: bar, layoutAlign: "client"} ]
|
||||
*/
|
||||
|
||||
// copy dim because we are going to modify it
|
||||
dim = dojo.mixin({}, dim);
|
||||
|
||||
dojo.addClass(container, "dijitLayoutContainer");
|
||||
|
||||
// set positions/sizes
|
||||
dojo.forEach(children, function(child){
|
||||
var elm = child.domNode,
|
||||
pos = child.layoutAlign;
|
||||
|
||||
// set elem to upper left corner of unused space; may move it later
|
||||
var elmStyle = elm.style;
|
||||
elmStyle.left = dim.l+"px";
|
||||
elmStyle.top = dim.t+"px";
|
||||
elmStyle.bottom = elmStyle.right = "auto";
|
||||
|
||||
dojo.addClass(elm, "dijitAlign" + capitalize(pos));
|
||||
|
||||
// set size && adjust record of remaining space.
|
||||
// note that setting the width of a <div> may affect it's height.
|
||||
if(pos=="top" || pos=="bottom"){
|
||||
size(child, { w: dim.w });
|
||||
dim.h -= child.h;
|
||||
if(pos=="top"){
|
||||
dim.t += child.h;
|
||||
}else{
|
||||
elmStyle.top = dim.t + dim.h + "px";
|
||||
}
|
||||
}else if(pos=="left" || pos=="right"){
|
||||
size(child, { h: dim.h });
|
||||
dim.w -= child.w;
|
||||
if(pos=="left"){
|
||||
dim.l += child.w;
|
||||
}else{
|
||||
elmStyle.left = dim.l + dim.w + "px";
|
||||
}
|
||||
}else if(pos=="flood" || pos=="client"){
|
||||
size(child, dim);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<div class='dijitAccordionPane'
|
||||
><div dojoAttachPoint='titleNode,focusNode' dojoAttachEvent='ondijitclick:_onTitleClick,onkeypress:_onKeyPress'
|
||||
class='dijitAccordionTitle' wairole="tab"
|
||||
><div class='dijitAccordionArrow'></div
|
||||
><div class='arrowTextUp' waiRole="presentation">▲</div
|
||||
><div class='arrowTextDown' waiRole="presentation">▼</div
|
||||
><span dojoAttachPoint='titleTextNode'>${title}</span></div
|
||||
><div><div dojoAttachPoint='containerNode' style='overflow: hidden; height: 1px; display: none'
|
||||
dojoAttachEvent='onkeypress:_onKeyPress'
|
||||
class='dijitAccordionBody' waiRole="tabpanel"
|
||||
></div></div>
|
||||
</div>
|
||||
@@ -0,0 +1,4 @@
|
||||
<div class="dijitTabContainer">
|
||||
<div dojoAttachPoint="tablistNode"></div>
|
||||
<div class="dijitTabPaneWrapper" dojoAttachPoint="containerNode" dojoAttachEvent="onkeypress:_onKeyPress" waiRole="tabpanel"></div>
|
||||
</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
<div id="${id}" class="dijitTooltipDialog" >
|
||||
<div class="dijitTooltipContainer">
|
||||
<div class ="dijitTooltipContents dijitTooltipFocusNode" dojoAttachPoint="containerNode" tabindex="0" waiRole="dialog"></div>
|
||||
</div>
|
||||
<span dojoAttachPoint="tabEnd" tabindex="0" dojoAttachEvent="focus:_cycleFocus"></span>
|
||||
<div class="dijitTooltipConnector" ></div>
|
||||
</div>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user