2012-03-28 14:37:03 +02:00
/ * *
* EGroupware clientside API : opening of windows , popups or application entries
*
* @ license http : //opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @ package etemplate
* @ subpackage api
* @ link http : //www.egroupware.org
* @ author Andreas Stöckel ( as AT stylite . de )
* @ author Ralf Becker < RalfBecker @ outdoor - training . de >
* @ version $Id$
* /
/ * e g w : u s e s
egw _core ;
egw _links ;
* /
2013-08-16 11:16:40 +02:00
/ * *
* @ augments Class
2014-10-09 11:34:24 +02:00
* @ param { object } _egw
* @ param { DOMwindow } _wnd
2013-08-16 11:16:40 +02:00
* /
2014-10-09 11:34:24 +02:00
egw . extend ( 'open' , egw . MODULE _WND _LOCAL , function ( _egw , _wnd )
{
"use strict" ;
2014-01-13 18:37:46 +01:00
2013-10-07 12:09:08 +02:00
/ * *
* Magic handling for mailto : uris using mail application .
2014-01-13 18:37:46 +01:00
*
2013-10-07 12:09:08 +02:00
* We check for open compose windows and add the address in as specified in
* the URL . If there are no open compose windows , a new one is opened . If
* there are more than one open compose window , we prompt for which one to
* use .
2014-01-13 18:37:46 +01:00
*
2013-10-07 12:09:08 +02:00
* The user must have set the 'Open EMail addresses in external mail program' preference
* to No , otherwise the browser will handle it .
2014-01-13 18:37:46 +01:00
*
2013-10-07 12:09:08 +02:00
* @ param { String } uri
* /
function mailto ( uri )
{
// Parse uri into a map
2014-01-13 18:37:46 +01:00
var match = [ ] , index ;
var mailto = uri . match ( /^mailto:([^?]+)/ ) || [ ] ;
var hashes = uri . slice ( uri . indexOf ( '?' ) + 1 ) . split ( '&' ) ;
for ( var i = 0 ; i < hashes . length ; i ++ )
2013-10-07 12:09:08 +02:00
{
2014-01-13 18:37:46 +01:00
index = hashes [ i ] . split ( '=' ) ;
match . push ( index [ 0 ] ) ;
match [ index [ 0 ] ] = index [ 1 ] ;
}
var content = {
to : mailto [ 1 ] || [ ] ,
cc : match [ 'cc' ] || [ ] ,
2014-10-09 11:34:24 +02:00
bcc : match [ 'bcc' ] || [ ]
} ;
2014-01-13 18:37:46 +01:00
2013-10-07 12:09:08 +02:00
// Get open compose windows
2015-03-02 11:23:13 +01:00
var compose = egw . getOpenWindows ( "mail" , /(^compose_)||(^mail.compose)/ ) ;
2013-10-07 12:09:08 +02:00
if ( compose . length == 0 )
{
// No compose windows, might be no mail app.js
// We really want to use mail_compose() here
2014-10-09 11:34:24 +02:00
egw . open ( '' , 'mail' , 'add' , { 'preset[mailto]' : uri } , 'compose__' , 'mail' ) ;
2013-10-07 12:09:08 +02:00
}
if ( compose . length == 1 )
{
try {
var 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 = $j ( document . createElement ( 'ul' ) ) ;
for ( var i = 0 ; i < compose . length ; i ++ )
{
var w = window . open ( '' , compose [ i ] , '100x100' ) ;
if ( w . closed ) continue ;
2013-10-10 11:37:21 +02:00
w . blur ( ) ;
2013-10-07 12:09:08 +02:00
var title = w . document . title || egw . lang ( "compose" ) ;
$j ( "<li data-window = '" + compose [ i ] + "'>" + title + "</li>" )
. click ( function ( ) {
var w = egw . open _link ( '' , $j ( 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 ( ) {
$j ( this ) . dialog ( "close" ) ;
} ;
prompt . dialog ( {
buttons : _buttons
} ) ;
}
}
2014-01-13 18:37:46 +01:00
2012-03-28 14:37:03 +02:00
return {
/ * *
* View an EGroupware entry : opens a popup of correct size or redirects window . location to requested url
2014-01-13 18:37:46 +01:00
*
* Examples :
2012-03-28 14:37:03 +02:00
* - egw . open ( 123 , 'infolog' ) or egw . open ( 'infolog:123' ) opens popup to edit or view ( if no edit rights ) infolog entry 123
* - egw . open ( 'infolog:123' , 'timesheet' , 'add' ) opens popup to add new timesheet linked to infolog entry 123
* - egw . open ( 123 , 'addressbook' , 'view' ) opens addressbook view for entry 123 ( showing linked infologs )
* - egw . open ( '' , 'addressbook' , 'view_list' , { search : 'Becker' } ) opens list of addresses containing 'Becker'
2014-01-13 18:37:46 +01:00
*
2014-10-09 11:34:24 +02:00
* @ param { string } | int | object id _data either just the id or if app == "" "app:id" or object with all data
2012-03-28 14:37:03 +02:00
* to be able to open files you need to give : ( mine - ) type , path or id , app2 and id2 ( path = / a p p s / a p p 2 / i d 2 / i d "
2014-10-09 11:34:24 +02:00
* @ param { string } app app - name or empty ( app is part of id )
* @ param { string } type default "edit" , possible "view" , "view_list" , "edit" ( falls back to "view" ) and "add"
* @ param { object | string } extra extra url parameters to append as object or string
* @ param { string } target target of window to open
* @ param { string } target _app target application to open in that tab
2015-03-18 11:36:47 +01:00
* @ param { boolean } _check _popup _blocker TRUE check if browser pop - up blocker is on / off , FALSE no check
* - This option only makes sense to be enabled when the open _link requested without user interaction
2013-08-16 11:16:40 +02:00
* @ memberOf egw
2012-03-28 14:37:03 +02:00
* /
2015-03-18 11:36:47 +01:00
open : function ( id _data , app , type , extra , target , target _app , _check _popup _blocker )
2012-03-28 14:37:03 +02:00
{
2014-01-21 10:21:46 +01:00
// Log for debugging purposes - special log tag 'navigation' always
// goes in user log, if user log is enabled
2014-02-07 15:04:12 +01:00
egw . debug ( "navigation" ,
2014-01-21 10:21:46 +01:00
"egw.open(id_data=%o, app=%s, type=%s, extra=%o, target=%s, target_app=%s)" ,
id _data , app , type , extra , target , target _app
) ;
2012-03-28 14:37:03 +02:00
var id ;
2012-04-25 18:23:27 +02:00
if ( typeof target === 'undefined' )
{
target = '_blank' ;
}
2012-03-28 14:37:03 +02:00
if ( ! app )
{
if ( typeof id _data != 'object' )
{
2012-05-17 11:26:25 +02:00
var app _id = id _data . split ( ':' , 2 ) ;
2012-03-28 14:37:03 +02:00
app = app _id [ 0 ] ;
id = app _id [ 1 ] ;
}
else
{
app = id _data . app ;
id = id _data . id ;
2013-12-07 00:12:05 +01:00
if ( typeof id _data . type != 'undefined' )
{
type = id _data . type ;
}
2012-03-28 14:37:03 +02:00
}
}
else if ( app != 'file' )
{
2012-05-17 11:26:25 +02:00
id = id _data ;
2012-03-28 14:37:03 +02:00
id _data = { 'id' : id , 'app' : app , 'extra' : extra } ;
}
var url ;
var popup ;
var params ;
if ( app == 'file' )
{
url = this . mime _open ( id _data ) ;
if ( typeof url == 'object' )
{
if ( typeof url . mime _popup != 'undefined' )
{
popup = url . mime _popup ;
delete url . mime _popup ;
}
2012-03-28 15:01:37 +02:00
if ( typeof url . mime _target != 'undefined' )
{
target = url . mime _target ;
delete url . mime _target ;
}
2015-03-25 18:48:24 +01:00
if ( typeof url . url == 'string' )
{
url = url . url ;
}
else
{
params = url ;
url = '/index.php' ;
}
2012-03-28 14:37:03 +02:00
}
}
else
{
var app _registry = this . link _get _registry ( app ) ;
2014-01-13 18:37:46 +01:00
2012-03-28 14:37:03 +02:00
if ( ! app || ! app _registry )
{
alert ( 'egw.open() app "' + app + '" NOT defined in link registry!' ) ;
2014-01-13 18:37:46 +01:00
return ;
2012-03-28 14:37:03 +02:00
}
if ( typeof type == 'undefined' ) type = 'edit' ;
if ( type == 'edit' && typeof app _registry . edit == 'undefined' ) type = 'view' ;
if ( typeof app _registry [ type ] == 'undefined' )
{
alert ( 'egw.open() type "' + type + '" is NOT defined in link registry for app "' + app + '"!' ) ;
2014-01-13 18:37:46 +01:00
return ;
2012-03-28 14:37:03 +02:00
}
url = '/index.php' ;
2014-01-20 10:48:17 +01:00
// Copy, not get a reference, or we'll change the registry
params = jQuery . extend ( { } , app _registry [ type ] ) ;
2012-03-28 14:37:03 +02:00
if ( type == 'view' || type == 'edit' ) // add id parameter for type view or edit
{
params [ app _registry [ type + '_id' ] ] = id ;
}
else if ( type == 'add' && id ) // add add_app and app_id parameters, if given for add
{
var app _id = id . split ( ':' , 2 ) ;
params [ app _registry . add _app ] = app _id [ 0 ] ;
params [ app _registry . add _id ] = app _id [ 1 ] ;
}
2014-01-13 18:37:46 +01:00
2012-03-28 14:37:03 +02:00
if ( typeof extra == 'string' )
{
url += '?' + extra ;
}
else if ( typeof extra == 'object' )
{
$j . extend ( params , extra ) ;
}
popup = app _registry [ type + '_popup' ] ;
}
2015-03-18 11:36:47 +01:00
return this . open _link ( this . link ( url , params ) , target , popup , target _app , _check _popup _blocker ) ;
2012-03-28 14:37:03 +02:00
} ,
2014-01-13 18:37:46 +01:00
2012-03-28 14:37:03 +02:00
/ * *
* Open a link , which can be either a menuaction , a EGroupware relative url or a full url
2014-01-13 18:37:46 +01:00
*
2014-10-09 11:34:24 +02:00
* @ param { string } _link menuaction , EGroupware relative url or a full url ( incl . "mailto:" or "javascript:" )
* @ param { string } _target optional target / window name
* @ param { string } _popup widthxheight , if a popup should be used
* @ param { string } _target _app app - name for opener
* @ param { boolean } _check _popup _blocker TRUE check if browser pop - up blocker is on / off , FALSE no check
2014-08-04 16:02:05 +02:00
* - This option only makes sense to be enabled when the open _link requested without user interaction
2015-03-24 10:43:38 +01:00
* @ param { string } _mime _type if given , we check if any app has registered a mime - handler for that type and use it
2012-03-28 14:37:03 +02:00
* /
2015-03-24 10:43:38 +01:00
open _link : function ( _link , _target , _popup , _target _app , _check _popup _blocker , _mime _type )
2012-03-28 14:37:03 +02:00
{
2014-01-21 10:21:46 +01:00
// Log for debugging purposes - don't use navigation here to avoid
// flooding log with details already captured by egw.open()
egw . debug ( "log" ,
"egw.open_link(_link=%s, _target=%s, _popup=%s, _target_app=%s)" ,
_link , _target , _popup , _target _app
) ;
2014-08-04 16:02:05 +02:00
//Check browser pop-up blocker
if ( _check _popup _blocker )
{
if ( this . _check _popupBlocker ( _link , _target , _popup , _target _app ) ) return ;
2014-10-09 11:34:24 +02:00
}
2012-03-28 14:37:03 +02:00
var url = _link ;
if ( url . indexOf ( 'javascript:' ) == 0 )
{
eval ( url . substr ( 11 ) ) ;
return ;
}
2013-10-07 12:09:08 +02:00
if ( url . indexOf ( 'mailto:' ) == 0 )
{
return mailto ( url ) ;
}
2012-03-28 14:37:03 +02:00
// link is not necessary an url, it can also be a menuaction!
if ( url . indexOf ( '/' ) == - 1 && url . split ( '.' ) . length >= 3 &&
! ( url . indexOf ( 'mailto:' ) == 0 || url . indexOf ( '/index.php' ) == 0 || url . indexOf ( '://' ) != - 1 ) )
{
url = "/index.php?menuaction=" + url ;
}
// append the url to the webserver url, if not already contained or empty
if ( url [ 0 ] == '/' && this . webserverUrl && this . webserverUrl != '/' && url . indexOf ( this . webserverUrl + '/' ) != 0 )
{
url = this . webserverUrl + url ;
}
2015-03-24 10:43:38 +01:00
var mime _info = _mime _type ? this . get _mime _info ( _mime _type ) : undefined ;
2015-03-25 18:48:24 +01:00
if ( mime _info && ( mime _info . mime _url || mime _info . mime _data ) )
2015-03-24 10:43:38 +01:00
{
2015-03-25 18:48:24 +01:00
var data = { } ;
for ( var attr in mime _info )
2015-03-24 10:43:38 +01:00
{
2015-03-25 18:48:24 +01:00
switch ( attr )
{
case 'mime_popup' :
_popup = mime _info . mime _popup ;
break ;
case 'mime_target' :
_target = mime _info . mime _target ;
break ;
case 'mime_type' :
data [ mime _info . mime _type ] = _mime _type ;
break ;
case 'mime_data' :
data [ mime _info [ attr ] ] = _link ;
break ;
case 'mime_url' :
data [ mime _info [ attr ] ] = url ;
break ;
default :
data [ attr ] = mime _info [ attr ] ;
break ;
}
2015-03-24 10:43:38 +01:00
}
2015-03-25 18:48:24 +01:00
url = egw . link ( '/index.php' , data ) ;
}
else if ( mime _info )
{
if ( mime _info . mime _popup ) _popup = mime _info . mime _popup ;
if ( mime _info . mime _target ) _target = mime _info . mime _target ;
2015-03-24 10:43:38 +01:00
}
2015-03-26 14:41:16 +01:00
2012-03-28 14:37:03 +02:00
if ( _popup )
{
var w _h = _popup . split ( 'x' ) ;
2014-12-01 11:44:51 +01:00
var popup _window = this . openPopup ( url , w _h [ 0 ] , w _h [ 1 ] , _target || '_blank' , _target _app , true ) ;
2014-01-13 18:37:46 +01:00
2013-10-05 11:28:12 +02:00
// Remember which windows are open
2013-10-10 11:37:21 +02:00
egw ( ) . storeWindow ( _target _app , popup _window ) ;
2014-01-13 18:37:46 +01:00
2013-10-05 11:38:22 +02:00
return popup _window ;
2012-03-28 14:37:03 +02:00
}
2014-02-07 15:04:12 +01:00
else if ( ( typeof _target == 'undefined' || _target == '_self' || typeof this . link _app _list ( ) [ _target ] != "undefined" ) )
2013-06-12 18:56:12 +02:00
{
2015-03-26 14:41:16 +01:00
// No mime type registered, set target properly based on browsing environment
if ( ! mime _info )
{
_target = egwIsMobile ( ) ? '_self' : '_blank' ;
}
2013-07-15 18:03:37 +02:00
if ( _target == '_self' )
{
// '_self' isn't allowed, but we can handle it
_target = undefined ;
}
2015-03-26 14:41:16 +01:00
else
{
return _wnd . open ( url , _target ) ;
}
2013-06-12 18:56:12 +02:00
// Use framework's link handler, if present
2014-02-07 15:04:12 +01:00
return this . link _handler ( url , _target ) ;
}
else
{
2015-03-26 14:41:16 +01:00
// No mime type registered, set target properly based on browsing environment
if ( ! mime _info )
{
_target = egwIsMobile ( ) ? '_self' : '_blank' ;
}
2014-02-07 15:04:12 +01:00
return _wnd . open ( url , _target ) ;
2013-06-12 18:56:12 +02:00
}
2014-02-07 15:04:12 +01:00
} ,
2014-12-01 11:44:51 +01:00
/ * *
* Open a ( centered ) popup window with given size and url
*
* @ param { string } _url
* @ param { number } _width
* @ param { number } _height
* @ param { string } _windowName or "_blank"
* @ param { string | boolean } _app app - name for framework to set correct opener or false for current app
* @ param { boolean } _returnID true : return window , false : return undefined
* @ param { string } _status "yes" or "no" to display status bar of popup
* @ param { boolean } _skip _framework
* @ returns { DOMWindow | undefined }
* /
openPopup : function ( _url , _width , _height , _windowName , _app , _returnID , _status , _skip _framework )
{
// Log for debugging purposes
egw . debug ( "navigation" , "openPopup(%s, %s, %s, %o, %s, %s)" , _url , _windowName , _width , _height , _status , _app ) ;
2015-02-06 17:43:36 +01:00
if ( _height == 'availHeight' ) _height = this . availHeight ( ) ;
2014-12-01 11:44:51 +01:00
// if we have a framework and we use mobile template --> let framework deal with opening popups
if ( ! _skip _framework && _wnd . framework )
{
return _wnd . framework . openPopup ( _url , _width , _height , _windowName , _app , _returnID , _status , _wnd ) ;
}
if ( typeof ( _app ) == 'undefined' ) _app = false ;
if ( typeof ( _returnID ) == 'undefined' ) _returnID = false ;
var $wnd = jQuery ( _wnd . top ) ;
var positionLeft = ( $wnd . outerWidth ( ) / 2 ) - ( _width / 2 ) + _wnd . screenX ;
var positionTop = ( $wnd . outerHeight ( ) / 2 ) - ( _height / 2 ) + _wnd . screenY ;
// IE fails, if name contains eg. a dash (-)
if ( navigator . userAgent . match ( /msie/i ) ) _windowName = ! _windowName ? '_blank' : _windowName . replace ( /[^a-zA-Z0-9_]+/ , '' ) ;
var windowID = _wnd . open ( _url , _windowName || '_blank' , "width=" + _width + ",height=" + _height +
",screenX=" + positionLeft + ",left=" + positionLeft + ",screenY=" + positionTop + ",top=" + positionTop +
",location=no,menubar=no,directories=no,toolbar=no,scrollbars=yes,resizable=yes,status=" + _status ) ;
// inject egw object
2015-03-18 11:36:47 +01:00
if ( windowID ) windowID . egw = _wnd . egw ;
2014-12-01 11:44:51 +01:00
// returning something, replaces whole window in FF, if used in link as "javascript:egw_openWindowCentered2()"
if ( _returnID !== false ) return windowID ;
} ,
2014-11-10 11:41:23 +01:00
/ * *
* Get available height of screen
* /
availHeight : function ( )
{
return screen . availHeight < screen . height ? screen . availHeight : screen . height - 100 ;
} ,
2014-02-07 15:04:12 +01:00
/ * *
* Use frameworks ( framed template ) link handler to open a url
*
* @ param { string } _url
* @ param { string } _target
* /
link _handler : function ( _url , _target )
{
2015-02-11 10:43:29 +01:00
// if url is supposed to open in admin, use admins loader to open it in it's own iframe
// (otherwise there's no tree and sidebox!)
if ( _target === 'admin' && ! _url . match ( /menuaction=admin\.admin_ui\.index/ ) )
{
_url = _url . replace ( /menuaction=([^&]+)/ , 'menuaction=admin.admin_ui.index&load=$1' ) ;
}
2014-02-07 15:04:12 +01:00
if ( _wnd . framework )
2013-09-02 15:25:00 +02:00
{
2014-02-07 15:04:12 +01:00
_wnd . framework . linkHandler ( _url , _target ) ;
2013-09-02 15:25:00 +02:00
}
2012-03-28 14:37:03 +02:00
else
{
2014-02-07 15:04:12 +01:00
_wnd . location . href = _url ;
2012-03-28 14:37:03 +02:00
}
2014-08-04 16:02:05 +02:00
} ,
2014-10-09 11:34:24 +02:00
2014-11-27 18:01:47 +01:00
/ * *
* Close current window / popup
* /
close : function ( )
{
if ( _wnd . framework && typeof _wnd . framework . popup _close == "function" )
{
_wnd . framework . popup _close ( _wnd ) ;
}
else
{
2015-01-30 16:25:47 +01:00
_wnd . close ( ) ;
2014-11-27 18:01:47 +01:00
}
} ,
2014-08-04 16:02:05 +02:00
/ * *
* Check if browser pop - up blocker is on / off
2014-10-09 11:34:24 +02:00
*
* @ param { string } _link menuaction , EGroupware relative url or a full url ( incl . "mailto:" or "javascript:" )
* @ param { string } _target optional target / window name
* @ param { string } _popup widthxheight , if a popup should be used
* @ param { string } _target _app app - name for opener
*
2014-08-04 16:02:05 +02:00
* @ return boolean returns false if pop - up blocker is off
2014-10-09 11:34:24 +02:00
* - returns true if pop - up blocker is on ,
* - and re - call the open _link with provided parameters , after user interaction .
2014-08-04 16:02:05 +02:00
* /
_check _popupBlocker : function ( _link , _target , _popup , _target _app )
{
var popup = window . open ( "" , "" , 'top=' + ( screen . height / 2 ) + ',left=' + ( screen . width / 2 ) + ',width=1,height=1,menubar=no,resizable=yes,scrollbars=yes,status=no,toolbar=no,dependent=yes' ) ;
if ( ! popup || popup == 'undefined' || popup == null )
{
et2 _dialog . show _dialog ( function ( ) {
window . egw . open _link ( _link , _target , _popup , _target _app ) ;
} , egw . lang ( "The browser popup blocker is on. Please click on OK button to see the pop-up.\n\nIf you would like to not see this message for the next time, allow your browser pop-up blocker to open popups from %1" , window . location . hostname ) ,
"Popup Blocker Warning" , { } , et2 _dialog . BUTTONS _OK , et2 _dialog . WARNING _MESSAGE ) ;
return true ;
}
else
{
popup . close ( ) ;
return false ;
}
2012-03-28 14:37:03 +02:00
}
} ;
} ) ;
2013-10-07 12:09:08 +02:00
// Add protocol handler as an option if mail handling is not forced so mail can handle mailto:
/ * N o t w o r k i n g c o n s i s t a n t l y y e t
$j ( function ( ) {
try {
if ( egw . user ( 'apps' ) . mail && ( egw . preference ( 'force_mailto' , 'addressbook' ) || true ) != '0' )
{
var params = egw . link _get _registry ( 'mail' , 'add' ) ;
if ( params )
{
params [ 'preset[mailto]' ] = '' ; // %s, but egw.link will encode it
navigator . registerProtocolHandler ( "mailto" , egw . link ( '/index.php' , params ) + '%s' , egw . lang ( 'mail' ) ) ;
}
}
} catch ( e ) { }
} ) ;
2014-11-27 18:01:47 +01:00
* /