mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5282 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
444 lines
12 KiB
JavaScript
444 lines
12 KiB
JavaScript
/*
|
|
Copyright (c) 2004-2006, The Dojo Foundation
|
|
All Rights Reserved.
|
|
|
|
Licensed under the Academic Free License version 2.1 or above OR the
|
|
modified BSD license. For more information on Dojo licensing, see:
|
|
|
|
http://dojotoolkit.org/community/licensing.shtml
|
|
*/
|
|
|
|
dojo.provide("dojo.widget.Dialog");
|
|
|
|
dojo.require("dojo.widget.*");
|
|
dojo.require("dojo.widget.ContentPane");
|
|
dojo.require("dojo.event.*");
|
|
dojo.require("dojo.gfx.color");
|
|
dojo.require("dojo.html.layout");
|
|
dojo.require("dojo.html.display");
|
|
dojo.require("dojo.html.iframe");
|
|
|
|
dojo.declare(
|
|
"dojo.widget.ModalDialogBase",
|
|
null,
|
|
{
|
|
// summary
|
|
// Mixin for widgets implementing a modal dialog
|
|
|
|
isContainer: true,
|
|
|
|
// focusElement: String
|
|
// provide a focusable element or element id if you need to
|
|
// work around FF's tendency to send focus into outer space on hide
|
|
focusElement: "",
|
|
|
|
// bgColor: String
|
|
// color of viewport when displaying a dialog
|
|
bgColor: "black",
|
|
|
|
// bgOpacity: Number
|
|
// opacity (0~1) of viewport color (see bgColor attribute)
|
|
bgOpacity: 0.4,
|
|
|
|
// followScroll: Boolean
|
|
// if true, readjusts the dialog (and dialog background) when the user moves the scrollbar
|
|
followScroll: true,
|
|
|
|
// closeOnBackgroundClick: Boolean
|
|
// clicking anywhere on the background will close the dialog
|
|
closeOnBackgroundClick: false,
|
|
|
|
trapTabs: function(/*Event*/ e){
|
|
// summary
|
|
// callback on focus
|
|
if(e.target == this.tabStartOuter) {
|
|
if(this._fromTrap) {
|
|
this.tabStart.focus();
|
|
this._fromTrap = false;
|
|
} else {
|
|
this._fromTrap = true;
|
|
this.tabEnd.focus();
|
|
}
|
|
} else if (e.target == this.tabStart) {
|
|
if(this._fromTrap) {
|
|
this._fromTrap = false;
|
|
} else {
|
|
this._fromTrap = true;
|
|
this.tabEnd.focus();
|
|
}
|
|
} else if(e.target == this.tabEndOuter) {
|
|
if(this._fromTrap) {
|
|
this.tabEnd.focus();
|
|
this._fromTrap = false;
|
|
} else {
|
|
this._fromTrap = true;
|
|
this.tabStart.focus();
|
|
}
|
|
} else if(e.target == this.tabEnd) {
|
|
if(this._fromTrap) {
|
|
this._fromTrap = false;
|
|
} else {
|
|
this._fromTrap = true;
|
|
this.tabStart.focus();
|
|
}
|
|
}
|
|
},
|
|
|
|
clearTrap: function(/*Event*/ e) {
|
|
// summary
|
|
// callback on blur
|
|
var _this = this;
|
|
setTimeout(function() {
|
|
_this._fromTrap = false;
|
|
}, 100);
|
|
},
|
|
|
|
postCreate: function() {
|
|
// summary
|
|
// if the target mixin class already defined postCreate,
|
|
// dojo.widget.ModalDialogBase.prototype.postCreate.call(this)
|
|
// should be called in its postCreate()
|
|
with(this.domNode.style){
|
|
position = "absolute";
|
|
zIndex = 999;
|
|
display = "none";
|
|
overflow = "visible";
|
|
}
|
|
var b = dojo.body();
|
|
b.appendChild(this.domNode);
|
|
|
|
// make background (which sits behind the dialog but above the normal text)
|
|
this.bg = document.createElement("div");
|
|
this.bg.className = "dialogUnderlay";
|
|
with(this.bg.style){
|
|
position = "absolute";
|
|
left = top = "0px";
|
|
zIndex = 998;
|
|
display = "none";
|
|
}
|
|
b.appendChild(this.bg);
|
|
this.setBackgroundColor(this.bgColor);
|
|
|
|
this.bgIframe = new dojo.html.BackgroundIframe();
|
|
if(this.bgIframe.iframe){
|
|
with(this.bgIframe.iframe.style){
|
|
position = "absolute";
|
|
left = top = "0px";
|
|
zIndex = 90;
|
|
display = "none";
|
|
}
|
|
}
|
|
|
|
if(this.closeOnBackgroundClick){
|
|
dojo.event.kwConnect({srcObj: this.bg, srcFunc: "onclick",
|
|
adviceObj: this, adviceFunc: "onBackgroundClick", once: true});
|
|
}
|
|
},
|
|
|
|
uninitialize: function(){
|
|
this.bgIframe.remove();
|
|
dojo.html.removeNode(this.bg, true);
|
|
},
|
|
|
|
setBackgroundColor: function(/*String*/ color) {
|
|
// summary
|
|
// changes background color specified by "bgColor" parameter
|
|
// usage:
|
|
// setBackgroundColor("black");
|
|
// setBackgroundColor(0xff, 0xff, 0xff);
|
|
if(arguments.length >= 3) {
|
|
color = new dojo.gfx.color.Color(arguments[0], arguments[1], arguments[2]);
|
|
} else {
|
|
color = new dojo.gfx.color.Color(color);
|
|
}
|
|
this.bg.style.backgroundColor = color.toString();
|
|
return this.bgColor = color; // String: the color
|
|
},
|
|
|
|
setBackgroundOpacity: function(/*Number*/ op) {
|
|
// summary
|
|
// changes background opacity set by "bgOpacity" parameter
|
|
if(arguments.length == 0) { op = this.bgOpacity; }
|
|
dojo.html.setOpacity(this.bg, op);
|
|
try {
|
|
this.bgOpacity = dojo.html.getOpacity(this.bg);
|
|
} catch (e) {
|
|
this.bgOpacity = op;
|
|
}
|
|
return this.bgOpacity; // Number: the opacity
|
|
},
|
|
|
|
_sizeBackground: function() {
|
|
if(this.bgOpacity > 0) {
|
|
|
|
var viewport = dojo.html.getViewport();
|
|
var h = viewport.height;
|
|
var w = viewport.width;
|
|
with(this.bg.style){
|
|
width = w + "px";
|
|
height = h + "px";
|
|
}
|
|
var scroll_offset = dojo.html.getScroll().offset;
|
|
this.bg.style.top = scroll_offset.y + "px";
|
|
this.bg.style.left = scroll_offset.x + "px";
|
|
// process twice since the scroll bar may have been removed
|
|
// by the previous resizing
|
|
var viewport = dojo.html.getViewport();
|
|
if (viewport.width != w) { this.bg.style.width = viewport.width + "px"; }
|
|
if (viewport.height != h) { this.bg.style.height = viewport.height + "px"; }
|
|
}
|
|
this.bgIframe.size(this.bg);
|
|
},
|
|
|
|
_showBackground: function() {
|
|
if(this.bgOpacity > 0) {
|
|
this.bg.style.display = "block";
|
|
}
|
|
if(this.bgIframe.iframe){
|
|
this.bgIframe.iframe.style.display = "block";
|
|
}
|
|
},
|
|
|
|
placeModalDialog: function() {
|
|
// summary: position modal dialog in center of screen
|
|
|
|
var scroll_offset = dojo.html.getScroll().offset;
|
|
var viewport_size = dojo.html.getViewport();
|
|
|
|
// find the size of the dialog (dialog needs to be showing to get the size)
|
|
var mb;
|
|
if(this.isShowing()){
|
|
mb = dojo.html.getMarginBox(this.domNode);
|
|
}else{
|
|
dojo.html.setVisibility(this.domNode, false);
|
|
dojo.html.show(this.domNode);
|
|
mb = dojo.html.getMarginBox(this.domNode);
|
|
dojo.html.hide(this.domNode);
|
|
dojo.html.setVisibility(this.domNode, true);
|
|
}
|
|
|
|
var x = scroll_offset.x + (viewport_size.width - mb.width)/2;
|
|
var y = scroll_offset.y + (viewport_size.height - mb.height)/2;
|
|
with(this.domNode.style){
|
|
left = x + "px";
|
|
top = y + "px";
|
|
}
|
|
},
|
|
|
|
_onKey: function(/*Event*/ evt){
|
|
if (evt.key){
|
|
// see if the key is for the dialog
|
|
var node = evt.target;
|
|
while (node != null){
|
|
if (node == this.domNode){
|
|
return; // yes, so just let it go
|
|
}
|
|
node = node.parentNode;
|
|
}
|
|
// this key is for the disabled document window
|
|
if (evt.key != evt.KEY_TAB){ // allow tabbing into the dialog for a11y
|
|
dojo.event.browser.stopEvent(evt);
|
|
// opera won't tab to a div
|
|
}else if (!dojo.render.html.opera){
|
|
try {
|
|
this.tabStart.focus();
|
|
} catch(e){}
|
|
}
|
|
}
|
|
},
|
|
|
|
showModalDialog: function() {
|
|
// summary
|
|
// call this function in show() of subclass before calling superclass.show()
|
|
if (this.followScroll && !this._scrollConnected){
|
|
this._scrollConnected = true;
|
|
dojo.event.connect(window, "onscroll", this, "_onScroll");
|
|
}
|
|
dojo.event.connect(document.documentElement, "onkey", this, "_onKey");
|
|
|
|
this.placeModalDialog();
|
|
this.setBackgroundOpacity();
|
|
this._sizeBackground();
|
|
this._showBackground();
|
|
this._fromTrap = true;
|
|
|
|
// set timeout to allow the browser to render dialog
|
|
setTimeout(dojo.lang.hitch(this, function(){
|
|
try{
|
|
this.tabStart.focus();
|
|
}catch(e){}
|
|
}), 50);
|
|
|
|
},
|
|
|
|
hideModalDialog: function(){
|
|
// summary
|
|
// call this function in hide() of subclass
|
|
|
|
// workaround for FF focus going into outer space
|
|
if (this.focusElement) {
|
|
dojo.byId(this.focusElement).focus();
|
|
dojo.byId(this.focusElement).blur();
|
|
}
|
|
|
|
this.bg.style.display = "none";
|
|
this.bg.style.width = this.bg.style.height = "1px";
|
|
if(this.bgIframe.iframe){
|
|
this.bgIframe.iframe.style.display = "none";
|
|
}
|
|
|
|
dojo.event.disconnect(document.documentElement, "onkey", this, "_onKey");
|
|
if (this._scrollConnected){
|
|
this._scrollConnected = false;
|
|
dojo.event.disconnect(window, "onscroll", this, "_onScroll");
|
|
}
|
|
},
|
|
|
|
_onScroll: function(){
|
|
var scroll_offset = dojo.html.getScroll().offset;
|
|
this.bg.style.top = scroll_offset.y + "px";
|
|
this.bg.style.left = scroll_offset.x + "px";
|
|
this.placeModalDialog();
|
|
},
|
|
|
|
checkSize: function() {
|
|
if(this.isShowing()){
|
|
this._sizeBackground();
|
|
this.placeModalDialog();
|
|
this.onResized();
|
|
}
|
|
},
|
|
|
|
onBackgroundClick: function(){
|
|
// summary
|
|
// Callback on background click.
|
|
// Clicking anywhere on the background will close the dialog, but only
|
|
// if the dialog doesn't have an explicit close button, and only if
|
|
// the dialog doesn't have a blockDuration.
|
|
if(this.lifetime - this.timeRemaining >= this.blockDuration){ return; }
|
|
this.hide();
|
|
}
|
|
});
|
|
|
|
dojo.widget.defineWidget(
|
|
"dojo.widget.Dialog",
|
|
[dojo.widget.ContentPane, dojo.widget.ModalDialogBase],
|
|
{
|
|
// 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.)
|
|
|
|
templatePath: dojo.uri.dojoUri("src/widget/templates/Dialog.html"),
|
|
|
|
// blockDuration: Integer
|
|
// number of seconds for which the user cannot dismiss the dialog
|
|
blockDuration: 0,
|
|
|
|
// lifetime: Integer
|
|
// if set, this controls the number of seconds the dialog will be displayed before automatically disappearing
|
|
lifetime: 0,
|
|
|
|
// closeNode: String
|
|
// Id of button or other dom node to click to close this dialog
|
|
closeNode: "",
|
|
|
|
postMixInProperties: function(){
|
|
dojo.widget.Dialog.superclass.postMixInProperties.apply(this, arguments);
|
|
if(this.closeNode){
|
|
this.setCloseControl(this.closeNode);
|
|
}
|
|
},
|
|
|
|
postCreate: function(){
|
|
dojo.widget.Dialog.superclass.postCreate.apply(this, arguments);
|
|
dojo.widget.ModalDialogBase.prototype.postCreate.apply(this, arguments);
|
|
},
|
|
|
|
show: function() {
|
|
if(this.lifetime){
|
|
this.timeRemaining = this.lifetime;
|
|
if(this.timerNode){
|
|
this.timerNode.innerHTML = Math.ceil(this.timeRemaining/1000);
|
|
}
|
|
if(this.blockDuration && this.closeNode){
|
|
if(this.lifetime > this.blockDuration){
|
|
this.closeNode.style.visibility = "hidden";
|
|
}else{
|
|
this.closeNode.style.display = "none";
|
|
}
|
|
}
|
|
if (this.timer) {
|
|
clearInterval(this.timer);
|
|
}
|
|
this.timer = setInterval(dojo.lang.hitch(this, "_onTick"), 100);
|
|
}
|
|
|
|
this.showModalDialog();
|
|
dojo.widget.Dialog.superclass.show.call(this);
|
|
},
|
|
|
|
onLoad: function(){
|
|
// when href is specified we need to reposition
|
|
// the dialog after the data is loaded
|
|
this.placeModalDialog();
|
|
dojo.widget.Dialog.superclass.onLoad.call(this);
|
|
},
|
|
|
|
fillInTemplate: function(){
|
|
// dojo.event.connect(this.domNode, "onclick", this, "killEvent");
|
|
},
|
|
|
|
hide: function(){
|
|
this.hideModalDialog();
|
|
dojo.widget.Dialog.superclass.hide.call(this);
|
|
|
|
if(this.timer){
|
|
clearInterval(this.timer);
|
|
}
|
|
},
|
|
|
|
setTimerNode: function(node){
|
|
// summary
|
|
// specify into which node to write the remaining # of seconds
|
|
// TODO: make this a parameter too
|
|
this.timerNode = node;
|
|
},
|
|
|
|
setCloseControl: function(/*String|DomNode*/ node) {
|
|
// summary
|
|
// Specify which node is the close button for this dialog.
|
|
// If no close node is specified then clicking anywhere on the screen will close the dialog.
|
|
this.closeNode = dojo.byId(node);
|
|
dojo.event.connect(this.closeNode, "onclick", this, "hide");
|
|
},
|
|
|
|
setShowControl: function(/*String|DomNode*/ node) {
|
|
// summary
|
|
// when specified node is clicked, show this dialog
|
|
// TODO: make this a parameter too
|
|
node = dojo.byId(node);
|
|
dojo.event.connect(node, "onclick", this, "show");
|
|
},
|
|
|
|
_onTick: function(){
|
|
// summary
|
|
// callback every second that the timer clicks
|
|
if(this.timer){
|
|
this.timeRemaining -= 100;
|
|
if(this.lifetime - this.timeRemaining >= this.blockDuration){
|
|
// TODO: this block of code is executing over and over again, rather than just once
|
|
if(this.closeNode){
|
|
this.closeNode.style.visibility = "visible";
|
|
}
|
|
}
|
|
if(!this.timeRemaining){
|
|
clearInterval(this.timer);
|
|
this.hide();
|
|
}else if(this.timerNode){
|
|
this.timerNode.innerHTML = Math.ceil(this.timeRemaining/1000);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
);
|