forked from extern/egroupware
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)
|
||||
{
|
||||
var app_registry = egw.link_get_registry('mail');
|
||||
var link = egw().link("/index.php","menuaction="+app_registry['add']['menuaction']);
|
||||
var link = '';
|
||||
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++)
|
||||
{
|
||||
var idToUse = _elems[i].id;
|
||||
var idToUseArray = idToUse.split('::');
|
||||
idToUse = idToUseArray[1];
|
||||
link += "&preset[type][]="+encodeURIComponent("text/vcard; charset="+(egw.preference('vcard_charset', 'addressbook') || 'utf-8'));
|
||||
link += "&preset[file][]="+encodeURIComponent("vfs://default/apps/addressbook/"+idToUse+"/.entry");
|
||||
link += "preset[type][]="+"text/vcard; charset="+(egw.preference('vcard_charset', 'addressbook') || 'utf-8')+'&';
|
||||
link += "preset[file][]="+"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'));
|
||||
}
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
egw.openWithinWindow("mail", "setCompose", content, link, /mail.mail_compose.compose/);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -56,6 +56,9 @@ var fw_base = (function(){ "use strict"; return Class.extend(
|
||||
|
||||
// Override the egw_getAppName function
|
||||
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.popups.concat(this.registerOpenedPopus(app.name));
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
windowID.framework = this;
|
||||
this.popups.push(windowID);
|
||||
|
||||
if (navigate)
|
||||
{
|
||||
@ -802,6 +808,111 @@ var fw_base = (function(){ "use strict"; return Class.extend(
|
||||
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
|
||||
* @param {type} _app
|
||||
|
@ -55,9 +55,6 @@ egw.extend('open', egw.MODULE_WND_LOCAL, function(_egw, _wnd)
|
||||
cc: match['cc'] || [],
|
||||
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
|
||||
// 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.
|
||||
uri = uri.replace(/</g,'<').replace(/>/g,'>');
|
||||
|
||||
if(compose.length == 0)
|
||||
{
|
||||
// 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
|
||||
});
|
||||
}
|
||||
egw.openWithinWindow ("mail", "setCompose", content, {'preset[mailto]':uri}, /mail_compose.compose/);
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* 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();
|
||||
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)
|
||||
{
|
||||
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
|
||||
if(!popup.name || ['_blank'].indexOf(popup.name) >= 0)
|
||||
{
|
||||
|
@ -656,7 +656,7 @@ app.classes.mail = AppJS.extend(
|
||||
* @function
|
||||
* @memberOf mail
|
||||
*
|
||||
* @param {String} window_name The name of an open content window.
|
||||
* @param {window object} compose compose window object
|
||||
* @param {object} content
|
||||
*
|
||||
* @description content Data to set into the window's fields
|
||||
@ -666,10 +666,9 @@ app.classes.mail = AppJS.extend(
|
||||
*
|
||||
* @return {boolean} Success
|
||||
*/
|
||||
setCompose: function(window_name, content)
|
||||
setCompose: function(compose, content)
|
||||
{
|
||||
// Get window
|
||||
var compose = window.open('', window_name);
|
||||
if(!compose || compose.closed) return false;
|
||||
|
||||
// Get etemplate of popup
|
||||
|
Loading…
Reference in New Issue
Block a user