2015-05-21 14:32:51 +02:00
/ *
Copyright 2008 - 2015 Clipperz Srl
This file is part of Clipperz , the online password manager .
For further information about its features and functionalities please
refer to http : //www.clipperz.com.
* Clipperz is free software : you can redistribute it and / or modify it
under the terms of the GNU Affero General Public License as published
by the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
* Clipperz is distributed in the hope that it will be useful , but
WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
See the GNU Affero General Public License for more details .
* You should have received a copy of the GNU Affero General Public
License along with Clipperz . If not , see http : //www.gnu.org/licenses/.
* /
"use strict" ;
Clipperz . Base . module ( 'Clipperz.PM.UI' ) ;
// https://github.com/eligrey/FileSaver.js
// https://github.com/eligrey/Blob.js
Clipperz . PM . UI . ExportController = function ( args ) {
this . _recordsInfo = args [ 'recordsInfo' ] || Clipperz . Base . exception . raise ( 'MandatoryParameter' ) ;
this . _processedRecords = 0 ;
this . _style =
"body {" +
"font-family: 'Dejavu Sans', monospace;" +
"margin: 0px;" +
"}" +
"header {" +
"padding: 10px;" +
"border-bottom: 2px solid black;" +
"}" +
2015-06-27 19:08:20 +02:00
"header p span {" +
// "padding: 0px 4px;" +
"font-weight: bold;" +
"}" +
2015-05-21 14:32:51 +02:00
"h1 {" +
"margin: 0px;" +
"}" +
"h2 {" +
"margin: 0px;" +
"padding-top: 10px;" +
"}" +
"h3 {" +
"margin: 0px;" +
"}" +
"h5 {" +
"margin: 0px;" +
"color: gray;" +
"}" +
"ul {" +
"margin: 0px;" +
"padding: 0px;" +
"}" +
"div > ul > li {" +
"border-bottom: 1px solid black;" +
"padding: 10px;" +
"}" +
"div > ul > li.archived {" +
"background-color: #ddd;" +
"}" +
"ul > li > ul > li {" +
"font-size: 9pt;" +
"display: inline-block;" +
"}" +
"ul > li > ul > li:after {" +
"content: \",\";" +
"padding-right: 5px;" +
"}" +
"ul > li > ul > li:last-child:after {" +
"content: \"\";" +
"padding-right: 0px;" +
"}" +
"dl {" +
"}" +
"dt {" +
"color: gray;" +
"font-size: 9pt;" +
"}" +
"dd {" +
"margin: 0px;" +
"margin-bottom: 5px;" +
"padding-left: 10px;" +
2015-06-27 19:08:20 +02:00
"font-size: 13pt;" +
2015-05-21 14:32:51 +02:00
"}" +
"div > div {" +
"background-color: black;" +
"color: white;" +
"padding: 10px;" +
"}" +
2015-06-27 19:08:20 +02:00
"li p, dd.hidden {" +
"white-space: pre-wrap;" +
"word-wrap: break-word;" +
"font-family: monospace;" +
"}" +
2015-05-21 14:32:51 +02:00
"textarea {" +
2015-06-27 19:08:20 +02:00
"display: none" +
// "width: 100%;" +
// "height: 200px;" +
"}" +
"a {" +
"color: white;" +
2015-05-21 14:32:51 +02:00
"}" +
"@media print {" +
"div > div, header > div {" +
"display: none !important;" +
"}" +
2015-06-27 19:08:20 +02:00
"div > ul > li.archived {" +
"color: #ddd;" +
"}" +
2015-05-21 14:32:51 +02:00
"ul > li {" +
"page-break-inside: avoid;" +
"} " +
"}" +
"" ;
return this ;
}
MochiKit . Base . update ( Clipperz . PM . UI . ExportController . prototype , {
'toString' : function ( ) {
return "Clipperz.PM.UI.ExportController" ;
} ,
//-----------------------------------------------------------------------------
'recordsInfo' : function ( ) {
return this . _recordsInfo ;
} ,
//=============================================================================
'reportRecordExport' : function ( aRecordData ) {
var percentage ;
var exportedCardsCount ;
var totalCardsToExport ;
this . _processedRecords = this . _processedRecords + 1 ;
exportedCardsCount = this . _processedRecords ;
totalCardsToExport = this . recordsInfo ( ) . length ;
percentage = Math . round ( 100 * exportedCardsCount / totalCardsToExport ) ;
//console.log("PROCESSING " + exportedCardsCount + "/" + totalCardsToExport + " - " + percentage + "%");
MochiKit . Signal . signal ( Clipperz . Signal . NotificationCenter , 'updateProgress' , percentage ) ;
return MochiKit . Async . succeed ( aRecordData ) ;
} ,
//=============================================================================
'renderCardToHtml' : function ( jsonCardData ) {
var label = Clipperz . PM . DataModel . Record . extractLabelFromFullLabel ( jsonCardData . label ) ;
var allTags = MochiKit . Base . keys ( Clipperz . PM . DataModel . Record . extractTagsFromFullLabel ( jsonCardData . label ) ) ;
var regularTags = MochiKit . Base . filter ( Clipperz . PM . DataModel . Record . isRegularTag , allTags ) ;
var isArchived = MochiKit . Iter . some ( allTags , MochiKit . Base . partial ( MochiKit . Base . objEqual , Clipperz . PM . DataModel . Record . archivedTag ) ) ;
return MochiKit . DOM . LI ( { 'class' : isArchived ? 'archived' : "" } ,
MochiKit . DOM . H2 ( { } , label ) ,
( regularTags . length > 0 ) ? MochiKit . DOM . UL ( { } , MochiKit . Base . map ( function ( tag ) { return MochiKit . DOM . LI ( { } , tag ) ; } , regularTags ) ) : null ,
MochiKit . DOM . DIV ( { } ,
MochiKit . DOM . DL ( { } ,
MochiKit . Base . map ( function ( key ) {
2015-06-27 19:08:20 +02:00
var isHiddenField = jsonCardData . currentVersion . fields [ key ] [ 'hidden' ] ;
2015-05-21 14:32:51 +02:00
return [
2015-06-27 19:08:20 +02:00
MochiKit . DOM . DT ( { } , jsonCardData . currentVersion . fields [ key ] [ 'label' ] ) ,
MochiKit . DOM . DD ( ( isHiddenField ? { 'class' : 'hidden' } : { } ) , jsonCardData . currentVersion . fields [ key ] [ 'value' ] ) ,
2015-05-21 14:32:51 +02:00
] ;
} , MochiKit . Base . keys ( jsonCardData . currentVersion . fields ) )
)
) ,
jsonCardData . data . notes ? MochiKit . DOM . P ( { } , jsonCardData . data . notes ) : null
) ;
} ,
'renderToHtml' : function ( jsonData ) {
2015-06-27 19:08:20 +02:00
var title ;
var style ;
var now ;
var dateString ;
var timeString
var body ;
2015-05-21 14:32:51 +02:00
title = "Clipperz data" ;
style = this . _style ;
2015-06-27 19:08:20 +02:00
now = new XDate ( ) ;
dateString = now . toString ( "MMM d, yyyy" ) ;
timeString = now . toString ( "HH:mm" ) ;
2015-05-21 14:32:51 +02:00
body = MochiKit . DOM . DIV ( { } ,
MochiKit . DOM . HEADER ( { } ,
MochiKit . DOM . H1 ( { } , "Your data on Clipperz" ) ,
2015-06-27 19:08:20 +02:00
MochiKit . DOM . H5 ( { } , "Export generated on " + dateString + " at " + timeString ) ,
2015-05-21 14:32:51 +02:00
MochiKit . DOM . DIV ( { } ,
2015-06-27 19:08:20 +02:00
MochiKit . DOM . P ( { } , "Security warning - This file lists the content of all your cards in a printer-friendly format" ) ,
MochiKit . DOM . P ( { } , [
"Beware: " ,
MochiKit . DOM . SPAN ( { 'class' : 'warning' } , "all data are unencrypted!" ) ,
" Therefore make sure to properly store and manage this file. We recommend to delete it as soon as it is no longer needed."
] ) ,
2015-05-21 14:32:51 +02:00
MochiKit . DOM . P ( { } , "If you are going to print its content on paper, store the printout in a safe and private place!" ) ,
MochiKit . DOM . P ( { } , "And, if you need to access your data when no Internet connection is available, please consider the much safer option of creating an offline copy." )
)
) ,
MochiKit . DOM . UL ( { } , MochiKit . Base . map ( this . renderCardToHtml , jsonData ) ) ,
MochiKit . DOM . DIV ( { } ,
2015-06-27 19:08:20 +02:00
// MochiKit.DOM.H3({}, "JSON content"),
// MochiKit.DOM.DIV({},
// MochiKit.DOM.P({}, "Instructions on how to use JSON content"),
// MochiKit.DOM.P({}, "The JSON version of your data may be useful if you want to move the whole content of your Clipperz account to a new Clipperz account or recover a card that has been accidentally deleted. Just follow these instructions:"),
// MochiKit.DOM.OL({},
// MochiKit.DOM.LI({}, "Login to your Clipperz account and go to \"Data > Import\"."),
// MochiKit.DOM.LI({}, "Select the JSON option."),
// MochiKit.DOM.LI({}, "Copy and paste the JSON content in the form.")
// ),
// MochiKit.DOM.P({}, "Of course, the unencrypted JSON content won't be transmitted to the Clipperz server.")
// ),
2015-05-21 14:32:51 +02:00
MochiKit . DOM . TEXTAREA ( { } , Clipperz . Base . serializeJSON ( jsonData ) ) ,
MochiKit . DOM . FOOTER ( { } ,
MochiKit . DOM . P ( { } ,
2015-06-27 19:08:20 +02:00
"This file has been downloaded from " ,
MochiKit . DOM . A ( { 'href' : 'https://clipperz.is' } , "clipperz.is" ) ,
", a service by Clipperz Srl. - " ,
2015-05-21 14:32:51 +02:00
MochiKit . DOM . A ( { 'href' : 'https://clipperz.is/terms_service/' } , "Terms of service" ) ,
" - " ,
MochiKit . DOM . A ( { 'href' : 'https://clipperz.is/privacy_policy/' } , "Privacy policy" )
2015-06-27 19:08:20 +02:00
)
// MochiKit.DOM.H4({}, "Clipperz - keep it to yourself")
2015-05-21 14:32:51 +02:00
)
)
) ;
2015-06-27 19:08:20 +02:00
return '<html><head><title>' + title + '</title><style type="text/css">' + style + '</style><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body>' + MochiKit . DOM . toHTML ( body ) + '</body></html>' ;
2015-05-21 14:32:51 +02:00
} ,
//----------------------------------------------------------------------------
'saveResult' : function ( exportedJSON ) {
var blob ;
var sortedJSON ;
2015-07-04 18:43:59 +02:00
var now = new XDate ( ) ;
var dateString = now . toString ( 'yyyyMMdd' ) ;
2015-05-21 14:32:51 +02:00
sortedJSON = MochiKit . Iter . sorted ( exportedJSON , function ( a , b ) { return a . label . toUpperCase ( ) . localeCompare ( b . label . toUpperCase ( ) ) ; } ) ;
blob = new Blob ( [ this . renderToHtml ( sortedJSON ) ] , { type : "text/html;charset=utf-8" } ) ;
2015-07-04 18:43:59 +02:00
saveAs ( blob , dateString + '-Clipperz_Export.html' ) ;
2015-05-21 14:32:51 +02:00
} ,
//=============================================================================
'run' : function ( ) {
var deferredResult ;
var self = this ;
deferredResult = new Clipperz . Async . Deferred ( "ExportController.run" , { trace : false } ) ;
deferredResult . addCallback ( MochiKit . Base . map , function ( recordIn ) {
var innerDeferredResult ;
innerDeferredResult = new Clipperz . Async . Deferred ( "ExportController.run__exportRecord" , { trace : false } ) ;
innerDeferredResult . addMethod ( recordIn . _rowObject , 'export' ) ;
innerDeferredResult . addMethod ( self , 'reportRecordExport' ) ;
innerDeferredResult . callback ( ) ;
return innerDeferredResult ;
} ) ;
deferredResult . addCallback ( Clipperz . Async . collectAll ) ;
deferredResult . addMethod ( this , 'saveResult' ) ;
deferredResult . callback ( this . recordsInfo ( ) ) ;
return deferredResult ;
} ,
//=============================================================================
_ _syntaxFix _ _ : "syntax fix"
} ) ;