mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-25 01:13:25 +01:00
WIP framework's popup storage/restore:
- Keep tracking of popup's window object and restore it when needed - Implement a method to check an already opened popup and execute a method in the selected popup context - Fix vcard import into opened compose windows not working
This commit is contained in:
parent
50bfc960a8
commit
a8e10cdc64
@ -769,72 +769,19 @@ app.classes.addressbook = AppJS.extend(
|
|||||||
*/
|
*/
|
||||||
adb_mail_vcard: function(_action, _elems)
|
adb_mail_vcard: function(_action, _elems)
|
||||||
{
|
{
|
||||||
var app_registry = egw.link_get_registry('mail');
|
var link = '';
|
||||||
var link = egw().link("/index.php","menuaction="+app_registry['add']['menuaction']);
|
|
||||||
var content = {vcard:{file:[], type:[]}};
|
var content = {vcard:{file:[], type:[]}};
|
||||||
|
|
||||||
// Get open compose windows
|
|
||||||
var compose = egw.getOpenWindows("mail", "(^compose_)|(^mail.compose)");
|
|
||||||
|
|
||||||
for (var i = 0; i < _elems.length; i++)
|
for (var i = 0; i < _elems.length; i++)
|
||||||
{
|
{
|
||||||
var idToUse = _elems[i].id;
|
var idToUse = _elems[i].id;
|
||||||
var idToUseArray = idToUse.split('::');
|
var idToUseArray = idToUse.split('::');
|
||||||
idToUse = idToUseArray[1];
|
idToUse = idToUseArray[1];
|
||||||
link += "&preset[type][]="+encodeURIComponent("text/vcard; charset="+(egw.preference('vcard_charset', 'addressbook') || 'utf-8'));
|
link += "preset[type][]="+"text/vcard; charset="+(egw.preference('vcard_charset', 'addressbook') || 'utf-8')+'&';
|
||||||
link += "&preset[file][]="+encodeURIComponent("vfs://default/apps/addressbook/"+idToUse+"/.entry");
|
link += "preset[file][]="+"vfs://default/apps/addressbook/"+idToUse+"/.entry"+'&';
|
||||||
content.vcard.file.push("vfs://default/apps/addressbook/"+idToUse+"/.entry");
|
content.vcard.file.push("vfs://default/apps/addressbook/"+idToUse+"/.entry");
|
||||||
content.vcard.type.push("text/vcard; charset="+(egw.preference('vcard_charset', 'addressbook') || 'utf-8'));
|
content.vcard.type.push("text/vcard; charset="+(egw.preference('vcard_charset', 'addressbook') || 'utf-8'));
|
||||||
}
|
}
|
||||||
|
egw.openWithinWindow("mail", "setCompose", content, link, /mail.mail_compose.compose/);
|
||||||
if(compose.length == 1)
|
|
||||||
{
|
|
||||||
var popup = egw.open_link('',compose[0],'100x100','mail');
|
|
||||||
popup.app.mail.setCompose(compose[0], content);
|
|
||||||
}
|
|
||||||
else if (compose.length > 1)
|
|
||||||
{
|
|
||||||
var buttons = [
|
|
||||||
{text: this.egw.lang("Add"), id: "add", "class": "ui-priority-primary", "default": true},
|
|
||||||
{text: this.egw.lang("Cancel"), id:"cancel"}
|
|
||||||
];
|
|
||||||
var c = [];
|
|
||||||
for(var i = 0; i < compose.length; i++)
|
|
||||||
{
|
|
||||||
var w = window.open('',compose[i],'100x100');
|
|
||||||
if(w.closed) continue;
|
|
||||||
w.blur();
|
|
||||||
c.push({label:w.document.title || egw.lang("compose"), compose:compose[i]});
|
|
||||||
}
|
|
||||||
et2_createWidget("dialog",
|
|
||||||
{
|
|
||||||
callback: function(_button_id, _value) {
|
|
||||||
if (_value && _value.grid)
|
|
||||||
{
|
|
||||||
switch (_button_id)
|
|
||||||
{
|
|
||||||
case "add":
|
|
||||||
var w = egw.open_link('', _value.grid.compose,'100x100','mail');
|
|
||||||
w.app.mail.setCompose(w.name, content);
|
|
||||||
return;
|
|
||||||
case "cancel":
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
title: this.egw.lang("Select an opened compose dialog"),
|
|
||||||
buttons: buttons,
|
|
||||||
value:{content:{grid:c}},
|
|
||||||
template: egw.webserverUrl+'/addressbook/templates/default/promptOpenedComposeDialog.xet?1',
|
|
||||||
resizable: false
|
|
||||||
}, et2_dialog._create_parent('addressbook'));
|
|
||||||
}
|
|
||||||
else if (typeof app_registry['view'] != 'undefined' && typeof app_registry['view_popup'] != 'undefined' )
|
|
||||||
{
|
|
||||||
var w_h =app_registry['view_popup'].split('x');
|
|
||||||
if (w_h[1] == 'egw_getWindowOuterHeight()') w_h[1] = (screen.availHeight>egw_getWindowOuterHeight()?screen.availHeight:egw_getWindowOuterHeight());
|
|
||||||
egw_openWindowCentered2(link, '_blank', w_h[0], w_h[1], 'yes');
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,6 +56,9 @@ var fw_base = (function(){ "use strict"; return Class.extend(
|
|||||||
|
|
||||||
// Override the egw_getAppName function
|
// Override the egw_getAppName function
|
||||||
window.egw_getAppName = this.egw_getAppName;
|
window.egw_getAppName = this.egw_getAppName;
|
||||||
|
|
||||||
|
// keep track of opened popups
|
||||||
|
this.popups = [];
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -133,6 +136,8 @@ var fw_base = (function(){ "use strict"; return Class.extend(
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.applications[this.appData.appName] = this.appData;
|
this.applications[this.appData.appName] = this.appData;
|
||||||
|
|
||||||
|
this.popups.concat(this.registerOpenedPopus(app.name));
|
||||||
}
|
}
|
||||||
|
|
||||||
// else display the default application
|
// else display the default application
|
||||||
@ -793,6 +798,7 @@ var fw_base = (function(){ "use strict"; return Class.extend(
|
|||||||
var windowID = egw(parentWindow).openPopup(_url, _width, _height, _windowName, _app, true, _status, true);
|
var windowID = egw(parentWindow).openPopup(_url, _width, _height, _windowName, _app, true, _status, true);
|
||||||
|
|
||||||
windowID.framework = this;
|
windowID.framework = this;
|
||||||
|
this.popups.push(windowID);
|
||||||
|
|
||||||
if (navigate)
|
if (navigate)
|
||||||
{
|
{
|
||||||
@ -802,6 +808,111 @@ var fw_base = (function(){ "use strict"; return Class.extend(
|
|||||||
if (_returnID !== false) return windowID;
|
if (_returnID !== false) return windowID;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
registerOpenedPopus: function (_app)
|
||||||
|
{
|
||||||
|
var w = Object.keys(egw.getOpenWindows(_app));
|
||||||
|
var popups = [];
|
||||||
|
var popup;
|
||||||
|
for (var i=0; i < w.length; i++)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
popup = window.open('', w[i], '100x100');
|
||||||
|
if (popup.location.href == "about:blank")
|
||||||
|
{
|
||||||
|
popup.close();
|
||||||
|
egw(window).windowClosed(_app, popup);
|
||||||
|
}
|
||||||
|
if (popup && egw.is_popup(popup)) popups.push(popup);
|
||||||
|
}catch(e)
|
||||||
|
{
|
||||||
|
if (popup)
|
||||||
|
{
|
||||||
|
popup.close();
|
||||||
|
egw.windowClosed(_app, popup);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return popups;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if given window is a "popup" alike, returning integer or undefined if not
|
||||||
|
*
|
||||||
|
* @param {DOMWindow} _wnd
|
||||||
|
* @returns {Number|undefined}
|
||||||
|
*/
|
||||||
|
popup_idx: function(_wnd)
|
||||||
|
{
|
||||||
|
if (typeof window.framework.popups != 'undefined')
|
||||||
|
{
|
||||||
|
for (var i=0; i < window.framework.popups.length; i++)
|
||||||
|
{
|
||||||
|
if (window.framework.popups[i] === _wnd)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {window} _wnd window object which suppose to be closed
|
||||||
|
*/
|
||||||
|
popup_close:function (_wnd)
|
||||||
|
{
|
||||||
|
var i = this.popup_idx(_wnd);
|
||||||
|
|
||||||
|
if (i !== undefined)
|
||||||
|
{
|
||||||
|
// Close the matched popup
|
||||||
|
this.popups.splice(i,1);
|
||||||
|
}
|
||||||
|
_wnd.close();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collect and close all already closed windowss
|
||||||
|
*/
|
||||||
|
popups_garbage_collector: function ()
|
||||||
|
{
|
||||||
|
for (var i=0; i < this.popups.length; i++)
|
||||||
|
{
|
||||||
|
if (this.popups[i].closed) this.popups.splice(i,1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get popups based on application name and regexp
|
||||||
|
* @param {string} _app app name
|
||||||
|
* @param {regexp} regex regular expression to check against location.href url
|
||||||
|
*
|
||||||
|
* @returns {Array} returns array of windows object
|
||||||
|
*/
|
||||||
|
popups_get: function(_app, regex)
|
||||||
|
{
|
||||||
|
var popups = [];
|
||||||
|
for (var i=0; i < this.popups.length; i++)
|
||||||
|
{
|
||||||
|
if (!this.popups[i].closed && this.popups[i].egw_appName == _app) {
|
||||||
|
popups.push(this.popups[i]);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (regex)
|
||||||
|
{
|
||||||
|
for (var j=0; j < popups.length; j++)
|
||||||
|
{
|
||||||
|
if (!popups[j].location.href.match(regex))
|
||||||
|
{
|
||||||
|
popups.splice(j,1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return popups;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get application window
|
* Get application window
|
||||||
* @param {type} _app
|
* @param {type} _app
|
||||||
|
@ -55,9 +55,6 @@ egw.extend('open', egw.MODULE_WND_LOCAL, function(_egw, _wnd)
|
|||||||
cc: match['cc'] || [],
|
cc: match['cc'] || [],
|
||||||
bcc: match['bcc'] || []
|
bcc: match['bcc'] || []
|
||||||
};
|
};
|
||||||
var popup;
|
|
||||||
// Get open compose windows
|
|
||||||
var compose = egw.getOpenWindows("mail", /(^compose_)||(^mail.compose)/);
|
|
||||||
|
|
||||||
// Encode html entities in the URI, otheerwise server XSS protection wont
|
// Encode html entities in the URI, otheerwise server XSS protection wont
|
||||||
// allow it to pass, because it may get mistaken for some forbiden tags,
|
// allow it to pass, because it may get mistaken for some forbiden tags,
|
||||||
@ -65,82 +62,8 @@ egw.extend('open', egw.MODULE_WND_LOCAL, function(_egw, _wnd)
|
|||||||
// including "<" would get mistaken for <math> tag, and server will cut it off.
|
// including "<" would get mistaken for <math> tag, and server will cut it off.
|
||||||
uri = uri.replace(/</g,'<').replace(/>/g,'>');
|
uri = uri.replace(/</g,'<').replace(/>/g,'>');
|
||||||
|
|
||||||
if(compose.length == 0)
|
egw.openWithinWindow ("mail", "setCompose", content, {'preset[mailto]':uri}, /mail_compose.compose/);
|
||||||
{
|
|
||||||
// No compose windows, might be no mail app.js
|
|
||||||
// We really want to use mail_compose() here
|
|
||||||
|
|
||||||
// Accoring to microsoft, IE 10/11 can only accept a url with 2083 caharacters
|
|
||||||
// therefore we need to send request to compose window with POST method
|
|
||||||
// instead of GET. We create a temporary <Form> and will post emails.
|
|
||||||
// ** WebServers and other browsers also have url length limit:
|
|
||||||
// Firefox:~ 65k, Safari:80k, Chrome: 2MB, Apache: 4k, Nginx: 4k
|
|
||||||
if (uri.length > 2083)
|
|
||||||
{
|
|
||||||
popup = egw.open('','mail','add','','compose__','mail');
|
|
||||||
var $tmpForm = jQuery(document.createElement('form')).appendTo('body');
|
|
||||||
var $tmpInput = jQuery(document.createElement('input')).attr({name:"preset[mailto]", type:"text", value: uri});
|
|
||||||
var $tmpSubmitInput = jQuery(document.createElement('input')).attr({type:"submit"});
|
|
||||||
// Set the temporary form's attributes
|
|
||||||
$tmpForm.attr({target:popup.name, action:"index.php?menuaction=mail.mail_compose.compose", method:"post"})
|
|
||||||
.append($tmpInput)
|
|
||||||
.append($tmpSubmitInput);
|
|
||||||
$tmpForm.submit();
|
|
||||||
// Remove the form after submit
|
|
||||||
$tmpForm.remove();
|
|
||||||
}
|
|
||||||
else // simple GET request
|
|
||||||
{
|
|
||||||
egw.open('','mail','add',{'preset[mailto]': uri},'compose__','mail');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(compose.length == 1)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
popup = egw.open_link('',compose[0],'100x100','mail');
|
|
||||||
popup.app.mail.setCompose(compose[0], content);
|
|
||||||
} catch(e) {
|
|
||||||
// Looks like a leftover window that wasn't removed from the list
|
|
||||||
egw.debug("warn", e.message);
|
|
||||||
popup.close();
|
|
||||||
egw.windowClosed("mail",popup);
|
|
||||||
window.setTimeout(function() {
|
|
||||||
egw.open_link(uri);
|
|
||||||
console.debug("Trying again with ", uri);
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(compose.length > 1)
|
|
||||||
{
|
|
||||||
// Need to prompt
|
|
||||||
var prompt = jQuery(document.createElement('ul'));
|
|
||||||
for(var i = 0; i < compose.length; i++)
|
|
||||||
{
|
|
||||||
var w = window.open('',compose[i],'100x100');
|
|
||||||
if(w.closed) continue;
|
|
||||||
w.blur();
|
|
||||||
var title = w.document.title || egw.lang("compose");
|
|
||||||
jQuery("<li data-window = '" + compose[i] + "'>"+ title + "</li>")
|
|
||||||
.click(function() {
|
|
||||||
var w = egw.open_link('',jQuery(this).attr("data-window"),'100x100','mail');
|
|
||||||
w.app.mail.setCompose(w.name, content);
|
|
||||||
prompt.dialog("close");
|
|
||||||
})
|
|
||||||
.appendTo(prompt);
|
|
||||||
}
|
|
||||||
_wnd.setTimeout(function() {
|
|
||||||
this.focus();
|
|
||||||
}, 200);
|
|
||||||
var _buttons = {};
|
|
||||||
_buttons[egw.lang("cancel")] = function() {
|
|
||||||
jQuery(this).dialog("close");
|
|
||||||
};
|
|
||||||
prompt.dialog({
|
|
||||||
buttons: _buttons
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
/**
|
/**
|
||||||
* View an EGroupware entry: opens a popup of correct size or redirects window.location to requested url
|
* View an EGroupware entry: opens a popup of correct size or redirects window.location to requested url
|
||||||
@ -509,6 +432,103 @@ egw.extend('open', egw.MODULE_WND_LOCAL, function(_egw, _wnd)
|
|||||||
popup.close();
|
popup.close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function helps to append content/ run commands into an already
|
||||||
|
* opened popup window. Popup winodws now are getting stored in framework
|
||||||
|
* object and can be retrived/closed from framework.
|
||||||
|
*
|
||||||
|
* @param {string} _app name of application to be requested its popups
|
||||||
|
* @param {string} _method application method implemented in app.js
|
||||||
|
* @param {object} _content content to be passed to method
|
||||||
|
* @param {string|object} _extra url or object of extra
|
||||||
|
* @param {regex} _regexp regular expression to get specific popup with matched url
|
||||||
|
*/
|
||||||
|
openWithinWindow: function (_app, _method, _content, _extra, _regexp)
|
||||||
|
{
|
||||||
|
var popups = window.framework.popups_get(_app, _regexp);
|
||||||
|
|
||||||
|
for(var i = 0; i < popups.length; i++)
|
||||||
|
{
|
||||||
|
if(popups[i].closed)
|
||||||
|
{
|
||||||
|
window.framework.popups_grabage_collector();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(popups.length == 1)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
popups[0].app[_app][_method](popups[0], _content);
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
|
window.setTimeout(function() {
|
||||||
|
egw.open('', _app, 'add', _extra, _app, _app);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (popups.length > 1)
|
||||||
|
{
|
||||||
|
var buttons = [
|
||||||
|
{text: this.lang("Add"), id: "add", "class": "ui-priority-primary", "default": true},
|
||||||
|
{text: this.lang("Cancel"), id:"cancel"}
|
||||||
|
];
|
||||||
|
var c = [];
|
||||||
|
for(var i = 0; i < popups.length; i++)
|
||||||
|
{
|
||||||
|
c.push({label:popups[i].document.title || this.lang(_app), index:i});
|
||||||
|
}
|
||||||
|
et2_createWidget("dialog",
|
||||||
|
{
|
||||||
|
callback: function(_button_id, _value) {
|
||||||
|
if (_value && _value.grid)
|
||||||
|
{
|
||||||
|
switch (_button_id)
|
||||||
|
{
|
||||||
|
case "add":
|
||||||
|
popups[_value.grid.index].app[_app][_method](popups[_value.grid.index], _content);
|
||||||
|
return;
|
||||||
|
case "cancel":
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
title: this.lang("Select an opened dialog"),
|
||||||
|
buttons: buttons,
|
||||||
|
value:{content:{grid:c}},
|
||||||
|
template: this.webserverUrl+'/api/templates/default/promptOpenedDialog.xet?1',
|
||||||
|
resizable: false
|
||||||
|
}, et2_dialog._create_parent(this.app_name()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// No compose windows, might be no mail app.js
|
||||||
|
// We really want to use mail_compose() here
|
||||||
|
|
||||||
|
// Accoring to microsoft, IE 10/11 can only accept a url with 2083 caharacters
|
||||||
|
// therefore we need to send request to compose window with POST method
|
||||||
|
// instead of GET. We create a temporary <Form> and will post emails.
|
||||||
|
// ** WebServers and other browsers also have url length limit:
|
||||||
|
// Firefox:~ 65k, Safari:80k, Chrome: 2MB, Apache: 4k, Nginx: 4k
|
||||||
|
if (_extra.length > 2083)
|
||||||
|
{
|
||||||
|
var popup = egw.open('', _app, 'add', '', '', _app);
|
||||||
|
var $tmpForm = jQuery(document.createElement('form')).appendTo('body');
|
||||||
|
var $tmpInput = jQuery(document.createElement('input')).attr({name:Object.keys(_extra)[0], type:"text", value: _extra});
|
||||||
|
var $tmpSubmitInput = jQuery(document.createElement('input')).attr({type:"submit"});
|
||||||
|
// Set the temporary form's attributes
|
||||||
|
$tmpForm.attr({target:popup.name, action:"index.php?menuaction=mail.mail_compose.compose", method:"post"})
|
||||||
|
.append($tmpInput)
|
||||||
|
.append($tmpSubmitInput);
|
||||||
|
$tmpForm.submit();
|
||||||
|
// Remove the form after submit
|
||||||
|
$tmpForm.remove();
|
||||||
|
}
|
||||||
|
else // simple GET request
|
||||||
|
{
|
||||||
|
egw.open('', _app, 'add', _extra, _app, _app);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -270,6 +270,12 @@ egw.extend('utils', egw.MODULE_GLOBAL, function()
|
|||||||
*/
|
*/
|
||||||
storeWindow: function(appname, popup)
|
storeWindow: function(appname, popup)
|
||||||
{
|
{
|
||||||
|
if (popup.opener) popup.opener.framework.popups_garbage_collector();
|
||||||
|
if (popup.opener && popup.opener.framework && egw.is_popup(popup)
|
||||||
|
&& typeof popup.opener.framework.popup_idx(popup) == 'undefined')
|
||||||
|
{
|
||||||
|
popup.opener.framework.popups.push(popup);
|
||||||
|
}
|
||||||
// Don't store if it has no name
|
// Don't store if it has no name
|
||||||
if(!popup.name || ['_blank'].indexOf(popup.name) >= 0)
|
if(!popup.name || ['_blank'].indexOf(popup.name) >= 0)
|
||||||
{
|
{
|
||||||
|
@ -656,7 +656,7 @@ app.classes.mail = AppJS.extend(
|
|||||||
* @function
|
* @function
|
||||||
* @memberOf mail
|
* @memberOf mail
|
||||||
*
|
*
|
||||||
* @param {String} window_name The name of an open content window.
|
* @param {window object} compose compose window object
|
||||||
* @param {object} content
|
* @param {object} content
|
||||||
*
|
*
|
||||||
* @description content Data to set into the window's fields
|
* @description content Data to set into the window's fields
|
||||||
@ -666,10 +666,9 @@ app.classes.mail = AppJS.extend(
|
|||||||
*
|
*
|
||||||
* @return {boolean} Success
|
* @return {boolean} Success
|
||||||
*/
|
*/
|
||||||
setCompose: function(window_name, content)
|
setCompose: function(compose, content)
|
||||||
{
|
{
|
||||||
// Get window
|
// Get window
|
||||||
var compose = window.open('', window_name);
|
|
||||||
if(!compose || compose.closed) return false;
|
if(!compose || compose.closed) return false;
|
||||||
|
|
||||||
// Get etemplate of popup
|
// Get etemplate of popup
|
||||||
|
Loading…
Reference in New Issue
Block a user