2012-03-26 21:46:51 +02:00
/ * *
2013-04-13 21:00:13 +02:00
* EGroupware eTemplate2 - JS VFS widgets
2012-03-26 21:46:51 +02:00
*
* @ license http : //opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @ package etemplate
* @ subpackage api
* @ link http : //www.egroupware.org
* @ author Nathan Gray
* @ copyright Nathan Gray 2012
* @ version $Id$
* /
"use strict" ;
/ * e g w : u s e s
jquery . jquery ;
et2 _core _inputWidget ;
et2 _core _valueWidget ;
2013-02-13 10:23:33 +01:00
et2 _widget _description ;
2013-02-20 21:53:15 +01:00
et2 _widget _file ;
2015-01-19 18:18:01 +01:00
/ e t e m p l a t e / j s / e x p o s e . j s ;
2012-03-26 21:46:51 +02:00
* /
/ * *
* Class which implements the "vfs" XET - Tag
2014-02-10 19:25:02 +01:00
*
2013-04-13 21:00:13 +02:00
* @ augments et2 _valueWidget
2012-03-26 21:46:51 +02:00
* /
2014-02-10 19:25:02 +01:00
var et2 _vfs = et2 _valueWidget . extend ( [ et2 _IDetachedDOM ] ,
2013-04-13 21:00:13 +02:00
{
2012-03-26 21:46:51 +02:00
attributes : {
"value" : {
"type" : "any" , // Object
2012-03-27 01:30:27 +02:00
"description" : "Array of (stat) information about the file"
2012-03-26 21:46:51 +02:00
}
} ,
/ * *
* Mime type of directories
* /
DIR _MIME _TYPE : 'httpd/unix-directory' ,
2013-04-13 21:00:13 +02:00
/ * *
* Constructor
2014-02-10 19:25:02 +01:00
*
2013-04-13 21:00:13 +02:00
* @ memberOf et2 _vfs
* /
2012-03-26 21:46:51 +02:00
init : function ( ) {
this . _super . apply ( this , arguments ) ;
this . value = "" ;
this . span = $j ( document . createElement ( "ul" ) )
. addClass ( 'et2_vfs' ) ;
this . setDOMNode ( this . span [ 0 ] ) ;
} ,
2012-07-03 01:02:57 +02:00
getValue : function ( ) {
return this . value ;
} ,
2012-03-26 21:46:51 +02:00
set _value : function ( _value ) {
2012-03-29 13:52:56 +02:00
if ( typeof _value !== 'object' )
2012-03-26 21:46:51 +02:00
{
2015-04-16 18:19:41 +02:00
// Only warn if it's an actual value, just blank for falsy values
if ( _value )
{
this . egw ( ) . debug ( "warn" , "%s only has path, needs full array" , this . id , _value ) ;
}
2012-03-26 21:46:51 +02:00
this . span . empty ( ) . text ( _value ) ;
return ;
}
2014-02-20 18:41:33 +01:00
this . span . empty ( ) ;
2012-07-03 01:02:57 +02:00
this . value = _value ;
2012-03-29 16:31:24 +02:00
var path = _value . path ? _value . path : '/' ;
// calculate path as parent of name, which can contain slashes
// eg. _value.path=/home/ralf/sub/file, _value.name=sub/file --> path=/home/ralf
// --> generate clickable fields for sub/ + file
2014-02-20 18:41:33 +01:00
if ( _value . path . indexOf ( _value . name ) >= 0 )
{
path = path . substr ( 0 , _value . path . length - _value . name . length - 1 ) ;
var path _offset = path . split ( '/' ) . length ;
var path _parts = _value . path . split ( '/' ) ;
}
else
{
var path _offset = 0 ;
var path _parts = [ _value . name ] ;
}
2012-03-26 21:46:51 +02:00
2012-03-28 01:32:32 +02:00
var text ;
2012-03-29 16:31:24 +02:00
for ( var i = path _offset ; i < path _parts . length ; i ++ )
2012-03-26 21:46:51 +02:00
{
2012-03-29 13:52:56 +02:00
path += ( path == '/' ? '' : '/' ) + path _parts [ i ] ;
text = egw . decodePath ( path _parts [ i ] ) ;
2012-03-26 21:46:51 +02:00
// Nice human-readable stuff for apps
if ( path _parts [ 1 ] == 'apps' )
{
switch ( path _parts . length )
{
case 2 :
if ( i == 1 )
{
text = this . egw ( ) . lang ( 'applications' ) ;
}
break ;
case 3 :
if ( i == 2 )
{
text = this . egw ( ) . lang ( path _parts [ 2 ] ) ;
}
break ;
case 4 :
if ( ! isNaN ( text ) )
{
2014-02-20 18:41:33 +01:00
var link _title = this . egw ( ) . link _title ( path _parts [ 2 ] , path _parts [ 3 ] ,
function ( title ) {
if ( ! title || this . value . name == title ) return ;
$j ( 'li' , this . span ) . last ( ) . text ( title ) ;
} , this
) ;
if ( link _title && typeof link _title !== 'undefined' ) text = link _title ;
2012-03-26 21:46:51 +02:00
}
break ;
}
}
2012-07-03 01:02:57 +02:00
var self = this ;
2012-03-29 16:31:24 +02:00
var data = { path : path , type : i < path _parts . length - 1 ? this . DIR _MIME _TYPE : _value . mime } ;
2013-04-13 11:46:00 +02:00
$j ( document . createElement ( "li" ) )
2012-03-26 21:46:51 +02:00
. addClass ( "vfsFilename" )
2012-03-29 16:31:24 +02:00
. text ( text + ( i < path _parts . length - 1 ? '/' : '' ) )
//.attr('title', egw.decodePath(path))
. addClass ( "et2_clickable et2_link" )
2014-02-10 19:25:02 +01:00
. click ( { data : data , egw : this . egw ( ) } , function ( e ) {
2012-07-03 01:02:57 +02:00
if ( ! self . onclick ) {
e . data . egw . open ( e . data . data , "file" ) ;
}
2014-02-10 19:25:02 +01:00
else if ( self . click ( e ) )
2012-07-03 01:02:57 +02:00
{
e . data . egw . open ( e . data . data , "file" ) ;
}
2012-03-29 16:31:24 +02:00
} )
2012-03-26 21:46:51 +02:00
. appendTo ( this . span ) ;
}
2012-03-28 01:32:32 +02:00
} ,
/ * *
2012-03-28 15:58:18 +02:00
* Code for implementing et2 _IDetachedDOM ( data grid )
2014-02-10 19:25:02 +01:00
*
* @ param { array } _attrs array of attribute - names to push further names onto
2012-03-28 15:58:18 +02:00
* /
getDetachedAttributes : function ( _attrs )
{
_attrs . push ( "value" ) ;
} ,
getDetachedNodes : function ( )
{
return [ this . span [ 0 ] ] ;
} ,
setDetachedAttributes : function ( _nodes , _values )
{
this . span = jQuery ( _nodes [ 0 ] ) ;
if ( typeof _values [ "value" ] != 'undefined' )
{
this . set _value ( _values [ "value" ] ) ;
}
}
2012-03-26 21:46:51 +02:00
2012-03-28 01:32:32 +02:00
} ) ;
et2 _register _widget ( et2 _vfs , [ "vfs" ] ) ;
2012-03-27 01:30:27 +02:00
/ * *
* vfs - name
* filename automatically urlencoded on return ( urldecoded on display to user )
2014-02-10 19:25:02 +01:00
*
2013-04-13 21:00:13 +02:00
* @ augments et2 _textbox
2012-03-27 01:30:27 +02:00
* /
2013-04-13 21:00:13 +02:00
var et2 _vfsName = et2 _textbox . extend (
{
/ * *
* Constructor
2014-02-10 19:25:02 +01:00
*
2013-04-13 21:00:13 +02:00
* @ memberOf et2 _vfsName
* /
2012-03-27 01:30:27 +02:00
init : function ( ) {
2012-03-28 15:58:18 +02:00
this . _super . apply ( this , arguments ) ;
2012-03-27 01:30:27 +02:00
this . input . addClass ( "et2_vfs" ) ;
} ,
set _value : function ( _value ) {
if ( _value . path )
{
2012-03-28 15:58:18 +02:00
_value = _value . path ;
2012-03-27 01:30:27 +02:00
}
2012-03-28 15:58:18 +02:00
_value = egw . decodePath ( _value ) ;
2012-03-27 01:30:27 +02:00
this . _super . apply ( this , [ _value ] ) ;
2012-03-28 15:58:18 +02:00
} ,
getValue : function ( ) {
2015-01-30 17:59:31 +01:00
return egw . encodePath ( this . _super . apply ( this ) || '' ) ;
2012-03-27 01:30:27 +02:00
}
} ) ;
et2 _register _widget ( et2 _vfsName , [ "vfs-name" ] ) ;
2013-04-12 11:39:37 +02:00
/ * *
* vfs - name
* filename automatically urlencoded on return ( urldecoded on display to user )
2014-02-10 19:25:02 +01:00
*
2013-04-13 21:00:13 +02:00
* @ augments et2 _textbox _ro
2013-04-12 11:39:37 +02:00
* /
2013-04-13 21:00:13 +02:00
var et2 _vfsName _ro = et2 _textbox _ro . extend (
{
/ * *
* Constructor
2014-02-10 19:25:02 +01:00
*
2013-04-13 21:00:13 +02:00
* @ memberOf et2 _vfsName _ro
* /
2013-04-12 11:39:37 +02:00
init : function ( ) {
this . _super . apply ( this , arguments ) ;
} ,
set _value : function ( _value ) {
if ( _value . path )
{
_value = _value . path ;
}
_value = egw . decodePath ( _value ) ;
this . _super . apply ( this , [ _value ] ) ;
} ,
getValue : function ( ) {
return egw . encodePath ( this . _super . apply ( this ) ) ;
}
} ) ;
et2 _register _widget ( et2 _vfsName _ro , [ "vfs-name_ro" ] ) ;
2012-03-28 01:32:32 +02:00
/ * *
2013-04-20 14:19:27 +02:00
* vfs - mime : icon for mimetype of file , or thumbnail
* incl . optional link overlay icon , if file is a symlink
2014-02-10 19:25:02 +01:00
*
2013-04-20 14:19:27 +02:00
* Creates following structure
* < span class = "iconOverlayContainer" >
* < img class = "et2_vfs vfsMimeIcon" src = "..." / >
* < span class = "overlayContainer" >
* < img class = "overlay" src = "etemplate/templates/default/images/link.png" / >
* < / s p a n >
* < / s p a n >
2014-02-10 19:25:02 +01:00
*
2013-04-20 14:19:27 +02:00
* span . overlayContainer is optional and only generated for symlinks
2014-02-10 19:25:02 +01:00
*
2013-04-13 21:00:13 +02:00
* @ augments et2 _valueWidget
2012-03-28 01:32:32 +02:00
* /
2015-01-19 18:18:01 +01:00
var et2 _vfsMime = expose ( et2 _valueWidget . extend ( [ et2 _IDetachedDOM ] ,
2013-04-13 21:00:13 +02:00
{
2012-03-28 01:32:32 +02:00
attributes : {
"value" : {
"type" : "any" , // Object
"description" : "Array of (stat) information about the file"
} ,
"size" : {
2013-08-14 20:01:22 +02:00
"name" : "Icon size" ,
2012-03-28 01:32:32 +02:00
"type" : "integer" ,
"description" : "Size of icon / thumbnail, in pixels" ,
"default" : et2 _no _init
2015-01-19 18:18:01 +01:00
} ,
2015-01-19 19:59:35 +01:00
"expose_callback" : {
2015-01-19 18:18:01 +01:00
"name" : "expose_callback" ,
"type" : "js" ,
"default" : et2 _no _init ,
"description" : "JS code which is executed when expose slides."
2015-01-20 16:07:09 +01:00
} ,
expose _view : {
name : "Expose view" ,
type : "boolean" ,
default : true ,
description : "Clicking on an image would popup an expose view"
2015-01-21 16:03:59 +01:00
} ,
thumb _mime _size : {
name : "Image thumbnail size" ,
type : "string" ,
default : "" ,
description : " Size of thumbnail in pixel for specified mime type with syntax of: mime_type(s),size (eg. image,video,128)"
2012-03-28 01:32:32 +02:00
}
2015-01-23 13:39:37 +01:00
2012-03-28 01:32:32 +02:00
} ,
2012-07-03 01:02:57 +02:00
legacyOptions : [ "size" ] ,
2015-01-23 13:39:37 +01:00
2013-04-13 21:00:13 +02:00
/ * *
* Constructor
2014-02-10 19:25:02 +01:00
*
2013-04-13 21:00:13 +02:00
* @ memberOf et2 _vfsMime
* /
2012-03-28 01:32:32 +02:00
init : function ( ) {
2012-03-28 15:58:18 +02:00
this . _super . apply ( this , arguments ) ;
2013-04-20 14:19:27 +02:00
this . iconOverlayContainer = jQuery ( document . createElement ( 'span' ) ) . addClass ( 'iconOverlayContainer' ) ;
2012-03-28 01:32:32 +02:00
this . image = jQuery ( document . createElement ( "img" ) ) ;
this . image . addClass ( "et2_vfs vfsMimeIcon" ) ;
2015-01-19 19:59:35 +01:00
this . iconOverlayContainer . append ( this . image ) ;
this . setDOMNode ( this . iconOverlayContainer [ 0 ] ) ;
} ,
2015-01-23 13:39:37 +01:00
2015-01-20 16:07:09 +01:00
/ * *
* Handler for expose slide action , from expose
* Returns data needed for the given index , or false to let expose handle it
*
* @ param { Gallery } gallery
* @ param { integer } index
* @ param { DOMNode } slide
2015-01-23 13:39:37 +01:00
* @ return { Array } array of objects consist of media contnet
2015-01-20 16:07:09 +01:00
* /
expose _onslide : function ( gallery , index , slide )
2015-01-19 20:42:03 +01:00
{
2015-01-20 16:07:09 +01:00
var content = false ;
if ( this . options . expose _callback && typeof this . options . expose _callback == 'function' )
{
//Call the callback to load more items
content = this . options . expose _callback . call ( this , [ gallery , index ] ) ;
if ( content ) this . add ( content ) ;
2015-01-19 18:18:01 +01:00
}
2015-01-20 16:07:09 +01:00
return content ;
2012-03-28 01:32:32 +02:00
} ,
2015-01-23 13:39:37 +01:00
2015-01-19 18:18:01 +01:00
/ * *
* Function to get media content to feed the expose
2015-01-23 13:39:37 +01:00
*
2015-01-19 18:18:01 +01:00
* @ param { type } _value
2015-01-20 16:07:09 +01:00
* @ returns { Array } return an array of object consists of media content
2015-01-19 18:18:01 +01:00
* /
getMedia : function ( _value )
{
2015-01-20 19:47:08 +01:00
var base _url = egw . webserverUrl . match ( /^\// , 'ig' ) ? egw ( window ) . window . location . origin + egw . webserverUrl : egw . webserverUrl ;
2015-04-11 10:18:53 +02:00
var mediaContent = [ {
title : _value . name ,
type : _value . mime ,
href : _value . download _url
} ] ;
// check if download_url is not already an url (some stream-wrappers allow to specify that!)
2015-04-14 15:12:17 +02:00
if ( _value . download _url && ( _value . download _url [ 0 ] == '/' || _value . download _url . substr ( 0 , 4 ) != 'http' ) )
2015-04-11 10:18:53 +02:00
{
mediaContent [ 0 ] . href = base _url + _value . download _url ;
if ( mediaContent [ 0 ] . href && mediaContent [ 0 ] . href . match ( /\/webdav.php/ , 'ig' ) )
{
mediaContent [ 0 ] . download _href = mediaContent [ 0 ] . href + '?download' ;
}
}
2015-01-28 12:21:20 +01:00
if ( _value && _value . mime && _value . mime . match ( /video\/|audio\// , 'ig' ) )
2015-01-19 18:18:01 +01:00
{
2015-04-11 10:18:53 +02:00
mediaContent [ 0 ] . thumbnail = this . egw ( ) . mime _icon ( _value . mime , _value . path , undefined , _value . mtime ) ;
2015-01-19 18:18:01 +01:00
}
else
{
2015-04-11 10:18:53 +02:00
mediaContent [ 0 ] . thumbnail = _value . path && _value . mime ?
this . egw ( ) . mime _icon ( _value . mime , _value . path , undefined , _value . mtime ) :
this . image . attr ( 'src' ) + '&thheight=128' ;
}
2015-01-19 18:18:01 +01:00
return mediaContent ;
} ,
2015-01-23 13:39:37 +01:00
2012-03-28 01:32:32 +02:00
set _value : function ( _value ) {
2012-07-03 01:02:57 +02:00
if ( typeof _value !== 'object' )
{
this . egw ( ) . debug ( "warn" , "%s only has path, needs array with path & mime" , this . id , _value ) ;
// Keep going, will be 'unknown type'
}
2015-02-13 09:27:08 +01:00
var src = this . egw ( ) . mime _icon ( _value . mime , _value . path , undefined , _value . mtime ) ;
2012-03-28 01:32:32 +02:00
if ( src )
{
// Set size of thumbnail
if ( src . indexOf ( "thumbnail.php" ) > - 1 )
{
if ( this . options . size )
{
src += "&thsize=" + this . options . size ;
}
2015-01-21 16:03:59 +01:00
else if ( this . options . thumb _mime _size )
{
var mime _size = this . options . thumb _mime _size . split ( ',' ) ;
var mime _regex = RegExp ( _value . mime . split ( '/' ) [ 0 ] ) ;
2015-01-23 13:39:37 +01:00
if ( typeof mime _size != 'undefined' && jQuery . isArray ( mime _size )
2015-01-21 16:03:59 +01:00
&& ! isNaN ( mime _size [ mime _size . length - 1 ] ) && isNaN ( mime _size [ 0 ] ) && this . options . thumb _mime _size . match ( mime _regex [ 0 ] , 'ig' ) )
{
src += "&thsize=" + mime _size [ mime _size . length - 1 ] ;
2015-01-23 13:39:37 +01:00
}
2015-01-21 16:03:59 +01:00
}
2012-03-28 10:10:57 +02:00
this . image . css ( "max-width" , "100%" ) ;
2012-03-28 01:32:32 +02:00
}
this . image . attr ( "src" , src ) ;
}
2013-04-20 14:19:27 +02:00
// add/remove link icon, if file is (not) a symlink
if ( ( _value . mode & et2 _vfsMode . prototype . types . l ) == et2 _vfsMode . prototype . types . l )
{
if ( typeof this . overlayContainer == 'undefined' )
{
2014-02-10 19:25:02 +01:00
2013-04-20 14:19:27 +02:00
this . overlayContainer = jQuery ( document . createElement ( 'span' ) ) . addClass ( 'overlayContainer' ) ;
this . overlayContainer . append ( jQuery ( document . createElement ( 'img' ) )
. addClass ( 'overlay' ) . attr ( 'src' , this . egw ( ) . image ( 'link' , 'etemplate' ) ) ) ;
this . iconOverlayContainer . append ( this . overlayContainer ) ;
}
}
else if ( typeof this . overlayContainer != 'undefined' )
{
this . overlayContainer . remove ( ) ;
delete this . overlayContainer ;
}
2012-03-28 01:32:32 +02:00
} ,
/ * *
* Implementation of "et2_IDetachedDOM" for fast viewing in gridview
* Override to add needed attributes
2014-02-10 19:25:02 +01:00
*
* @ param { array } _attrs array of attribute - names to push further names onto
2012-03-28 01:32:32 +02:00
* /
getDetachedAttributes : function ( _attrs ) {
_attrs . push ( "value" , "class" ) ;
} ,
getDetachedNodes : function ( ) {
2015-01-20 16:07:09 +01:00
return [ this . node , this . iconOverlayContainer [ 0 ] , this . image [ 0 ] ] ;
2012-03-28 01:32:32 +02:00
} ,
setDetachedAttributes : function ( _nodes , _values ) {
2015-01-20 16:07:09 +01:00
this . iconOverlayContainer = jQuery ( _nodes [ 1 ] ) ;
this . image = jQuery ( _nodes [ 2 ] ) ;
2015-01-19 20:42:03 +01:00
this . node = _nodes [ 0 ] ;
2013-04-20 14:19:27 +02:00
this . overlayContainer = _nodes [ 0 ] . children [ 1 ] ;
2012-03-28 01:32:32 +02:00
if ( typeof _values [ 'class' ] != "undefined" ) {
this . image . addClass ( _values [ 'class' ] ) ;
}
if ( typeof _values [ 'value' ] != "undefined" ) {
this . set _value ( _values [ 'value' ] ) ;
}
}
2015-01-19 18:18:01 +01:00
} ) ) ;
2012-03-28 01:32:32 +02:00
et2 _register _widget ( et2 _vfsMime , [ "vfs-mime" ] ) ;
2012-03-27 01:30:27 +02:00
/ * *
* vfs - size
* Human readable file sizes
2014-02-10 19:25:02 +01:00
*
2013-04-13 21:00:13 +02:00
* @ augments et2 _description
2012-03-27 01:30:27 +02:00
* /
var et2 _vfsSize = et2 _description . extend ( {
2012-07-23 19:59:09 +02:00
attributes : {
"value" : {
2014-02-10 19:25:02 +01:00
"type" : "integer"
2012-07-23 19:59:09 +02:00
}
} ,
2013-04-13 21:00:13 +02:00
/ * *
* Constructor
2014-02-10 19:25:02 +01:00
*
2013-04-13 21:00:13 +02:00
* @ memberOf et2 _vfsSize
* /
2012-03-27 01:30:27 +02:00
init : function ( ) {
2012-03-28 10:10:57 +02:00
this . _super . apply ( this , arguments ) ;
2012-03-27 01:30:27 +02:00
this . span . addClass ( "et2_vfs" ) ;
} ,
human _size : function ( size ) {
if ( typeof size !== "number" )
{
size = parseInt ( size ) ;
}
if ( ! size )
{
size = 0 ;
}
var units = [ 'B' , 'KB' , 'MB' , 'GB' , 'TB' , 'PB' , 'EB' , 'ZB' , 'YB' ] ;
var i = 0 ;
while ( size >= 1024 )
{
size /= 1024 ;
++ i ;
}
return size . toFixed ( i == 0 ? 0 : 1 ) + ' ' + units [ i ] ;
} ,
set _value : function ( _value ) {
if ( _value . size )
{
2013-04-13 11:46:00 +02:00
_value = _value . size ;
2012-03-27 01:30:27 +02:00
}
jQuery ( this . node ) . text ( this . human _size ( _value ) ) ;
} ,
setDetachedAttributes : function ( _nodes , _values )
2012-03-28 15:58:18 +02:00
{
2012-03-27 01:30:27 +02:00
if ( typeof _values [ "value" ] !== "undefined" ) {
this . node = _nodes [ 0 ] ;
this . set _value ( _values [ "value" ] ) ;
delete _values [ "value" ] ;
}
this . _super . apply ( this , arguments ) ;
}
} ) ;
et2 _register _widget ( et2 _vfsSize , [ "vfs-size" ] ) ;
/ * *
2013-04-13 21:00:13 +02:00
* vfs - mode : textual representation of permissions + extra bits
2014-02-10 19:25:02 +01:00
*
2013-04-13 21:00:13 +02:00
* @ augments et2 _description
2012-03-27 01:30:27 +02:00
* /
var et2 _vfsMode = et2 _description . extend ( {
// Masks for file types
types : {
2012-03-28 01:32:32 +02:00
'l' : 0xA000 , // link
2013-04-13 11:46:00 +02:00
's' : 0xC000 , // Socket
2012-03-27 01:30:27 +02:00
'p' : 0x1000 , // FIFO pipe
'c' : 0x2000 , // Character special
'd' : 0x4000 , // Directory
'b' : 0x6000 , // Block special
2012-03-28 01:32:32 +02:00
'-' : 0x8000 // Regular
2012-03-27 01:30:27 +02:00
} ,
2014-02-10 19:25:02 +01:00
// Sticky / UID / GID
2012-03-27 01:30:27 +02:00
sticky : [
{ mask : 0x200 , "char" : "T" , position : 9 } , // Sticky
{ mask : 0x400 , "char" : "S" , position : 6 } , // sGID
{ mask : 0x800 , "char" : "S" , position : 3 } // SUID
] ,
perms : {
'x' : 0x1 , // Execute
'w' : 0x2 , // Write
'r' : 0x4 // Read
} ,
2014-02-10 19:25:02 +01:00
2013-04-13 21:00:13 +02:00
/ * *
* Constructor
2014-02-10 19:25:02 +01:00
*
2013-04-13 21:00:13 +02:00
* @ memberOf et2 _vfsMode
* /
2012-03-27 01:30:27 +02:00
init : function ( ) {
2012-03-28 15:58:18 +02:00
this . _super . apply ( this , arguments ) ;
2012-03-27 01:30:27 +02:00
this . span . addClass ( "et2_vfs" ) ;
} ,
/ * *
* Get text for file stuff
* Result will be like - rwxr -- r -- . First char is type , then read , write , execute ( or other bits ) for
* user , group , world
2014-02-10 19:25:02 +01:00
*
* @ param { number } _value vfs mode
2012-03-27 01:30:27 +02:00
* /
text _mode : function ( _value ) {
var text = [ ] ;
if ( typeof _value != "number" )
{
_value = parseInt ( _value ) ;
}
if ( ! _value ) return "----------" ;
// Figure out type
var type = 'u' ; // unknown
for ( var flag in this . types )
{
2013-04-13 11:46:00 +02:00
if ( ( _value & this . types [ flag ] ) == this . types [ flag ] )
2012-03-27 01:30:27 +02:00
{
type = flag ;
break ;
}
}
// World, group, user - build string backwards
for ( var i = 0 ; i < 3 ; i ++ )
{
for ( var perm in this . perms )
{
if ( _value & this . perms [ perm ] )
{
text . unshift ( perm ) ;
}
else
{
text . unshift ( "-" ) ;
}
}
_value = _value >> 3 ;
}
// Sticky / UID / GID
for ( var i = 0 ; i < this . sticky . length ; i ++ )
{
if ( this . sticky [ i ] . mask & _value )
{
current = text [ this . sticky [ i ] . position ] ;
2012-03-28 01:32:32 +02:00
text [ this . sticky [ i ] . position ] = this . sticky [ i ] [ "char" ] ;
if ( current == 'x' ) text [ this . sticky [ i ] . position ] . toLowerCase ( ) ;
2012-03-27 01:30:27 +02:00
}
}
return type + text . join ( '' ) ;
} ,
set _value : function ( _value ) {
if ( _value . size )
{
2013-04-13 11:46:00 +02:00
_value = _value . size ;
2012-03-27 01:30:27 +02:00
}
var text = this . text _mode ( _value ) ;
jQuery ( this . node ) . text ( text ) ;
} ,
setDetachedAttributes : function ( _nodes , _values )
2012-03-28 15:58:18 +02:00
{
2012-03-27 01:30:27 +02:00
if ( typeof _values [ "value" ] !== "undefined" ) {
this . node = _nodes [ 0 ] ;
this . set _value ( _values [ "value" ] ) ;
delete _values [ "value" ] ;
}
this . _super . apply ( this , arguments ) ;
}
} ) ;
et2 _register _widget ( et2 _vfsMode , [ "vfs-mode" ] ) ;
/ * *
2013-04-13 21:00:13 +02:00
* vfs - uid / vfs - gid : Displays the name for an ID .
2012-03-27 01:30:27 +02:00
* Same as read - only selectAccount , except if there ' s no user it shows "root"
2014-02-10 19:25:02 +01:00
*
2013-04-13 21:00:13 +02:00
* @ augments et2 _selectAccount _ro
2012-03-27 01:30:27 +02:00
* /
2013-04-13 21:00:13 +02:00
var et2 _vfsUid = et2 _selectAccount _ro . extend (
{
/ * *
* @ memberOf et2 _vfsUid
* @ param _node
* @ param _value
* /
2012-03-27 01:30:27 +02:00
set _title : function ( _node , _value ) {
if ( _value == "" )
{
arguments [ 1 ] = "root" ;
}
this . _super . apply ( this , arguments ) ;
}
} ) ;
et2 _register _widget ( et2 _vfsUid , [ "vfs-uid" , "vfs-gid" ] ) ;
2012-03-29 01:27:18 +02:00
/ * v f s - u p l o a d a k a V F S f i l e : d i s p l a y s e i t h e r d o w n l o a d a n d d e l e t e ( x ) l i n k s o r a f i l e u p l o a d
* + value is either a vfs path or colon separated $app : $id : $relative _path , eg : infolog : 123 : special / offer
* + if empty ( $id ) / new entry , file is created in a hidden temporary directory in users home directory
* and calling app is responsible to move content of that dir to entry directory , after entry is saved
* + option : required mimetype or regular expression for mimetype to match , eg . '/^text\//i' for all text files
* + if path ends in a slash , multiple files can be uploaded , their original filename is kept then
2014-02-10 19:25:02 +01:00
*
2013-04-13 21:00:13 +02:00
* @ augments et2 _file
2012-03-29 01:27:18 +02:00
* /
2013-04-13 21:00:13 +02:00
var et2 _vfsUpload = et2 _file . extend (
2014-02-10 19:25:02 +01:00
{
2015-09-01 00:32:50 +02:00
attributes : {
"value" : {
"type" : "any" , // Either nothing, or an object with file info
2015-09-02 21:52:47 +02:00
} ,
"path" : {
"name" : "Path" ,
"description" : "Upload files to the specified VFS path" ,
"type" : "string" ,
"default" : ''
2015-09-01 00:32:50 +02:00
}
} ,
2012-03-30 00:43:07 +02:00
legacyOptions : [ "mime" ] ,
2012-03-29 01:27:18 +02:00
asyncOptions : {
2015-09-01 00:32:50 +02:00
target : egw . ajaxUrl ( self . egw ( ) . getAppName ( ) + ".etemplate_widget_vfs.ajax_upload.etemplate" )
2012-03-29 01:27:18 +02:00
} ,
2013-04-13 21:00:13 +02:00
/ * *
* Constructor
2014-02-10 19:25:02 +01:00
*
2013-04-13 21:00:13 +02:00
* @ param _parent
* @ param attrs
* @ memberof et2 _vfsUpload
* /
2012-03-30 00:43:07 +02:00
init : function ( _parent , attrs ) {
2012-03-29 01:27:18 +02:00
this . _super . apply ( this , arguments ) ;
2015-09-01 00:32:50 +02:00
$j ( this . node ) . addClass ( "et2_vfs" ) ;
2015-09-02 21:52:47 +02:00
if ( ! this . options . path )
{
this . options . path = this . options . id ;
}
// If the path is a directory, allow multiple uploads
if ( this . options . path . substr ( - 1 ) == '/' )
2012-03-30 00:43:07 +02:00
{
this . set _multiple ( true ) ;
}
2015-09-01 00:32:50 +02:00
this . list = $j ( document . createElement ( 'table' ) ) . appendTo ( this . node ) ;
2012-03-29 01:27:18 +02:00
} ,
2015-09-01 00:32:50 +02:00
/ * *
* If there is a file / files in the specified location , display them
2015-09-02 21:52:47 +02:00
* Value is the information for the file [ s ] in the specified location .
2015-09-01 00:32:50 +02:00
*
* @ param { Object [ ] } _value
* /
2012-03-29 01:27:18 +02:00
set _value : function ( _value ) {
2015-09-02 21:52:47 +02:00
// Remove previous
while ( this . _children . length > 0 )
{
var node = this . _children [ this . _children . length - 1 ] ;
this . removeChild ( node ) ;
node . free ( ) ;
}
2015-09-01 00:32:50 +02:00
this . progress . empty ( ) ;
this . list . empty ( ) ;
2015-09-02 21:52:47 +02:00
// Set new
if ( typeof _value == 'object' && _value && _value . length )
2015-09-01 00:32:50 +02:00
{
2015-09-02 21:52:47 +02:00
for ( var i = 0 ; i < _value . length ; i ++ )
{
this . _addFile ( _value [ i ] ) ;
}
2015-09-01 00:32:50 +02:00
}
} ,
2015-09-02 21:52:47 +02:00
/ * *
* Value is determined by what ' s at the location specified by path
*
* @ returns { null }
* /
getValue : function ( ) {
return null ;
} ,
2015-09-01 00:32:50 +02:00
getDOMNode : function ( sender ) {
if ( sender !== this && sender . _type . indexOf ( 'vfs' ) >= 0 )
{
var value = sender . getValue && sender . getValue ( ) || sender . options . value || { } ;
var row = $j ( '[data-path="' + ( value . path ) + '"]' , this . list ) ;
if ( sender . _type === 'vfs-mime' )
{
return $j ( '.icon' , row ) . get ( 0 ) || null ;
}
else
{
return $j ( '.title' , row ) . get ( 0 ) || null ;
}
}
else
{
return this . _super . apply ( this , arguments ) ;
}
} ,
2015-09-02 21:52:47 +02:00
/ * *
* Add in the request id
* /
beforeSend : function ( form )
{
var instance = this . getInstanceManager ( ) ;
var extra = this . _super . apply ( this , arguments ) ;
extra . path = this . options . path ;
return extra ;
} ,
2015-09-01 00:32:50 +02:00
_addFile : function ( file _data ) {
var row = $j ( document . createElement ( "tr" ) )
2015-09-02 21:52:47 +02:00
. attr ( "data-path" , file _data . path )
2015-09-01 00:32:50 +02:00
. attr ( "draggable" , "true" )
. appendTo ( this . list ) ;
var mime = $j ( document . createElement ( "td" ) )
. addClass ( 'icon' )
. appendTo ( row ) ;
var title = $j ( document . createElement ( "td" ) )
. addClass ( 'title' )
. appendTo ( row ) ;
var mime = et2 _createWidget ( 'vfs-mime' , { value : file _data } , this ) ;
var vfs = et2 _createWidget ( 'vfs' , { value : file _data } , this ) ;
2015-09-02 21:52:47 +02:00
// Add in delete button
if ( ! this . options . readonly )
{
var self = this ;
var delete _button = $j ( document . createElement ( "td" ) )
. appendTo ( row ) ;
$j ( "<div />" )
. appendTo ( delete _button )
// We don't use ui-icon because it assigns a bg image
. addClass ( "delete icon" )
. bind ( 'click' , function ( ) {
et2 _dialog . show _dialog (
function ( button ) {
if ( button == et2 _dialog . YES _BUTTON )
{
egw . json ( "filemanager_ui::ajax_action" , [
'delete' ,
[ row . attr ( 'data-path' ) ] ,
''
] ,
function ( data ) {
if ( data && data . errs == 0 ) { row . slideUp ( row . remove ) ; }
if ( data && data . msg ) {
self . egw ( ) . message ( data . msg , data . errs == 0 ? 'success' : 'error' ) ;
}
}
) . sendRequest ( ) ;
}
} ,
egw . lang ( 'Delete file?' )
) ;
} ) ;
}
2012-03-29 01:27:18 +02:00
}
} ) ;
et2 _register _widget ( et2 _vfsUpload , [ "vfs-upload" ] ) ;
2013-10-01 17:40:14 +02:00
var et2 _vfsSelect = et2 _inputWidget . extend (
{
// Allowed mode options
modes : [ 'open' , 'open-multiple' , 'saveas' , 'select-dir' ] ,
2014-02-10 19:25:02 +01:00
2013-10-01 17:40:14 +02:00
attributes : {
"mode" : {
name : "Dialog mode" ,
type : "string" ,
description : "One of {open|open-multiple|saveas|select-dir}" ,
default : "open-multiple"
} ,
"method" : {
name : "Server side callback" ,
type : "string" ,
description : "Server side callback to process selected value(s) in app.class.method or class::method format. The first parameter will be Method ID, the second the file list."
} ,
"method_id" : {
name : "Method ID" ,
type : "any" ,
description : "optional parameter passed to server side callback. Can be a string or a function." ,
default : ""
} ,
"path" : {
name : "Path" ,
type : "string" ,
description : "Start path in VFS. Leave unset to use the last used path."
} ,
"mime" : {
name : "Mime type" ,
type : "string" ,
description : "Limit display to the given mime-type"
} ,
"button_label" : {
name : "Button label" ,
description : "Set the label on the dialog's OK button." ,
default : "open"
} ,
"value" : {
"type" : "any" , // Object
"description" : "Array of paths (strings)"
2015-01-23 13:39:37 +01:00
} ,
2014-04-30 12:52:27 +02:00
"button_caption" : {
name : "button caption" ,
type : "string" ,
2014-06-25 18:26:59 +02:00
default : "Select files from Filemanager ..." ,
2014-06-24 17:18:55 +02:00
description : "Caption for vfs-select button." ,
translate : true
2013-10-01 17:40:14 +02:00
}
} ,
2014-02-10 19:25:02 +01:00
2013-10-01 17:40:14 +02:00
/ * *
* Constructor
2014-02-10 19:25:02 +01:00
*
2013-10-01 17:40:14 +02:00
* @ param _parent
* @ param _attrs
* @ memberOf et2 _vfsSelect
* /
init : function ( _parent , _attrs ) {
// _super.apply is responsible for the actual setting of the params (some magic)
this . _super . apply ( this , arguments ) ;
// Allow no child widgets
this . supportedWidgetClasses = [ ] ;
2015-01-23 13:39:37 +01:00
2014-04-30 12:52:27 +02:00
this . button = $j ( document . createElement ( "button" ) )
2013-10-11 15:48:50 +02:00
. attr ( "title" , this . egw ( ) . lang ( "Select file(s) from VFS" ) )
2014-04-30 12:52:27 +02:00
. addClass ( "et2_button et2_button_text et2_vfs_btn" )
. css ( "background-image" , "url(" + this . egw ( ) . image ( "filemanager/navbar" ) + ")" ) ;
2015-01-23 13:39:37 +01:00
2014-04-30 12:52:27 +02:00
if ( this . options . button _caption != "" )
{
this . button . text ( this . options . button _caption ) ;
}
2014-03-28 09:46:54 +01:00
this . setDOMNode ( egw . app ( 'filemanager' ) ? this . button [ 0 ] : document . createElement ( 'span' ) ) ;
2013-10-01 17:40:14 +02:00
} ,
click : function ( e ) {
2014-02-10 19:25:02 +01:00
2013-10-01 17:40:14 +02:00
// No permission
2014-03-28 09:46:54 +01:00
if ( ! egw . app ( 'filemanager' ) ) return ;
2014-02-10 19:25:02 +01:00
2013-10-01 17:40:14 +02:00
var self = this ;
var attrs = {
menuaction : 'filemanager.filemanager_select.select' ,
mode : this . options . mode ,
method : this . options . method ,
label : this . options . button _label ,
id : typeof this . options . method _id == "function" ? this . options . method _id . call ( ) : this . options . method _id
} ;
if ( this . options . path )
{
attrs . path = this . options . path ;
}
if ( this . options . mime )
{
attrs . mime = this . options . mime ;
} ;
2014-02-10 19:25:02 +01:00
2013-10-01 17:40:14 +02:00
// Open the filemanager select in a popup
2015-03-17 18:27:00 +01:00
var popup = this . egw ( window ) . open _link (
2013-10-01 17:40:14 +02:00
this . egw ( ) . link ( '/index.php' , attrs ) ,
'link_existing' ,
2014-12-22 10:52:58 +01:00
'680x400'
2013-10-01 17:40:14 +02:00
) ;
if ( popup )
{
2015-03-17 18:27:00 +01:00
// Safari and IE lose reference to global variables after window close
// Try to get updated data before window is closed then later we trigger
// change event on widget
self . egw ( ) . window . setTimeout ( function ( ) {
jQuery ( popup ) . bind ( 'unload' , function ( ) {
// Set selected files to widget
self . value = this . selected _files ;
// Update path to where the user wound up]
if ( typeof this . etemplate2 != 'undefined' ) self . options . path = this . etemplate2 . getByApplication ( 'filemanager' ) [ 0 ] . widgetContainer . getArrayMgr ( "content" ) . getEntry ( 'path' ) ;
} ) ;
} , 1000 ) ;
2015-04-11 10:18:53 +02:00
2013-10-01 17:40:14 +02:00
// Update on close doesn't always (ever, in chrome) work, so poll
var poll = self . egw ( ) . window . setInterval (
function ( ) {
if ( popup . closed ) {
self . egw ( ) . window . clearInterval ( poll ) ;
// Fire a change event so any handlers run
$j ( self . node ) . change ( ) ;
}
} , 1000
) ;
}
} ,
/ * *
2014-02-10 19:25:02 +01:00
* Set the dialog ' s mode .
2013-10-01 17:40:14 +02:00
* Valid options are in et2 _vfsSelect . modes
2014-02-10 19:25:02 +01:00
*
* @ param { string } mode 'open' , 'open-multiple' , 'saveas' or 'select-dir'
2013-10-01 17:40:14 +02:00
* /
set _mode : function ( mode ) {
// Check mode
if ( jQuery . inArray ( mode , this . modes ) < 0 )
{
this . egw ( ) . debug ( "warn" , "Invalid mode for '%s': %s Valid options:" , this . id , mode , this . modes ) ;
return ;
}
this . options . mode = mode ;
} ,
/ * *
* Set the label on the dialog ' s OK button .
2014-02-10 19:25:02 +01:00
*
* @ param { string } label
2013-10-01 17:40:14 +02:00
* /
set _button _label : function ( label )
{
this . options . button _label = label ;
} ,
2015-01-23 13:39:37 +01:00
2014-04-30 12:52:27 +02:00
/ * *
* Set the caption for vfs - select button
2015-01-23 13:39:37 +01:00
*
2014-04-30 12:52:27 +02:00
* @ param { string } caption string value as a caption
* /
set _button _caption : function ( caption )
{
this . options . button _caption = caption ;
} ,
2015-01-23 13:39:37 +01:00
2013-10-01 17:40:14 +02:00
/ * *
* Set the ID passed to the server side callback
2014-02-10 19:25:02 +01:00
*
* @ param { string } id
2013-10-01 17:40:14 +02:00
* /
set _method _id : function ( id ) {
this . options . method _id = id ;
} ,
2013-10-01 17:52:25 +02:00
getValue : function ( ) {
2013-10-01 17:40:14 +02:00
return this . value ;
}
} ) ;
2013-10-11 15:48:50 +02:00
et2 _register _widget ( et2 _vfsSelect , [ "vfs-select" ] ) ;