@ -8,7 +8,6 @@ define([
var UNSORTED = module . UNSORTED = "unsorted" ;
var UNSORTED = module . UNSORTED = "unsorted" ;
var TRASH = module . TRASH = "trash" ;
var TRASH = module . TRASH = "trash" ;
var TEMPLATE = module . TEMPLATE = "template" ;
var TEMPLATE = module . TEMPLATE = "template" ;
var NEW _FILES _DATA = 'filesData' ;
module . init = function ( files , config ) {
module . init = function ( files , config ) {
var exp = { } ;
var exp = { } ;
@ -16,6 +15,7 @@ define([
var Messages = Cryptpad . Messages ;
var Messages = Cryptpad . Messages ;
var FILES _DATA = module . FILES _DATA = exp . FILES _DATA = Cryptpad . storageKey ;
var FILES _DATA = module . FILES _DATA = exp . FILES _DATA = Cryptpad . storageKey ;
var OLD _FILES _DATA = module . OLD _FILES _DATA = exp . OLD _FILES _DATA = Cryptpad . oldStorageKey ;
var NEW _FOLDER _NAME = Messages . fm _newFolder ;
var NEW _FOLDER _NAME = Messages . fm _newFolder ;
var NEW _FILE _NAME = Messages . fm _newFile ;
var NEW _FILE _NAME = Messages . fm _newFile ;
@ -43,7 +43,7 @@ define([
var a = { } ;
var a = { } ;
a [ ROOT ] = { } ;
a [ ROOT ] = { } ;
a [ TRASH ] = { } ;
a [ TRASH ] = { } ;
a [ FILES _DATA ] = [] ;
a [ FILES _DATA ] = {} ;
a [ TEMPLATE ] = [ ] ;
a [ TEMPLATE ] = [ ] ;
return a ;
return a ;
} ;
} ;
@ -54,15 +54,19 @@ define([
var compareFiles = function ( fileA , fileB ) { return fileA === fileB ; } ;
var compareFiles = function ( fileA , fileB ) { return fileA === fileB ; } ;
var isFile = exp . isFile = function ( element ) {
var isFile = exp . isFile = function ( element , allowStr ) {
return typeof ( element ) === "number" || typeof ( element ) === "string" ;
return typeof ( element ) === "number" ||
( ( typeof ( files [ OLD _FILES _DATA ] ) !== "undefined" || allowStr )
&& typeof ( element ) === "string" ) ;
} ;
} ;
exp . isReadOnlyFile = function ( element ) {
exp . isReadOnlyFile = function ( element ) {
if ( ! isFile ( element ) ) { return false ; }
if ( ! isFile ( element ) ) { return false ; }
var parsed = Cryptpad . parsePadUrl ( element ) ;
var data = exp . getFileData ( element ) ;
var parsed = Cryptpad . parsePadUrl ( data . href ) ;
if ( ! parsed ) { return false ; }
if ( ! parsed ) { return false ; }
var pHash = parsed . hashData ;
var pHash = parsed . hashData ;
if ( ! pHash || pHash . type !== "pad" ) { return ; }
return pHash && pHash . mode === 'view' ;
return pHash && pHash . mode === 'view' ;
} ;
} ;
@ -70,12 +74,12 @@ define([
return typeof ( element ) === "object" ;
return typeof ( element ) === "object" ;
} ;
} ;
exp . isFolderEmpty = function ( element ) {
exp . isFolderEmpty = function ( element ) {
if ( typeof ( element ) !== "object" ) { return false ; }
if ( ! isFolder ( element ) ) { return false ; }
return Object . keys ( element ) . length === 0 ;
return Object . keys ( element ) . length === 0 ;
} ;
} ;
exp . hasSubfolder = function ( element , trashRoot ) {
exp . hasSubfolder = function ( element , trashRoot ) {
if ( typeof ( element ) !== "object" ) { return false ; }
if ( ! isFolder ( element ) ) { return false ; }
var subfolder = 0 ;
var subfolder = 0 ;
var addSubfolder = function ( el ) {
var addSubfolder = function ( el ) {
subfolder += isFolder ( el . element ) ? 1 : 0 ;
subfolder += isFolder ( el . element ) ? 1 : 0 ;
@ -93,7 +97,7 @@ define([
} ;
} ;
exp . hasFile = function ( element , trashRoot ) {
exp . hasFile = function ( element , trashRoot ) {
if ( typeof ( element ) !== "object" ) { return false ; }
if ( ! isFolder ( element ) ) { return false ; }
var file = 0 ;
var file = 0 ;
var addFile = function ( el ) {
var addFile = function ( el ) {
file += isFile ( el . element ) ? 1 : 0 ;
file += isFile ( el . element ) ? 1 : 0 ;
@ -113,29 +117,33 @@ define([
// Get data from AllFiles (Cryptpad_RECENTPADS)
// Get data from AllFiles (Cryptpad_RECENTPADS)
var getFileData = exp . getFileData = function ( file ) {
var getFileData = exp . getFileData = function ( file ) {
if ( ! file ) { return ; }
if ( ! file ) { return ; }
var res ;
return files [ FILES _DATA ] [ file ] || { } ;
files [ FILES _DATA ] . some ( function ( arr ) {
var href = arr . href ;
if ( href === file ) {
res = arr ;
return true ;
}
return false ;
} ) ;
return res ;
} ;
} ;
// Data from filesData
// Data from filesData
var getTitle = exp . getTitle = function ( hre f) {
var getTitle = exp . getTitle = function ( file , type ) {
if ( workgroup ) { debug ( "No titles in workgroups" ) ; return ; }
if ( workgroup ) { debug ( "No titles in workgroups" ) ; return ; }
var data = getFileData ( hre f) ;
var data = getFileData ( file ) ;
if ( ! hre f || ! data ) {
if ( ! file || ! data || ! data . href ) {
error ( "getTitle called with a non-existing href: ", href ) ;
error ( "getTitle called with a non-existing file id: " , file , data ) ;
return ;
return ;
}
}
return data . title ;
if ( type === 'title' ) { return data . title ; }
if ( type === 'name' ) { return data . filename ; }
return data . filename || data . title || NEW _FILE _NAME ;
} ;
} ;
var getIdFromHref = exp . getIdFromHref = function ( href ) {
var result ;
getFiles ( [ FILES _DATA ] ) . some ( function ( id ) {
if ( files [ FILES _DATA ] [ id ] . href === href ) {
result = id ;
return true ;
}
return ;
} ) ;
return result ;
} ;
// PATHS
// PATHS
@ -246,31 +254,25 @@ define([
}
}
return ret ;
return ret ;
} ;
} ;
_getFiles [ FILES_DATA ] = function ( ) {
_getFiles [ OLD_ FILES_DATA ] = function ( ) {
var ret = [ ] ;
var ret = [ ] ;
if ( ! files [ FILES_DATA ] ) { return ret ; }
if ( ! files [ OLD_ FILES_DATA ] ) { return ret ; }
files [ FILES_DATA ] . forEach ( function ( el ) {
files [ OLD_ FILES_DATA ] . forEach ( function ( el ) {
if ( el . href && ret . indexOf ( el . href ) === - 1 ) {
if ( el . href && ret . indexOf ( el . href ) === - 1 ) {
ret . push ( el . href ) ;
ret . push ( el . href ) ;
}
}
} ) ;
} ) ;
return ret ;
return ret ;
} ;
} ;
_getFiles [ NEW_ FILES_DATA ] = function ( ) {
_getFiles [ FILES_DATA ] = function ( ) {
var ret = [ ] ;
var ret = [ ] ;
if ( ! files [ NEW _FILES _DATA ] ) { return ret ; }
if ( ! files [ FILES _DATA ] ) { return ret ; }
for ( var k in files [ NEW _FILES _DATA ] ) {
return Object . keys ( files [ FILES _DATA ] ) . map ( Number ) ;
var el = files [ NEW _FILES _DATA ] [ k ] ;
if ( el . href && ret . indexOf ( el . href ) === - 1 ) {
ret . push ( el . href ) ;
}
} ;
return ret ;
} ;
} ;
var getFiles = exp . getFiles = function ( categories ) {
var getFiles = exp . getFiles = function ( categories ) {
var ret = [ ] ;
var ret = [ ] ;
if ( ! categories || ! categories . length ) {
if ( ! categories || ! categories . length ) {
categories = [ ROOT , 'hrefArray' , TRASH , FILES_DATA , NEW_ FILES_DATA ] ;
categories = [ ROOT , 'hrefArray' , TRASH , OLD _FILES _DATA , FILES _DATA ] ;
}
}
categories . forEach ( function ( c ) {
categories . forEach ( function ( c ) {
if ( typeof _getFiles [ c ] === "function" ) {
if ( typeof _getFiles [ c ] === "function" ) {
@ -281,7 +283,7 @@ define([
} ;
} ;
// SEARCH
// SEARCH
var _findFileInRoot = function ( path , hre f) {
var _findFileInRoot = function ( path , file ) {
if ( ! isPathIn ( path , [ ROOT , TRASH ] ) ) { return [ ] ; }
if ( ! isPathIn ( path , [ ROOT , TRASH ] ) ) { return [ ] ; }
var paths = [ ] ;
var paths = [ ] ;
var root = find ( path ) ;
var root = find ( path ) ;
@ -292,7 +294,7 @@ define([
} ;
} ;
if ( isFile ( root ) ) {
if ( isFile ( root ) ) {
if ( compareFiles ( hre f, root ) ) {
if ( compareFiles ( file , root ) ) {
if ( paths . indexOf ( path ) === - 1 ) {
if ( paths . indexOf ( path ) === - 1 ) {
paths . push ( path ) ;
paths . push ( path ) ;
}
}
@ -302,25 +304,25 @@ define([
for ( var e in root ) {
for ( var e in root ) {
var nPath = path . slice ( ) ;
var nPath = path . slice ( ) ;
nPath . push ( e ) ;
nPath . push ( e ) ;
_findFileInRoot ( nPath , hre f) . forEach ( addPaths ) ;
_findFileInRoot ( nPath , file ) . forEach ( addPaths ) ;
}
}
return paths ;
return paths ;
} ;
} ;
exp . findFileInRoot = function ( hre f) {
exp . findFileInRoot = function ( file ) {
return _findFileInRoot ( [ ROOT ] , hre f) ;
return _findFileInRoot ( [ ROOT ] , file ) ;
} ;
} ;
var _findFileInHrefArray = function ( rootName , hre f) {
var _findFileInHrefArray = function ( rootName , file ) {
if ( ! files [ rootName ] ) { return [ ] ; }
if ( ! files [ rootName ] ) { return [ ] ; }
var unsorted = files [ rootName ] . slice ( ) ;
var unsorted = files [ rootName ] . slice ( ) ;
var ret = [ ] ;
var ret = [ ] ;
var i = - 1 ;
var i = - 1 ;
while ( ( i = unsorted . indexOf ( hre f, i + 1 ) ) !== - 1 ) {
while ( ( i = unsorted . indexOf ( file , i + 1 ) ) !== - 1 ) {
ret . push ( [ rootName , i ] ) ;
ret . push ( [ rootName , i ] ) ;
}
}
return ret ;
return ret ;
} ;
} ;
var _findFileInTrash = function ( path , hre f) {
var _findFileInTrash = function ( path , file ) {
var root = find ( path ) ;
var root = find ( path ) ;
var paths = [ ] ;
var paths = [ ] ;
var addPaths = function ( p ) {
var addPaths = function ( p ) {
@ -334,7 +336,7 @@ define([
if ( ! Array . isArray ( arr ) ) { return ; }
if ( ! Array . isArray ( arr ) ) { return ; }
var nPath = path . slice ( ) ;
var nPath = path . slice ( ) ;
nPath . push ( key ) ;
nPath . push ( key ) ;
_findFileInTrash ( nPath , hre f) . forEach ( addPaths ) ;
_findFileInTrash ( nPath , file ) . forEach ( addPaths ) ;
} ) ;
} ) ;
}
}
if ( path . length === 2 ) {
if ( path . length === 2 ) {
@ -344,70 +346,44 @@ define([
nPath . push ( i ) ;
nPath . push ( i ) ;
nPath . push ( 'element' ) ;
nPath . push ( 'element' ) ;
if ( isFile ( el . element ) ) {
if ( isFile ( el . element ) ) {
if ( compareFiles ( hre f, el . element ) ) {
if ( compareFiles ( file , el . element ) ) {
addPaths ( nPath ) ;
addPaths ( nPath ) ;
}
}
return ;
return ;
}
}
_findFileInTrash ( nPath , hre f) . forEach ( addPaths ) ;
_findFileInTrash ( nPath , file ) . forEach ( addPaths ) ;
} ) ;
} ) ;
}
}
if ( path . length >= 4 ) {
if ( path . length >= 4 ) {
_findFileInRoot ( path , hre f) . forEach ( addPaths ) ;
_findFileInRoot ( path , file ) . forEach ( addPaths ) ;
}
}
return paths ;
return paths ;
} ;
} ;
var findFile = exp . findFile = function ( hre f) {
var findFile = exp . findFile = function ( file ) {
var rootpaths = _findFileInRoot ( [ ROOT ] , hre f) ;
var rootpaths = _findFileInRoot ( [ ROOT ] , file ) ;
var templatepaths = _findFileInHrefArray ( TEMPLATE , hre f) ;
var templatepaths = _findFileInHrefArray ( TEMPLATE , file ) ;
var trashpaths = _findFileInTrash ( [ TRASH ] , hre f) ;
var trashpaths = _findFileInTrash ( [ TRASH ] , file ) ;
return rootpaths . concat ( templatepaths , trashpaths ) ;
return rootpaths . concat ( templatepaths , trashpaths ) ;
} ;
} ;
exp . search = function ( value ) {
exp . search = function ( value ) {
if ( typeof ( value ) !== "string" ) { return [ ] ; }
if ( typeof ( value ) !== "string" ) { return [ ] ; }
var res = [ ] ;
var res = [ ] ;
// Search in ROOT
var findIn = function ( root ) {
Object . keys ( root ) . forEach ( function ( k ) {
if ( isFile ( root [ k ] ) ) {
if ( k . toLowerCase ( ) . indexOf ( value . toLowerCase ( ) ) !== - 1 ) {
res . push ( root [ k ] ) ;
}
return ;
}
findIn ( root [ k ] ) ;
} ) ;
} ;
findIn ( files [ ROOT ] ) ;
// Search in TRASH
var trash = files [ TRASH ] ;
Object . keys ( trash ) . forEach ( function ( k ) {
if ( k . toLowerCase ( ) . indexOf ( value . toLowerCase ( ) ) !== - 1 ) {
trash [ k ] . forEach ( function ( el ) {
if ( isFile ( el . element ) ) {
res . push ( el . element ) ;
}
} ) ;
}
trash [ k ] . forEach ( function ( el ) {
if ( isFolder ( el . element ) ) {
findIn ( el . element ) ;
}
} ) ;
} ) ;
// Search title
// Search title
var allFilesList = files [ FILES _DATA ] . slice ( ) ;
var allFilesList = files [ FILES _DATA ] ;
allFilesList . forEach ( function ( t ) {
var lValue = value . toLowerCase ( ) ;
if ( t . title && t . title . toLowerCase ( ) . indexOf ( value . toLowerCase ( ) ) !== - 1 ) {
getFiles ( [ FILES _DATA ] ) . forEach ( function ( id ) {
res . push ( t . href ) ;
var data = allFilesList [ id ] ;
if ( ( data . title && data . title . toLowerCase ( ) . indexOf ( lValue ) !== - 1 ) ||
( data . filename && data . filename . toLowerCase ( ) . indexOf ( lValue ) !== - 1 ) ) {
res . push ( id ) ;
}
}
} ) ;
} ) ;
// Search Href
// Search Href
var href = Cryptpad . getRelativeHref ( value ) ;
var href = Cryptpad . getRelativeHref ( value ) ;
if ( href ) {
if ( href ) {
res . push ( href ) ;
var id = getIdFromHref ( href ) ;
if ( id ) { res . push ( id ) ; }
}
}
res = Cryptpad . deduplicateString ( res ) ;
res = Cryptpad . deduplicateString ( res ) ;
@ -442,24 +418,21 @@ define([
var pushFileData = exp . pushData = function ( data , cb ) {
var pushFileData = exp . pushData = function ( data , cb ) {
if ( typeof cb !== "function" ) { cb = function ( ) { } ; }
if ( typeof cb !== "function" ) { cb = function ( ) { } ; }
var todo = function ( ) {
var todo = function ( ) {
files [ FILES _DATA ] . push ( data ) ;
var id = Cryptpad . createRandomInteger ( ) ;
cb ( ) ;
files [ FILES _DATA ] [ id ] = data ;
cb ( null , id ) ;
} ;
} ;
if ( ! Cryptpad . isLoggedIn ( ) || ! AppConfig . enablePinning ) { return void todo ( ) ; }
if ( ! Cryptpad . isLoggedIn ( ) || ! AppConfig . enablePinning || config . testMode ) {
return void todo ( ) ;
}
Cryptpad . pinPads ( [ Cryptpad . hrefToHexChannelId ( data . href ) ] , function ( e ) {
Cryptpad . pinPads ( [ Cryptpad . hrefToHexChannelId ( data . href ) ] , function ( e ) {
if ( e ) { return void cb ( e ) ; }
if ( e ) { return void cb ( e ) ; }
todo ( ) ;
todo ( ) ;
} ) ;
} ) ;
} ;
} ;
var spliceFileData = exp . removeData = function ( idx ) {
var spliceFileData = exp . removeData = function ( id ) {
var data = files [ FILES _DATA ] [ idx ] ;
files [ FILES _DATA ] [ id ] = undefined ;
if ( typeof data === "object" && Cryptpad . isLoggedIn ( ) && AppConfig . enablePinning ) {
delete files [ FILES _DATA ] [ id ] ;
Cryptpad . unpinPads ( [ Cryptpad . hrefToHexChannelId ( data . href ) ] , function ( e , hash ) {
if ( e ) { return void logError ( e ) ; }
debug ( 'UNPIN' , hash ) ;
} ) ;
}
files [ FILES _DATA ] . splice ( idx , 1 ) ;
} ;
} ;
// MOVE
// MOVE
@ -506,16 +479,10 @@ define([
}
}
}
}
// Move to root
// Move to root
var name ;
var newName = isFile ( element ) ?
if ( isPathIn ( elementPath , [ 'hrefArray' ] ) ) {
getAvailableName ( newParent , Cryptpad . createChannelId ( ) ) :
name = getTitle ( element ) ;
isInTrashRoot ( elementPath ) ?
} else if ( isInTrashRoot ( elementPath ) ) {
elementPath [ 1 ] : elementPath . pop ( ) ;
// Element from the trash root: elementPath = [TRASH, "{dirName}", 0, 'element']
name = elementPath [ 1 ] ;
} else {
name = elementPath [ elementPath . length - 1 ] ;
}
var newName = ! isPathIn ( elementPath , [ ROOT ] ) ? getAvailableName ( newParent , name ) : name ;
if ( typeof ( newParent [ newName ] ) !== "undefined" ) {
if ( typeof ( newParent [ newName ] ) !== "undefined" ) {
log ( Messages . fo _unavailableName ) ;
log ( Messages . fo _unavailableName ) ;
@ -536,7 +503,7 @@ define([
return ;
return ;
}
}
// Try to copy, and if success, remove the element from the old location
// Try to copy, and if success, remove the element from the old location
if ( copyElement ( p , newPath ) ) {
if ( copyElement ( p .slice ( ) , newPath ) ) {
toRemove . push ( p ) ;
toRemove . push ( p ) ;
}
}
} ) ;
} ) ;
@ -552,11 +519,10 @@ define([
// ADD
// ADD
var add = exp . add = function ( data , path ) {
var add = exp . add = function ( i d, path ) {
if ( ! Cryptpad . isLoggedIn ( ) ) { return ; }
if ( ! Cryptpad . isLoggedIn ( ) ) { return ; }
var data = files [ FILES _DATA ] [ id ] ;
if ( ! data || typeof ( data ) !== "object" ) { return ; }
if ( ! data || typeof ( data ) !== "object" ) { return ; }
var href = data . href ;
var name = data . title ;
var newPath = path , parentEl ;
var newPath = path , parentEl ;
if ( path && ! Array . isArray ( path ) ) {
if ( path && ! Array . isArray ( path ) ) {
newPath = decodeURIComponent ( path ) . split ( ',' ) ;
newPath = decodeURIComponent ( path ) . split ( ',' ) ;
@ -564,43 +530,20 @@ define([
// Add to href array
// Add to href array
if ( path && isPathIn ( newPath , [ 'hrefArray' ] ) ) {
if ( path && isPathIn ( newPath , [ 'hrefArray' ] ) ) {
parentEl = find ( newPath ) ;
parentEl = find ( newPath ) ;
parentEl . push ( href ) ;
parentEl . push ( id ) ;
return ;
return ;
}
}
// Add to root if path is ROOT or if no path
// Add to root if path is ROOT or if no path
var filesList = getFiles ( [ ROOT , TRASH , 'hrefArray' ] ) ;
var filesList = getFiles ( [ ROOT , TRASH , 'hrefArray' ] ) ;
if ( ( path && isPathIn ( newPath , [ ROOT ] ) || filesList . indexOf ( href ) === - 1 ) && name ) {
if ( path && isPathIn ( newPath , [ ROOT ] ) || filesList . indexOf ( href ) === - 1 ) {
parentEl = find ( newPath || [ ROOT ] ) ;
parentEl = find ( newPath || [ ROOT ] ) ;
if ( parentEl ) {
if ( parentEl ) {
var newName = getAvailableName ( parentEl , name ) ;
var newName = getAvailableName ( parentEl , Cryptpad. createChannelId ( ) ) ;
parentEl [ newName ] = href ;
parentEl [ newName ] = id ;
return ;
return ;
}
}
}
}
} ;
} ;
exp . addFile = function ( filePath , name , type , cb ) {
var parentEl = findElement ( files , filePath ) ;
var fileName = getAvailableName ( parentEl , name || NEW _FILE _NAME ) ;
var href = '/' + type + '/#' + Cryptpad . createRandomHash ( ) ;
pushFileData ( {
href : href ,
title : fileName ,
atime : + new Date ( ) ,
ctime : + new Date ( )
} , function ( err ) {
if ( err ) {
logError ( err ) ;
return void cb ( err ) ;
}
parentEl [ fileName ] = href ;
var newPath = filePath . slice ( ) ;
newPath . push ( fileName ) ;
cb ( void 0 , {
newPath : newPath
} ) ;
} ) ;
} ;
exp . addFolder = function ( folderPath , name , cb ) {
exp . addFolder = function ( folderPath , name , cb ) {
var parentEl = find ( folderPath ) ;
var parentEl = find ( folderPath ) ;
var folderName = getAvailableName ( parentEl , name || NEW _FOLDER _NAME ) ;
var folderName = getAvailableName ( parentEl , name || NEW _FOLDER _NAME ) ;
@ -614,19 +557,15 @@ define([
// FORGET (move with href not path)
// FORGET (move with href not path)
exp . forget = function ( href ) {
exp . forget = function ( href ) {
var id = getIdFromHref ( href ) ;
if ( ! id ) { return ; }
if ( ! Cryptpad . isLoggedIn ( ) ) {
if ( ! Cryptpad . isLoggedIn ( ) ) {
// delete permanently
// delete permanently
var data = getFileData ( href ) ;
exp . removePadAttribute ( href ) ;
if ( data ) {
spliceFileData ( id ) ;
var i = find ( [ FILES _DATA ] ) . indexOf ( data ) ;
if ( i !== - 1 ) {
exp . removePadAttribute ( href ) ;
spliceFileData ( i ) ;
}
}
return ;
return ;
}
}
var paths = findFile ( href ) ;
var paths = findFile ( id ) ;
move ( paths , [ TRASH ] ) ;
move ( paths , [ TRASH ] ) ;
} ;
} ;
@ -648,29 +587,21 @@ define([
} ) ;
} ) ;
} ;
} ;
var checkDeletedFiles = function ( ) {
var checkDeletedFiles = function ( ) {
// Nothing in FILES_DATA for workgroups
// Nothing in OLD_ FILES_DATA for workgroups
if ( workgroup || ! Cryptpad . isLoggedIn ( ) ) { return ; }
if ( workgroup || ! Cryptpad . isLoggedIn ( ) ) { return ; }
var filesList = getFiles ( [ ROOT , 'hrefArray' , TRASH ] ) ;
var filesList = getFiles ( [ ROOT , 'hrefArray' , TRASH ] ) ;
var toRemove = [ ] ;
var fData = files [ FILES _DATA ] ;
files [ FILES _DATA ] . forEach ( function ( arr ) {
getFiles ( [ FILES _DATA ] ) . forEach ( function ( id ) {
var f = arr . href ;
if ( filesList . indexOf ( id ) === - 1 ) {
if ( filesList . indexOf ( f ) === - 1 ) {
removePadAttribute ( fData [ id ] . href ) ;
toRemove . push ( arr ) ;
spliceFileData ( id ) ;
}
} ) ;
toRemove . forEach ( function ( f ) {
var idx = files [ FILES _DATA ] . indexOf ( f ) ;
if ( idx !== - 1 ) {
debug ( "Removing" , f , "from filesData" ) ;
spliceFileData ( idx ) ;
removePadAttribute ( f . href ) ;
}
}
} ) ;
} ) ;
} ;
} ;
var deleteHrefs = function ( href s) {
var deleteHrefs = function ( ids ) {
href s. forEach ( function ( obj ) {
ids . forEach ( function ( obj ) {
var idx = files [ obj . root ] . indexOf ( obj . href ) ;
var idx = files [ obj . root ] . indexOf ( obj . id ) ;
files [ obj . root ] . splice ( idx , 1 ) ;
files [ obj . root ] . splice ( idx , 1 ) ;
} ) ;
} ) ;
} ;
} ;
@ -690,27 +621,24 @@ define([
var toSplice = [ ] ;
var toSplice = [ ] ;
allFilesPaths . forEach ( function ( path ) {
allFilesPaths . forEach ( function ( path ) {
var el = find ( path ) ;
var el = find ( path ) ;
toSplice . push ( el ) ;
if ( ! el ) { return ; }
} ) ;
var id = getIdFromHref ( el . href ) ;
toSplice . forEach ( function ( el ) {
if ( ! id ) { return ; }
var i = find ( [ FILES _DATA ] ) . indexOf ( el ) ;
spliceFileData ( id ) ;
if ( i === - 1 ) { return ; }
removePadAttribute ( el . href ) ;
removePadAttribute ( el . href ) ;
console . log ( el . href ) ;
spliceFileData ( i ) ;
} ) ;
} ) ;
return ;
return ;
}
}
var href s = [ ] ;
var id s = [ ] ;
hrefPaths . forEach ( function ( path ) {
hrefPaths . forEach ( function ( path ) {
var href = find ( path ) ;
var id = find ( path ) ;
href s. push ( {
id s. push ( {
root : path [ 0 ] ,
root : path [ 0 ] ,
href: href
id: id
} ) ;
} ) ;
} ) ;
} ) ;
deleteHrefs ( href s) ;
deleteHrefs ( id s) ;
rootPaths . forEach ( function ( path ) {
rootPaths . forEach ( function ( path ) {
var parentPath = path . slice ( ) ;
var parentPath = path . slice ( ) ;
@ -741,7 +669,7 @@ define([
deleteMultipleTrashRoot ( trashRoot ) ;
deleteMultipleTrashRoot ( trashRoot ) ;
// In some cases, we want to remove pads from a location without removing them from
// In some cases, we want to remove pads from a location without removing them from
// FILES_DATA (replaceHref)
// OLD_ FILES_DATA (replaceHref)
if ( ! nocheck ) { checkDeletedFiles ( ) ; }
if ( ! nocheck ) { checkDeletedFiles ( ) ; }
} ;
} ;
exp . delete = function ( paths , cb , nocheck ) {
exp . delete = function ( paths , cb , nocheck ) {
@ -760,65 +688,70 @@ define([
logError ( 'Renaming `root` is forbidden' ) ;
logError ( 'Renaming `root` is forbidden' ) ;
return ;
return ;
}
}
if ( ! newName || newName . trim ( ) === "" ) { return ; }
// Copy the element path and remove the last value to have the parent path and the old name
// Copy the element path and remove the last value to have the parent path and the old name
var element = find ( path ) ;
var element = find ( path ) ;
var parentPath = path . slice ( ) ;
var oldName = parentPath . pop ( ) ;
// Folders
if ( oldName === newName ) {
if ( isFolder ( element ) ) {
var parentPath = path . slice ( ) ;
var oldName = parentPath . pop ( ) ;
if ( ! newName || ! newName . trim ( ) || oldName === newName ) { return ; }
var parentEl = find ( parentPath ) ;
if ( typeof ( parentEl [ newName ] ) !== "undefined" ) {
log ( Messages . fo _existingNameError ) ;
return ;
}
parentEl [ newName ] = element ;
parentEl [ oldName ] = undefined ;
delete parentEl [ oldName ] ;
if ( typeof cb === "function" ) { cb ( ) ; }
return ;
return ;
}
}
var parentEl = find ( parentPath ) ;
if ( typeof ( parentEl [ newName ] ) !== "undefined" ) {
// Files
log ( Messages . fo _existingNameError ) ;
var data = files [ FILES _DATA ] [ element ] ;
if ( ! data ) { return ; }
if ( ! newName || newName . trim ( ) === "" ) {
data . filename = undefined ;
delete data . filename ;
if ( typeof cb === "function" ) { cb ( ) ; }
return ;
return ;
}
}
parentEl [ newName ] = element ;
var oldName = getTitle ( element , 'name' ) ;
parentEl [ oldName ] = undefined ;
if ( oldName === newName ) { return ; }
delete parentEl [ oldName ] ;
data . filename = newName ;
if ( typeof cb === "function" ) { cb ( ) ; }
if ( typeof cb === "function" ) { cb ( ) ; }
} ;
} ;
// REPLACE
// REPLACE
var replaceFile = function ( path , o , n ) {
var root = find ( path ) ;
if ( isFile ( root ) ) { return ; }
for ( var e in root ) {
if ( isFile ( root [ e ] ) ) {
if ( compareFiles ( o , root [ e ] ) ) {
root [ e ] = n ;
}
} else {
var nPath = path . slice ( ) ;
nPath . push ( e ) ;
replaceFile ( nPath , o , n ) ;
}
}
} ;
// Replace a href by a stronger one everywhere in the drive (except FILES_DATA)
exp . replace = function ( o , n ) {
exp . replace = function ( o , n ) {
if ( ! isFile ( o ) || ! isFile ( n ) ) { return ; }
var idO = getIdFromHref ( o ) ;
var paths = findFile ( o ) ;
if ( ! idO || ! isFile ( idO ) ) { return ; }
var data = getFileData ( idO ) ;
if ( ! data ) { return ; }
data . href = n ;
} ;
// If all the occurences of an href are in the trash, remvoe them and add the file in root.
// This is use with setPadTitle when we open a stronger version of a deleted pad
exp . restoreHref = function ( href ) {
var idO = getIdFromHref ( href ) ;
if ( ! idO || ! isFile ( idO ) ) { return ; }
var paths = findFile ( idO ) ;
// Remove all the occurences in the trash
// Remove all the occurences in the trash
// Replace all the occurences not in the trash
// If all the occurences are in the trash or no occurence, add the pad to root
// If all the occurences are in the trash or no occurence, add the pad to unsorted
var allInTrash = true ;
var allInTrash = true ;
paths . forEach ( function ( p ) {
paths . forEach ( function ( p ) {
if ( p [ 0 ] === TRASH ) {
if ( p [ 0 ] === TRASH ) {
exp . delete ( p , null , true ) ; // 3rd parameter means skip "checkDeletedFiles"
exp . delete ( p , null , true ) ; // 3rd parameter means skip "checkDeletedFiles"
return ;
return ;
} else {
allInTrash = false ;
var parentPath = p . slice ( ) ;
var key = parentPath . pop ( ) ;
var parentEl = find ( parentPath ) ;
parentEl [ key ] = n ;
}
}
allInTrash = false ;
} ) ;
} ) ;
if ( allInTrash ) {
if ( allInTrash ) {
add ( n ) ;
add ( idO ) ;
}
}
} ;
} ;
@ -831,7 +764,7 @@ define([
// * 'root', 'trash', 'unsorted' and 'filesData' exist and are objects
// * 'root', 'trash', 'unsorted' and 'filesData' exist and are objects
// * ROOT: Folders are objects, files are href
// * ROOT: Folders are objects, files are href
// * TRASH: Trash root contains only arrays, each element of the array is an object {element:.., path:..}
// * TRASH: Trash root contains only arrays, each element of the array is an object {element:.., path:..}
// * FILES_DATA: - Data (title, cdate, adte) are stored in filesData. filesData contains only href keys linking to object with title, cdate, adate.
// * OLD_ FILES_DATA: - Data (title, cdate, adte) are stored in filesData. filesData contains only href keys linking to object with title, cdate, adate.
// - Dates (adate, cdate) can be parsed/formatted
// - Dates (adate, cdate) can be parsed/formatted
// - All files in filesData should be either in 'root', 'trash' or 'unsorted'. If that's not the case, copy the fily to 'unsorted'
// - All files in filesData should be either in 'root', 'trash' or 'unsorted'. If that's not the case, copy the fily to 'unsorted'
// * TEMPLATE: Contains only files (href), and does not contains files that are in ROOT
// * TEMPLATE: Contains only files (href), and does not contains files that are in ROOT
@ -843,7 +776,7 @@ define([
if ( typeof ( files [ ROOT ] ) !== "object" ) { debug ( "ROOT was not an object" ) ; files [ ROOT ] = { } ; }
if ( typeof ( files [ ROOT ] ) !== "object" ) { debug ( "ROOT was not an object" ) ; files [ ROOT ] = { } ; }
var element = elem || files [ ROOT ] ;
var element = elem || files [ ROOT ] ;
for ( var el in element ) {
for ( var el in element ) {
if ( ! isFile ( element [ el ] ) && ! isFolder ( element [ el ] ) ) {
if ( ! isFile ( element [ el ] , true ) && ! isFolder ( element [ el ] ) ) {
debug ( "An element in ROOT was not a folder nor a file. " , element [ el ] ) ;
debug ( "An element in ROOT was not a folder nor a file. " , element [ el ] ) ;
element [ el ] = undefined ;
element [ el ] = undefined ;
delete element [ el ] ;
delete element [ el ] ;
@ -857,7 +790,7 @@ define([
// We have an old file (href) which is not in filesData: add it
// We have an old file (href) which is not in filesData: add it
var id = Cryptpad . createRandomInteger ( ) ;
var id = Cryptpad . createRandomInteger ( ) ;
var key = Cryptpad . createChannelId ( ) ;
var key = Cryptpad . createChannelId ( ) ;
files [ NEW_ FILES_DATA ] [ id ] = { href : element [ el ] , filename : el } ;
files [ FILES_DATA ] [ id ] = { href : element [ el ] , filename : el } ;
element [ key ] = id ;
element [ key ] = id ;
delete element [ el ] ;
delete element [ el ] ;
}
}
@ -869,21 +802,25 @@ define([
var toClean ;
var toClean ;
var addToClean = function ( obj , idx , el ) {
var addToClean = function ( obj , idx , el ) {
if ( typeof ( obj ) !== "object" ) { toClean . push ( idx ) ; return ; }
if ( typeof ( obj ) !== "object" ) { toClean . push ( idx ) ; return ; }
if ( ! isFile ( obj . element ) && ! isFolder ( obj . element ) ) { toClean . push ( idx ) ; return ; }
if ( ! isFile ( obj . element , true ) && ! isFolder ( obj . element ) ) { toClean . push ( idx ) ; return ; }
if ( ! $ . isArray ( obj . path ) ) { toClean . push ( idx ) ; return ; }
if ( ! $ . isArray ( obj . path ) ) { toClean . push ( idx ) ; return ; }
if ( typeof obj . element === "string" ) {
if ( typeof obj . element === "string" ) {
// We have an old file (href) which is not in filesData: add it
// We have an old file (href) which is not in filesData: add it
var id = Cryptpad . createRandomInteger ( ) ;
var id = Cryptpad . createRandomInteger ( ) ;
files [ NEW_ FILES_DATA ] [ id ] = { href : obj . element , filename : el } ;
files [ FILES_DATA ] [ id ] = { href : obj . element , filename : el } ;
obj . element = id ;
obj . element = id ;
}
}
if ( isFolder ( obj . element ) ) { fixRoot ( obj . element ) ; }
if ( isFolder ( obj . element ) ) { fixRoot ( obj . element ) ; }
} ;
} ;
for ( var el in tr ) {
for ( var el in tr ) {
if ( ! $ . isArray ( tr [ el ] ) ) {
if ( ! Array . isArray ( tr [ el ] ) ) {
debug ( "An element in TRASH root is not an array. " , tr [ el ] ) ;
debug ( "An element in TRASH root is not an array. " , tr [ el ] ) ;
tr [ el ] = undefined ;
tr [ el ] = undefined ;
delete tr [ el ] ;
delete tr [ el ] ;
} else if ( tr [ el ] . length === 0 ) {
debug ( "Empty array in TRASH root. " , tr [ el ] ) ;
tr [ el ] = undefined ;
delete tr [ el ] ;
} else {
} else {
toClean = [ ] ;
toClean = [ ] ;
tr [ el ] . forEach ( function ( obj , idx ) { addToClean ( obj , idx , el ) ; } ) ;
tr [ el ] . forEach ( function ( obj , idx ) { addToClean ( obj , idx , el ) ; } ) ;
@ -900,13 +837,13 @@ define([
var rootFiles = getFiles ( [ ROOT ] ) . slice ( ) ;
var rootFiles = getFiles ( [ ROOT ] ) . slice ( ) ;
var toClean = [ ] ;
var toClean = [ ] ;
us . forEach ( function ( el , idx ) {
us . forEach ( function ( el , idx ) {
if ( ! isFile ( el ) || rootFiles . indexOf ( el ) !== - 1 ) {
if ( ! isFile ( el , true ) || rootFiles . indexOf ( el ) !== - 1 ) {
toClean . push ( idx ) ;
toClean . push ( idx ) ;
}
}
if ( typeof el === "string" ) {
if ( typeof el === "string" ) {
// We have an old file (href) which is not in filesData: add it
// We have an old file (href) which is not in filesData: add it
var id = Cryptpad . createRandomInteger ( ) ;
var id = Cryptpad . createRandomInteger ( ) ;
files [ NEW_ FILES_DATA ] [ id ] = { href : el } ;
files [ FILES_DATA ] [ id ] = { href : el } ;
us [ idx ] = id ;
us [ idx ] = id ;
}
}
} ) ;
} ) ;
@ -915,8 +852,8 @@ define([
} ) ;
} ) ;
} ;
} ;
var fixFilesData = function ( ) {
var fixFilesData = function ( ) {
if ( typeof files [ NEW_ FILES_DATA ] !== "object" ) { debug ( " FILES_DATA was not an object") ; files [ NEW_ FILES_DATA ] = { } ; }
if ( typeof files [ FILES_DATA ] !== "object" ) { debug ( " OLD_ FILES_DATA was not an object") ; files [ FILES_DATA ] = { } ; }
var fd = files [ NEW_ FILES_DATA ] ;
var fd = files [ FILES_DATA ] ;
var rootFiles = getFiles ( [ ROOT , TRASH , 'hrefArray' ] ) ;
var rootFiles = getFiles ( [ ROOT , TRASH , 'hrefArray' ] ) ;
var root = find ( [ ROOT ] ) ;
var root = find ( [ ROOT ] ) ;
var toClean = [ ] ;
var toClean = [ ] ;
@ -925,12 +862,12 @@ define([
var el = fd [ id ] ;
var el = fd [ id ] ;
if ( ! el || typeof ( el ) !== "object" ) {
if ( ! el || typeof ( el ) !== "object" ) {
debug ( "An element in filesData was not an object." , el ) ;
debug ( "An element in filesData was not an object." , el ) ;
toClean . push ( el ) ;
toClean . push ( id ) ;
continue ;
continue ;
}
}
if ( ! el . href ) {
if ( ! el . href ) {
debug ( "Removing an element in filesData with a missing href." , el ) ;
debug ( "Removing an element in filesData with a missing href." , el ) ;
toClean . push ( el ) ;
toClean . push ( id ) ;
continue ;
continue ;
}
}
if ( Cryptpad . isLoggedIn ( ) && rootFiles . indexOf ( id ) === - 1 ) {
if ( Cryptpad . isLoggedIn ( ) && rootFiles . indexOf ( id ) === - 1 ) {
@ -940,19 +877,16 @@ define([
continue ;
continue ;
}
}
} ;
} ;
toClean . forEach ( function ( el ) {
toClean . forEach ( function ( id ) {
var idx = fd . indexOf ( el ) ;
spliceFileData ( id ) ;
if ( idx !== - 1 ) {
spliceFileData ( idx ) ;
}
} ) ;
} ) ;
} ;
} ;
// Make sure unsorted doesn't exist anymore
// Make sure unsorted doesn't exist anymore
// Note: Unsorted only works with ld structure where pads are href
// Note: Unsorted only works with the o ld structure where pads are href
// It should be called before the migration code
// It should be called before the migration code
var fixUnsorted = function ( ) {
var fixUnsorted = function ( ) {
if ( ! files [ UNSORTED ] || ! files [ FILES_DATA ] ) { return ; }
if ( ! files [ UNSORTED ] || ! files [ OLD_ FILES_DATA ] ) { return ; }
debug ( "UNSORTED still exists in the object, removing it..." ) ;
debug ( "UNSORTED still exists in the object, removing it..." ) ;
var us = files [ UNSORTED ] ;
var us = files [ UNSORTED ] ;
if ( us . length === 0 ) {
if ( us . length === 0 ) {
@ -964,38 +898,34 @@ define([
if ( typeof el !== "string" ) {
if ( typeof el !== "string" ) {
return ;
return ;
}
}
var data = files [ FILES_DATA ] . filter ( function ( x ) {
var data = files [ OLD_ FILES_DATA ] . filter ( function ( x ) {
return x . href === el ;
return x . href === el ;
} ) ;
} ) ;
if ( data . length === 0 ) {
if ( data . length === 0 ) {
files [ FILES_DATA ] . push ( {
files [ OLD_ FILES_DATA ] . push ( {
href : el
href : el
} ) ;
} ) ;
}
}
return ;
return ;
/ *
TODO remove
var name = data . length !== 0 ? data [ 0 ] . title : NEW _FILE _NAME ;
var newName = getAvailableName ( root , name ) ;
root [ newName ] = el ;
* /
} ) ;
} ) ;
delete files [ UNSORTED ] ;
delete files [ UNSORTED ] ;
} ;
} ;
// TODO: getRecentPads in cryptpad-common
// mergeDrive...
// TODO: in fixRoot, trash and template, make sure we have a filedata associated to the id
var migrateToNewFormat = function ( ) {
var migrateToNewFormat = function ( ) {
if ( ! files [ FILES_DATA ] ) { return ; }
if ( ! files [ OLD _FILES _DATA ] ) { return ; }
try {
try {
var oldData = files [ FILES _DATA ] . slice ( ) ;
var oldData = files [ OLD _FILES _DATA ] . slice ( ) ;
var newData = files [ NEW _FILES _DATA ] = { } ;
if ( ! files [ FILES _DATA ] ) {
files [ FILES _DATA ] = { } ;
}
var newData = files [ FILES _DATA ] ;
//var oldFiles = oldData.map(function (o) { return o.href; });
//var oldFiles = oldData.map(function (o) { return o.href; });
oldData . forEach ( function ( obj ) {
oldData . forEach ( function ( obj ) {
if ( ! obj || ! obj . href ) { return ; }
if ( ! obj || ! obj . href ) { return ; }
var href = obj . href ;
var href = obj . href ;
var id = Cryptpad . createRandomInteger ( ) ;
var id = Cryptpad . createRandomInteger ( ) ;
var paths = findFile ( href ) ;
var paths = findFile ( href ) ;
var data = getFileData( href ) ;
var data = obj ;
var key = Cryptpad . createChannelId ( ) ;
var key = Cryptpad . createChannelId ( ) ;
if ( data ) {
if ( data ) {
newData [ id ] = data ;
newData [ id ] = data ;
@ -1021,7 +951,7 @@ define([
delete parent [ okey ] ;
delete parent [ okey ] ;
} ) ;
} ) ;
} ) ;
} ) ;
delete files [ FILES_DATA ] ;
delete files [ OLD_ FILES_DATA ] ;
} catch ( e ) {
} catch ( e ) {
console . error ( e ) ;
console . error ( e ) ;
}
}