@ -63,7 +63,8 @@ function rcube_webmail()
recipients _separator : ',' , // @deprecated
recipients _delimiter : ', ' , // @deprecated
popup _width : 1150 ,
popup _width _small : 900
popup _width _small : 900 ,
thread _padding : '15px'
} ;
// create protected reference to myself
@ -115,7 +116,7 @@ function rcube_webmail()
this . buttons [ command ] . push ( button _prop ) ;
if ( this . loaded )
init _button ( command , button _prop ) ;
this . init _button ( command , button _prop ) ;
} ;
// register a specific gui object
@ -282,8 +283,7 @@ function rcube_webmail()
} , this . env . mail _read _time * 1000 ) ;
if ( this . env . blockedobjects ) {
if ( this . gui _objects . remoteobjectsmsg )
this . gui _objects . remoteobjectsmsg . style . display = 'block' ;
$ ( this . gui _objects . remoteobjectsmsg ) . show ( ) ;
this . enable _command ( 'load-remote' , true ) ;
}
@ -720,14 +720,18 @@ function rcube_webmail()
// check input before leaving compose step
if ( this . task == 'mail' && this . env . action == 'compose' && ! this . env . server _error && command != 'save-pref'
&& $ . inArray ( command , this . env . compose _commands ) < 0
&& $ . inArray ( command , this . env . compose _commands ) < 0 && ! this . compose _skip _unsavedcheck
) {
if ( ! this . env . is _sent && this . cmp _hash != this . compose _field _hash ( ) && ! confirm ( this . get _label ( 'notsentwarning' ) ) )
return false ;
if ( ! this . env . is _sent && this . cmp _hash != this . compose _field _hash ( ) ) {
this . confirm _dialog ( this . get _label ( 'notsentwarning' ) , 'discard' , function ( ) {
// remove copy from local storage if compose screen is left intentionally
ref . remove _compose _data ( ref . env . compose _id ) ;
ref . compose _skip _unsavedcheck = true ;
ref . command ( command , props , obj , event ) ;
} ) ;
// remove copy from local storage if compose screen is left intentionally
this . remove _compose _data ( this . env . compose _id ) ;
this . compose _skip _unsavedcheck = true ;
return false ;
}
}
this . last _command = command ;
@ -944,8 +948,9 @@ function rcube_webmail()
if ( form ) {
// user prefs
if ( ( input = $ ( "[name='_pagesize']" , form ) ) && input . length && isNaN ( parseInt ( input . val ( ) ) ) ) {
alert ( this . get _label ( 'nopagesizewarning' ) ) ;
input . focus ( ) ;
this . alert _dialog ( this . get _label ( 'nopagesizewarning' ) , function ( ) {
input . focus ( ) ;
} ) ;
break ;
}
// contacts/identities
@ -957,8 +962,9 @@ function rcube_webmail()
else if ( this . task == 'settings' && ( this . env . identities _level % 2 ) == 0 &&
( input = $ ( "[name='_email']" , form ) ) && input . length && ! rcube _check _email ( input . val ( ) )
) {
alert ( this . get _label ( 'noemailwarning' ) ) ;
input . focus ( ) ;
this . alert _dialog ( this . get _label ( 'noemailwarning' ) , function ( ) {
input . focus ( ) ;
} ) ;
break ;
}
}
@ -1199,7 +1205,7 @@ function rcube_webmail()
if ( ! ( flag = this . upload _file ( props || this . gui _objects . uploadform , 'upload' ) ) ) {
if ( flag !== false )
alert ( this . get _label ( 'selectimportfile' ) ) ;
this . alert _dialog ( this . get _label ( 'selectimportfile' ) ) ;
aborted = true ;
}
break ;
@ -1351,7 +1357,7 @@ function rcube_webmail()
if ( ! ( flag = this . upload _file ( form , 'import' , importlock ) ) ) {
this . set _busy ( false , null , importlock ) ;
if ( flag !== false )
alert ( this . get _label ( 'selectimportfile' ) ) ;
this . alert _dialog ( this . get _label ( 'selectimportfile' ) ) ;
aborted = true ;
}
break ;
@ -1366,7 +1372,7 @@ function rcube_webmail()
if ( form ) {
var lock , file = win . $ ( '#rcmimportfile' ) [ 0 ] ;
if ( file && ! file . value ) {
alert( win . rcmail . get _label ( 'selectimportfile' ) ) ;
win. rcmail . alert_dialog ( win . rcmail . get _label ( 'selectimportfile' ) ) ;
return ;
}
@ -1548,22 +1554,28 @@ function rcube_webmail()
// Add variable to GET string, replace old value if exists
this . add _url = function ( url , name , value )
{
var urldata , datax , hash = '' ;
value = urlencode ( value ) ;
if ( /(#[a-z0-9_-]+)$/ . test ( url ) ) {
hash = RegExp . $1 ;
url = url . substr ( 0 , url . length - hash . length ) ;
}
if ( /(\?.*)$/ . test ( url ) ) {
var urldata = RegExp . $1 ,
datax = RegExp ( '((\\?|&)' + RegExp . escape ( name ) + '=[^&]*)' ) ;
urldata = RegExp . $1 ;
datax = RegExp ( '((\\?|&)' + RegExp . escape ( name ) + '=[^&]*)' ) ;
if ( datax . test ( urldata ) ) {
if ( datax . test ( urldata ) )
urldata = urldata . replace ( datax , RegExp . $2 + name + '=' + value ) ;
}
else
urldata += '&' + name + '=' + value
urldata += '&' + name + '=' + value ;
return url . replace ( /(\?.*)$/ , urldata ) ;
return url . replace ( /(\?.*)$/ , urldata ) + hash ;
}
return url + '?' + name + '=' + value ;
return url + '?' + name + '=' + value + hash ;
} ;
// append CSRF protection token to the given url
@ -2319,13 +2331,20 @@ function rcube_webmail()
} ) ;
if ( this . env . threading && message . depth ) {
$ ( 'td.subject' , domrow ) . attr ( 'style' , 'padding-left:' + Math . min ( 90 , message . depth * 15 ) + 'px !important' ) ;
n = this . calculate _thread _padding ( message . depth ) ;
$ ( 'td.subject' , domrow ) . attr ( 'style' , 'padding-left:' + n + ' !important' ) ;
$ ( 'span.branch' , domrow ) . remove ( ) ;
}
return domrow ;
} ;
this . calculate _thread _padding = function ( level )
{
ref . env . thread _padding . match ( /^([0-9.]+)(.+)/ ) ;
return ( Math . min ( 6 , level ) * parseFloat ( RegExp . $1 ) ) + RegExp . $2 ;
} ;
this . set _list _sorting = function ( sort _col , sort _order )
{
var sort _old = this . env . sort _col == 'arrival' ? 'date' : this . env . sort _col ,
@ -3142,8 +3161,9 @@ function rcube_webmail()
else {
// if shift was pressed delete it immediately
if ( ( list && list . modkey == SHIFT _KEY ) || ( event && rcube _event . get _modifier ( event ) == SHIFT _KEY ) ) {
if ( confirm ( this . get _label ( 'deletemessagesconfirm' ) ) )
this . permanently _remove _messages ( ) ;
this . confirm _dialog ( this . get _label ( 'deletemessagesconfirm' ) , 'delete' , function ( ) {
ref . permanently _remove _messages ( ) ;
} ) ;
}
else
this . move _messages ( trash ) ;
@ -3522,7 +3542,7 @@ function rcube_webmail()
// go to specified page
var p = parseInt ( this . value ) ;
if ( p && p != ref . env . current _page && ! ref . busy ) {
ref . hide _menu ( 'pagejump-selector' );
ref . hide _menu ( 'pagejump-selector' , e );
ref . list _page ( p ) ;
}
} ) ;
@ -3691,7 +3711,7 @@ function rcube_webmail()
// notify user about loosing attachments
if ( ref . env . attachments && ! $ . isEmptyObject ( ref . env . attachments ) ) {
alert( ref . get _label ( 'encryptnoattachments' ) ) ;
ref. alert_dialog ( ref . get _label ( 'encryptnoattachments' ) ) ;
$ . each ( ref . env . attachments , function ( name , attach ) {
ref . remove _from _attachment _list ( name ) ;
@ -3748,8 +3768,9 @@ function rcube_webmail()
if ( ! isvalid ) {
if ( ! recipients . length ) {
alert ( ref . get _label ( 'norecipientwarning' ) ) ;
$ ( "[name='_to']" ) . focus ( ) ;
ref . alert _dialog ( ref . get _label ( 'norecipientwarning' ) , function ( ) {
$ ( "[name='_to']" ) . focus ( ) ;
} ) ;
}
return false ;
}
@ -3940,11 +3961,10 @@ function rcube_webmail()
} ) ;
li . append ( ul _ ) ;
li . append ( $ ( '<input>' )
. attr ( 'type' , 'button' )
li . append ( $ ( '<button>' )
. attr ( 'rel' , keyrec . keyid )
. a ttr ( 'value' , ref . get _label ( 'import' ) )
. addClass ( 'button import key')
. tex t( ref . get _label ( 'import' ) )
. addClass ( 'button import import key')
. prop ( 'disabled' , keyrec . revoked || keyrec . disabled || keyrec . expired ) ) ;
ul . append ( li ) ;
@ -3961,7 +3981,7 @@ function rcube_webmail()
) ;
// delegate handler for import button clicks
ul . on ( 'click' , ' input. button.importkey', function ( ) {
ul . on ( 'click' , ' button.importkey', function ( ) {
var btn = $ ( this ) ,
keyid = btn . attr ( 'rel' ) ,
pk = new PublicKey ( ) ,
@ -3984,7 +4004,7 @@ function rcube_webmail()
// import to keyring
ref . mailvelope _keyring . importPublicKey ( armored ) . then ( function ( status ) {
if ( status === 'REJECTED' ) {
// alert(ref.get_label('Key import was rejected'));
// ref. alert_dialog (ref.get_label('Key import was rejected'));
}
else {
var $key = keyid . substr ( - 8 ) . toUpperCase ( ) ;
@ -4022,19 +4042,20 @@ function rcube_webmail()
this . purge _mailbox = function ( mbox )
{
var lock , post _data = { _mbox : mbox } ;
this . confirm _dialog ( this . get _label ( 'purgefolderconfirm' ) , 'delete' , function ( ) {
var lock , post _data = { _mbox : mbox } ;
if ( ! confirm ( this . get _label ( 'purgefolderconfirm' ) ) )
return false ;
// lock interface if it's the active mailbox
if ( mbox == ref . env . mailbox ) {
lock = ref . set _busy ( true , 'loading' ) ;
post _data . _reload = 1 ;
}
// lock interface if it's the active mailbox
if ( mbox == this . env . mailbox ) {
lock = this . set _busy ( true , 'loading' ) ;
post _data . _reload = 1 ;
}
// send request to server
ref . http _post ( 'purge' , post _data , lock ) ;
} ) ;
// send request to server
this . http _post ( 'purge' , post _data , lock ) ;
return false ;
} ;
// test if purge command is allowed
@ -4503,7 +4524,7 @@ function rcube_webmail()
// check if all files has been uploaded
for ( key in this . env . attachments ) {
if ( typeof this . env . attachments [ key ] === 'object' && ! this . env . attachments [ key ] . complete ) {
alert ( this . get _label ( 'notuploadedwarning' ) ) ;
this . alert _dialog ( this . get _label ( 'notuploadedwarning' ) ) ;
return false ;
}
}
@ -4585,15 +4606,17 @@ function rcube_webmail()
// check sender (if have no identities)
if ( input _from . prop ( 'type' ) == 'text' && ! rcube _check _email ( input _from . val ( ) , true ) ) {
alert ( this . get _label ( 'nosenderwarning' ) ) ;
input _from . focus ( ) ;
this . alert _dialog ( this . get _label ( 'nosenderwarning' ) , function ( ) {
input _from . focus ( ) ;
} ) ;
return false ;
}
// check for empty recipient
if ( ! rcube _check _email ( get _recipients ( [ input _to , input _cc , input _bcc ] ) , true ) ) {
alert ( this . get _label ( 'norecipientwarning' ) ) ;
input _to . focus ( ) ;
this . alert _dialog ( this . get _label ( 'norecipientwarning' ) , function ( ) {
input _to . focus ( ) ;
} ) ;
return false ;
}
@ -4750,8 +4773,10 @@ function rcube_webmail()
}
// submit delete request
if ( key && confirm ( this . get _label ( 'deleteresponseconfirm' ) ) ) {
this . http _post ( 'settings/delete-response' , { _key : key } , false ) ;
if ( key ) {
this . confirm _dialog ( this . get _label ( 'deleteresponseconfirm' ) , 'delete' , function ( ) {
ref . http _post ( 'settings/delete-response' , { _key : key } , false ) ;
} ) ;
}
} ;
@ -5158,14 +5183,16 @@ function rcube_webmail()
if ( ! this . gui _objects . attachmentlist )
return false ;
var label , indicator , li = $ ( '<li>' ) ;
if ( ! att . complete && this . env . loadingicon )
att . html = '<img src="' + this . env . loadingicon + '" alt="" class="uploading" />' + att . html ;
if ( ! att . complete && att . frame )
att. html = '<a title="' + this . get _label ( 'cancel' ) + '" onclick="return rcmail.cancel_attachment_upload(\'' + name + '\', \'' + att .frame + '\') ;" href="#cancelupload" class="cancelupload">'
+ ( this . env . cancelicon ? '<img src="' + this . env . cancelicon + '" alt="' + this . get _label ( 'cancel' ) + '" />' : this . get _label ( 'cancel' ) ) + '</a>' + att . html ;
var indicator , li = $ ( '<li>' ) ;
if ( ! att . complete && att . frame ) {
label = this . get _label ( 'cancel' ) ;
att . html = '<a title="' + label + '" onclick="return rcmail.cancel_attachment_upload(\'' + name + '\', \'' + att . frame + '\');" href="#cancelupload" class="cancelupload">'
+ ( this . env . cancelicon ? '<img src="' + this . env . cancelicon + '" alt="' + label + '" />' : '<span class="inner">' + label + '</span>' ) + '</a>' + att . html ;
}
li . attr ( 'id' , name )
. addClass ( att . classname )
@ -5756,33 +5783,19 @@ function rcube_webmail()
this . ksearch _data . num -- ;
} ;
// Getter for input value (with support for non-input content-editable elements)
// returns a string from last comma to current cursor position
// Getter for input value
// returns a string from the last comma to current cursor position
this . ksearch _input _get = function ( )
{
if ( ! this . ksearch _input )
return '' ;
var sel, range , sp , cp = 0 , value = '' ;
var cp = this . get _caret _pos ( this . ksearch _input ) ;
if ( this . ksearch _input . value === undefined ) {
if ( ( sel = window . getSelection ( ) ) && ( range = sel . getRangeAt ( 0 ) ) ) {
value = $ ( range . endContainer ) . text ( ) ;
cp = range . endOffset ;
}
else {
value = $ ( this . ksearch _input ) . text ( ) ;
}
}
else {
cp = this . get _caret _pos ( this . ksearch _input ) ;
value = this . ksearch _input . value ;
}
return value . substr ( 0 , cp ) . split ( /[,;]/ ) . pop ( ) ;
return this . ksearch _input . value . substr ( 0 , cp ) . split ( /[,;]/ ) . pop ( ) ;
} ;
// Setter for input value (with support for non-input content-editable elements)
// Setter for input value
// replaces 'from' string with 'to' and sets cursor position at the end
this . ksearch _input _replace = function ( from , to , input )
{
@ -5792,24 +5805,15 @@ function rcube_webmail()
if ( ! input )
input = this . ksearch _input ;
if ( input . value === undefined ) {
var node = $ ( input ) . contents ( ) . filter ( function ( ) { return this . nodeType == 3 ; } ) . last ( ) ;
// here we assume there's only one text node
if ( node . length ) {
$ ( node ) [ 0 ] . textContent = to ;
}
}
else {
var cpos = this . get _caret _pos ( input ) ,
p = input . value . lastIndexOf ( from , cpos ) ,
pre = input . value . substring ( 0 , p ) ,
end = input . value . substring ( p + from . length , input . value . length ) ;
var cpos = this . get _caret _pos ( input ) ,
p = input . value . lastIndexOf ( from , cpos ) ,
pre = input . value . substring ( 0 , p ) ,
end = input . value . substring ( p + from . length , input . value . length ) ;
input . value = pre + to + end ;
input . value = pre + to + end ;
// set caret to insert pos
this . set _caret _pos ( input , p + to . length ) ;
}
// set caret to insert pos
this . set _caret _pos ( input , p + to . length ) ;
// run onchange action on the element
$ ( input ) . change ( ) ;
@ -6215,10 +6219,11 @@ function rcube_webmail()
{
var undelete = this . env . source && this . env . address _sources [ this . env . source ] . undelete ;
if ( ! undelete && ! confirm ( this . get _label ( 'deletecontactconfirm' ) ) )
return ;
return this . _with _selected _contacts ( 'delete' ) ;
if ( ! undelete ) {
this . confirm _dialog ( this . get _label ( 'deletecontactconfirm' ) , 'delete' , function ( ) {
ref . _with _selected _contacts ( 'delete' ) ;
} ) ;
}
} ;
this . _with _selected _contacts = function ( action , post _data )
@ -6400,9 +6405,11 @@ function rcube_webmail()
this . group _delete = function ( )
{
if ( this . env . group && confirm ( this . get _label ( 'deletegroupconfirm' ) ) ) {
var lock = this . set _busy ( true , 'groupdeleting' ) ;
this . http _post ( 'group-delete' , { _source : this . env . source , _gid : this . env . group } , lock ) ;
if ( this . env . group ) {
this . confirm _dialog ( this . get _label ( 'deletegroupconfirm' ) , 'delete' , function ( ) {
var lock = ref . set _busy ( true , 'groupdeleting' ) ;
ref . http _post ( 'group-delete' , { _source : ref . env . source , _gid : ref . env . group } , lock ) ;
} ) ;
}
} ;
@ -6515,20 +6522,21 @@ function rcube_webmail()
if ( ! elem )
elem = $ ( '.ff_' + col ) ;
if ( label )
if ( label && ! $ ( 'label[for="ff_' + col + '"]' ) . length )
elem . placeholder ( label ) ;
} ;
this . insert _edit _field = function ( col , section , menu )
{
// just make pre-defined input field visible
var elem = $ ( '#ff_' + col ) ;
var elem = $ ( '#ff_' + col ) ;
if ( elem . length ) {
$ ( 'label[for="ff_' + col + '"]' ) . parent ( ) . show ( ) ;
elem . show ( ) . focus ( ) ;
$ ( menu ) . children ( 'option[value="' + col + '"]' ) . prop ( 'disabled' , true ) ;
$ ( menu ) . children ( 'option[value="' + col + '"]' ) . prop ( 'disabled' , true ) ;
}
else {
var lastelem = $ ( '.ff_' + col ) ,
var lastelem = $ ( '.ff_' + col ) ,
appendcontainer = $ ( '#contactsection' + section + ' .contactcontroller' + col ) ;
if ( ! appendcontainer . length ) {
@ -6541,25 +6549,31 @@ function rcube_webmail()
sect . prepend ( appendcontainer ) ;
}
if ( appendcontainer . length && appendcontainer . get ( 0 ) . nodeName == 'FIELDSET' ) {
var input , colprop = this . env . coltypes [ col ] ,
if ( appendcontainer . get ( 0 ) . nodeName == 'FIELDSET' ) {
var label , input ,
colprop = this . env . coltypes [ col ] ,
name _suffix = colprop . limit != 1 ? '[]' : '' ,
compact = $ ( menu ) . data ( 'compact' ) ? true : false ,
input _id = 'ff_' + col + ( colprop . count || 0 ) ,
row = $ ( '<div>' ) . addClass ( 'row' ) ,
cell = $ ( '<div>' ) . addClass ( 'contactfieldcontent data' ) ,
label = $ ( '<div>' ) . addClass ( 'contactfieldlabel label' ) ;
if ( colprop . subtypes _select )
label . html ( colprop . subtypes _select ) ;
row = $ ( '<div>' ) . addClass ( 'row input-group' ) ,
cell = $ ( '<div>' ) . addClass ( 'contactfieldcontent ' + colprop . type ) ;
// Field label
if ( colprop . subtypes _select ) {
label = $ ( colprop . subtypes _select ) ;
if ( ! compact )
label = $ ( '<div>' ) . addClass ( 'contactfieldlabel label' ) . append ( label ) ;
else
label . addClass ( 'input-group-addon' ) ;
}
else
label . html ( '<label for="' + input _id + '">' + colprop . label + '</label>' ) ;
var name _suffix = colprop . limit != 1 ? '[]' : '' ;
label = $ ( '<label>' ) . addClass ( 'contactfieldlabel label input-group-addon' ) . attr ( 'for' , input _id ) . text ( colprop . label ) ;
// Field input
if ( colprop . type == 'text' || colprop . type == 'date' ) {
input = $ ( '<input>' )
. addClass ( 'ff_' + col )
. attr ( { type : 'text' , name : '_' + col + name _suffix , size : colprop . size , id : input _id } )
. appendTo ( cell ) ;
. addClass ( 'form-control ff_' + col )
. attr ( { type : 'text' , name : '_' + col + name _suffix , size : colprop . size , id : input _id } ) ;
this . init _edit _field ( col , input ) ;
@ -6568,17 +6582,19 @@ function rcube_webmail()
}
else if ( colprop . type == 'textarea' ) {
input = $ ( '<textarea>' )
. addClass ( 'ff_' + col )
. attr ( { name : '_' + col + name _suffix , cols : colprop . size , rows : colprop . rows , id : input _id } )
. appendTo ( cell ) ;
. addClass ( 'form-control ff_' + col )
. attr ( { name : '_' + col + name _suffix , cols : colprop . size , rows : colprop . rows , id : input _id } ) ;
this . init _edit _field ( col , input ) ;
}
else if ( colprop . type == 'composite' ) {
var i , childcol , cp , first , templ , cols = [ ] , suffices = [ ] ;
var i , childcol , cp , first , templ , cols = [ ] , suffices = [ ] , content = cell ;
if ( compact )
content = $ ( '<div class="content input-group-addon">' ) ;
// read template for composite field order
if ( ( templ = this . env [ col + '_template' ] ) ) {
if ( templ = this . env [ col + '_template' ] ) {
for ( i = 0 ; i < templ . length ; i ++ ) {
cols . push ( templ [ i ] [ 1 ] ) ;
suffices . push ( templ [ i ] [ 2 ] ) ;
@ -6593,42 +6609,61 @@ function rcube_webmail()
childcol = cols [ i ] ;
cp = colprop . childs [ childcol ] ;
input = $ ( '<input>' )
. addClass ( 'ff_' + childcol )
. attr ( { type : 'text' , name : '_' + childcol + name _suffix , size : cp . size } )
. appendTo ( cell ) ;
cell . append ( suffices [ i ] || " " ) ;
. addClass ( 'form-control ff_' + childcol )
. attr ( { type : 'text' , name : '_' + childcol + name _suffix , size : cp . size } )
. appendTo ( content ) ;
if ( ! compact )
content . append ( suffices [ i ] || " " ) ;
this . init _edit _field ( childcol , input ) ;
if ( ! first ) first = input ;
}
input = first ; // set focus to the first of this composite fields
if ( compact )
input = content ;
else
input = first ; // set focus to the first of this composite fields
}
else if ( colprop . type == 'select' ) {
input = $ ( '<select>' )
. addClass ( 'ff_' + col )
. attr ( { 'name' : '_' + col + name _suffix , id : input _id } )
. appendTo ( cell ) ;
. addClass ( 'form-control ff_' + col )
. attr ( { name : '_' + col + name _suffix , id : input _id } ) ;
var options = input . attr ( 'options' ) ;
options [ options . length ] = new Option ( '---' , '' ) ;
if ( colprop . options )
$ . each ( colprop . options , function ( i , val ) { options [ options . length ] = new Option ( val , i ) ; } ) ;
$ . each ( colprop . options , function ( i , val ) { options [ options . length ] = new Option ( val , i ) ; } ) ;
}
if ( input ) {
var delbutton = $ ( '<a href="#del"></a>' )
. addClass ( 'contactfieldbutton deletebutton ')
. addClass ( 'contactfieldbutton deletebutton input-group-addon icon delete ')
. attr ( { title : this . get _label ( 'delete' ) , rel : col } )
. html ( this . env . delbutton )
. click ( function ( ) { ref . delete _edit _field ( this ) ; return false } )
. appendTo ( cell ) ;
. click ( function ( ) { ref . delete _edit _field ( this ) ; return false ; } ) ;
row . append ( label ) . append ( cell ) . appendTo ( appendcontainer . show ( ) ) ;
input . first ( ) . focus ( ) ;
row . append ( label ) ;
if ( ! compact ) {
if ( colprop . type != 'composite' )
cell . append ( input ) ;
row . append ( cell . append ( delbutton ) ) ;
}
else
row . append ( input ) . append ( delbutton ) ;
row . appendTo ( appendcontainer . show ( ) ) ;
if ( input . is ( 'div' ) )
input . find ( 'input:first' ) . focus ( ) ;
else
input . first ( ) . focus ( ) ;
// disable option if limit reached
if ( ! colprop . count ) colprop . count = 0 ;
if ( ++ colprop . count == colprop . limit && colprop . limit )
$ ( menu ) . children ( 'option[value="' + col + '"]' ) . prop ( 'disabled' , true ) ;
$ ( menu ) . children ( 'option[value="' + col + '"]' ) . prop ( 'disabled' , true ) ;
}
}
}
@ -6643,7 +6678,7 @@ function rcube_webmail()
// just clear input but don't hide the last field
if ( -- colprop . count <= 0 && colprop . visible )
$ ( elem ) . parent ( ) . children ( 'input' ) . val ( '' ) . blur ( ) ;
$ ( elem ) . parent ( ) . find ( 'input' ) . val ( '' ) . blur ( ) ;
else {
$ ( elem ) . parents ( 'div.row' ) . remove ( ) ;
// hide entire fieldset if no more rows
@ -6821,7 +6856,7 @@ function rcube_webmail()
this . qrcode = function ( )
{
var title = this . get _label ( 'qrcode' ) ,
options = { button : false , cancel _button : 'close' , width : 300 , height : 3 5 0} ,
options = { button : false , cancel _button : 'close' , width : 300 , height : 3 0 0} ,
img = new Image ( 300 , 300 ) ;
img . src = this . url ( 'addressbook/qrcode' , { _source : this . env . source , _cid : this . env . cid } ) ;
@ -6907,8 +6942,11 @@ function rcube_webmail()
id = this . env . iid ? this . env . iid : selection [ 0 ] ;
// submit request with appended token
if ( id && confirm ( this . get _label ( 'deleteidentityconfirm' ) ) )
this . http _post ( 'settings/delete-identity' , { _iid : id } , true ) ;
if ( id ) {
this . confirm _dialog ( this . get _label ( 'deleteidentityconfirm' ) , 'delete' , function ( ) {
ref . http _post ( 'settings/delete-identity' , { _iid : id } , true ) ;
} ) ;
}
} ;
this . update _identity _row = function ( id , name , add )
@ -7071,8 +7109,10 @@ function rcube_webmail()
if ( ! name )
name = this . env . mailbox ;
if ( name && confirm ( this . get _label ( 'deletefolderconfirm' ) ) ) {
this . http _post ( 'delete-folder' , { _mbox : name } , this . set _busy ( true , 'folderdeleting' ) ) ;
if ( name ) {
this . confirm _dialog ( this . get _label ( 'deletefolderconfirm' ) , 'delete' , function ( ) {
ref . http _post ( 'delete-folder' , { _mbox : name } , ref . set _busy ( true , 'folderdeleting' ) ) ;
} ) ;
}
} ;
@ -7424,7 +7464,7 @@ function rcube_webmail()
/********* GUI functionality *********/
/*********************************************************/
var init _button = function ( cmd , prop )
this . init _button = function ( cmd , prop )
{
var elm = document . getElementById ( prop . id ) ;
if ( ! elm )
@ -7460,7 +7500,7 @@ function rcube_webmail()
continue ;
for ( var i = 0 ; i < this . buttons [ cmd ] . length ; i ++ ) {
init _button ( cmd , this . buttons [ cmd ] [ i ] ) ;
this . init _button ( cmd , this . buttons [ cmd ] [ i ] ) ;
}
}
} ;
@ -7785,6 +7825,30 @@ function rcube_webmail()
else
popup . html ( content ) ;
// assign special classes to dialog buttons
var i = 0 , fn = function ( button , classes , idx ) {
if ( typeof button == 'function' ) {
button = {
click : button ,
text : idx ,
'class' : classes
} ;
}
else {
buttons [ 'class' ] = classes ;
}
return button ;
} ;
if ( options && options . button _classes )
$ . each ( buttons , function ( idx , button ) {
var cl = options . button _classes [ i ] ;
if ( cl )
buttons [ idx ] = fn ( button , cl , idx ) ;
i ++ ;
} ) ;
options = $ . extend ( {
title : title ,
buttons : buttons ,
@ -7803,16 +7867,16 @@ function rcube_webmail()
// resize and center popup
var win = $ ( window ) , w = win . width ( ) , h = win . height ( ) ,
width = popup . width ( ) , height = options . height || ( popup [ 0 ] . scrollHeight + 20 ) ;
width = popup . width ( ) ,
height = options . height || ( popup [ 0 ] . scrollHeight + 20 ) ,
dialog = popup . parent ( ) ,
titlebar _height = $ ( '.ui-dialog-titlebar' , dialog ) . outerHeight ( ) ,
buttonpane _height = $ ( '.ui-dialog-buttonpane' , dialog ) . outerHeight ( ) ,
padding = ( parseInt ( dialog . css ( 'padding-top' ) ) + parseInt ( popup . css ( 'padding-top' ) ) ) * 2 ;
popup . dialog ( 'option' , {
height : Math . min ( h - 40 , height + 28 + ( buttons ? 50 : 0 ) ) ,
width : Math . min ( w - 20 , width + 28 )
} ) ;
// assign special classes to dialog buttons
$ . each ( options . button _classes || [ ] , function ( i , v ) {
if ( v ) $ ( $ ( '.ui-dialog-buttonpane button' , popup . parent ( ) ) . get ( i ) ) . addClass ( v ) ;
height : Math . min ( h - 40 , height + titlebar _height + buttonpane _height + padding + 2 ) ,
width : Math . min ( w - 20 , width + 24 )
} ) ;
return popup ;
@ -7822,12 +7886,17 @@ function rcube_webmail()
this . simple _dialog = function ( content , title , action _func , options )
{
var title = this . get _label ( title ) ,
cancel _label = ( options || { } ) . cancel _button || 'cancel' ,
save _label = ( options || { } ) . button || 'save' ,
close _func = function ( e , ui , dialog ) { ( ref . is _framed ( ) ? parent . $ : $ ) ( dialog || this ) . dialog ( 'close' ) ; } ,
save _class = ( options || { } ) . button _class || save _label . replace ( /^[^\.]+\./i , '' ) ,
cancel _label = ( options || { } ) . cancel _button || 'cancel' ,
cancel _class = ( options || { } ) . cancel _class || cancel _label . replace ( /^[^\.]+\./i , '' ) ,
close _func = function ( e , ui , dialog ) {
( ref . is _framed ( ) ? parent . $ : $ ) ( dialog || this ) . dialog ( 'close' ) ;
if ( options && options . cancel _func ) options . cancel _func ( e , ref ) ;
} ,
buttons = [ {
text : ref . get _label ( cancel _label ) ,
'class' : 'cancel' ,
text : this . get _label ( cancel _label ) ,
'class' : cancel _class . replace ( /close/i , 'cancel' ) ,
click : close _func
} ] ;
@ -7836,13 +7905,37 @@ function rcube_webmail()
else
buttons . unshift ( {
text : this . get _label ( save _label ) ,
'class' : 'mainaction ' + save _ label ,
click : function ( e , ui ) { if ( action _func ( e )) close _func ( e , ui , this ) ; }
'class' : 'mainaction ' + save _ class ,
click : function ( e , ui ) { if ( action _func ( e , ref )) close _func ( e , ui , this ) ; }
} ) ;
return this . show _popup _dialog ( content , title , buttons , options ) ;
} ;
// show_popup_dialog() wrapper for alert() type dialogs
this . alert _dialog = function ( content , action , options )
{
options = $ . extend ( options || { } , {
cancel _button : 'ok' ,
cancel _class : 'save' ,
cancel _func : action
} ) ;
return this . simple _dialog ( content , options . title || 'alerttitle' , null , options ) ;
} ;
// simple_dialog() wrapper for confirm() type dialogs
this . confirm _dialog = function ( content , button _label , action , options )
{
var action _func = function ( e , ref ) { action ( e , ref ) ; return true ; } ;
options = $ . extend ( options || { } , {
button : button _label || 'continue'
} ) ;
return this . simple _dialog ( content , options . title || 'confirmationtitle' , action _func , options ) ;
} ;
// enable/disable buttons for page shifting
this . set _page _buttons = function ( )
{
@ -8069,7 +8162,7 @@ function rcube_webmail()
// display fetched raw headers
this . set _headers = function ( content )
{
if ( this . gui _objects . all _headers _ row && this . gui _objects . all _headers _ box && content )
if ( this . gui _objects . all _headers _ box && content )
$ ( this . gui _objects . all _headers _box ) . html ( content ) . show ( ) ;
} ;
@ -8085,7 +8178,7 @@ function rcube_webmail()
// fetch headers only once
if ( ! this . gui _objects . all _headers _box . innerHTML ) {
this . http _ po st( 'headers' , { _uid : this . env . uid , _mbox : this . env . mailbox } ,
this . http _ reque st( 'headers' , { _uid : this . env . uid , _mbox : this . env . mailbox } ,
this . display _message ( this . get _label ( 'loading' ) , 'loading' )
) ;
}
@ -8122,7 +8215,7 @@ function rcube_webmail()
var n = 0 , s = 0 ,
folder = ref . env . mailboxes [ this ] ,
id = folder . id ,
a = $ ( link . cloneNode ( false ) ) ,
a = $ ( link . cloneNode ( false ) ) .attr ( 'rel' , folder . id ) ,
row = $ ( '<li>' ) ;
if ( folder . virtual )
@ -8159,7 +8252,6 @@ function rcube_webmail()
// register delegate event handler for folder item clicks
container . on ( 'click' , 'a.active' , function ( e ) {
container . data ( 'callback' ) ( $ ( this ) . data ( 'id' ) ) ;
return false ;
} ) ;
this . folder _selector _element = container ;
@ -8302,8 +8394,7 @@ function rcube_webmail()
this . focused _menu = null ;
this . menu _keyboard _active = false ;
}
}
} ;
// position a menu element on the screen in relation to other object
this . element _position = function ( element , obj )
@ -8678,11 +8769,20 @@ function rcube_webmail()
if ( response . action == 'list' || response . action == 'search' ) {
// highlight message row when we're back from message page
if ( uid ) {
if ( ! list . rows [ uid ] )
if ( uid === 'FIRST' ) {
uid = list . get _first _row ( ) ;
}
else if ( uid === 'LAST' ) {
uid = list . get _last _row ( ) ;
}
else if ( ! list . rows [ uid ] ) {
uid += '-' + this . env . mailbox ;
if ( list . rows [ uid ] ) {
}
if ( uid && list . rows [ uid ] ) {
list . select ( uid ) ;
}
delete this . env . list _uid ;
}
@ -8700,15 +8800,38 @@ function rcube_webmail()
}
}
else if ( this . task == 'addressbook' ) {
this . enable _command ( 'export' , ( this . contact _list && this . contact _list . rowcount > 0 ) ) ;
var list = this . contact _list ,
uid = this . env . list _uid ;
this . enable _command ( 'export' , ( list && list . rowcount > 0 ) ) ;
if ( response . action == 'list' || response . action == 'search' ) {
this . enable _command ( 'search-create' , this . env . source == '' ) ;
this . enable _command ( 'search-delete' , this . env . search _id ) ;
this . update _group _commands ( ) ;
if ( this . contact _list . rowcount > 0 && ! $ ( document . activeElement ) . is ( 'input,textarea' ) )
this . contact _list . focus ( ) ;
this . triggerEvent ( 'listupdate' , { folder : this . env . source , rowcount : this . contact _list . rowcount } ) ;
if ( list && uid ) {
if ( uid === 'FIRST' ) {
uid = list . get _first _row ( ) ;
}
else if ( uid === 'LAST' ) {
uid = list . get _last _row ( ) ;
}
if ( uid && list . rows [ uid ] ) {
list . select ( uid ) ;
}
delete this . env . list _uid ;
// trigger 'select' so all dependent actions update its state
list . triggerEvent ( 'select' ) ;
}
if ( list . rowcount > 0 && ! $ ( document . activeElement ) . is ( 'input,textarea' ) )
list . focus ( ) ;
this . triggerEvent ( 'listupdate' , { folder : this . env . source , rowcount : list . rowcount } ) ;
}
}
break ;
@ -8791,6 +8914,9 @@ function rcube_webmail()
// callback when an iframe finished loading
this . iframe _loaded = function ( unlock )
{
if ( ! unlock )
unlock = this . env . frame _lock ;
this . set _busy ( false , null , unlock ) ;
if ( this . submit _timer )
@ -9576,7 +9702,7 @@ rcube_webmail.subject_text = function(elem)
{
var t = $ ( elem ) . clone ( ) ;
t . find ( '.skip-on-drag,.skip-content,.voice' ) . remove ( ) ;
return t. text ( ) ;
return $. trim ( t. text ( ) ) ;
} ;
// set event handlers on all iframe elements (and their contents)