@ -1,81 +1,59 @@
define ( [
'jquery' ,
'/bower_components/chainpad-crypto/crypto.js' ,
'/common/toolbar3.js' ,
'json.sortify' ,
'/common/common-util.js' ,
'/bower_components/nthen/index.js' ,
'/common/sframe-common.js' ,
'/common/sframe-app-framework.js' ,
'/common/common-util.js' ,
'/common/common-hash.js' ,
'/common/common-interface.js' ,
'/api/config' ,
'/common/common-realtime.js' ,
'/common/common-thumbnail.js' ,
'/customize/pages.js' ,
'/customize/messages.js' ,
'/customize/application_config.js' ,
'/common/common-thumbnail.js' ,
'/whiteboard/colors.js' ,
'/customize/application_config.js' ,
'/bower_components/chainpad/chainpad.dist.js' ,
'/bower_components/secure-fabric.js/dist/fabric.min.js' ,
'/bower_components/file-saver/FileSaver.min.js' ,
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css' ,
'css!/bower_components/components-font-awesome/css/font-awesome.min.css' ,
'less!/customize/src/less2/main.less' ,
] , function (
$ ,
Crypto ,
Toolbar ,
JSONSortify ,
Util ,
Sortify ,
nThen ,
SFCommon ,
Framework ,
Util ,
Hash ,
UI ,
ApiConfig ,
CommonRealtime ,
Thumb ,
Pages ,
Messages ,
AppConfig ,
Thumb ,
Colors ,
AppConfig ,
ChainPad )
{
var saveAs = window . saveAs ;
var APP = window . APP = {
$ : $
} ;
var Fabric = APP . Fabric = window . fabric ;
var stringify = function ( obj ) {
return JSONSortify ( obj ) ;
} ;
var toolbar ;
var verbose = function ( x ) { console . log ( x ) ; } ;
verbose = function ( ) { } ; // comment out to enable verbose logging
var andThen = function ( common ) {
var config = { } ;
/* Initialize Fabric */
var canvas = APP . canvas = new Fabric . Canvas ( 'cp-app-whiteboard-canvas' , {
containerClass : 'cp-app-whiteboard-canvas-container'
} ) ;
var $canvas = $ ( 'canvas' ) ;
var $controls = $ ( '#cp-app-whiteboard-controls' ) ;
var $canvasContainer = $ ( 'canvas' ) . parents ( '.cp-app-whiteboard-canvas-container' ) ;
var mkControls = function ( framework , canvas ) {
var $pickers = $ ( '#cp-app-whiteboard-pickers' ) ;
var $colors = $ ( '#cp-app-whiteboard-colors' ) ;
var $cursors = $ ( '#cp-app-whiteboard-cursors' ) ;
var $deleteButton = $ ( '#cp-app-whiteboard-delete' ) ;
var $toggle = $ ( '#cp-app-whiteboard-toggledraw' ) ;
var $controls = $ ( '#cp-app-whiteboard-controls' ) ;
var $width = $ ( '#cp-app-whiteboard-width' ) ;
var $widthLabel = $ ( 'label[for="cp-app-whiteboard-width"]' ) ;
var $opacity = $ ( '#cp-app-whiteboard-opacity' ) ;
var $opacityLabel = $ ( 'label[for="cp-app-whiteboard-opacity"]' ) ;
var $toggle = $ ( '#cp-app-whiteboard-toggledraw' ) ;
var $deleteButton = $ ( '#cp-app-whiteboard-delete' ) ;
var metadataMgr = framework . _ . cpNfInner . metadataMgr ;
// Brush
var readOnly = false ;
var brush = {
color : '#000000' ,
opacity : 1
@ -136,39 +114,6 @@ define([
updateBrushOpacity ( ) ;
$opacity . on ( 'change' , updateBrushOpacity ) ;
var pickColor = function ( current , cb ) {
var $picker = $ ( '<input>' , {
type : 'color' ,
value : '#FFFFFF' ,
} )
. on ( 'change' , function ( ) {
var color = this . value ;
cb ( color ) ;
} ) . appendTo ( $pickers ) ;
setTimeout ( function ( ) {
$picker . val ( current ) ;
$picker . click ( ) ;
} ) ;
} ;
var setColor = function ( c ) {
c = Colors . rgb2hex ( c ) ;
brush . color = c ;
canvas . freeDrawingBrush . color = Colors . hex2rgba ( brush . color , brush . opacity ) ;
APP . $color . css ( {
'color' : c ,
} ) ;
createCursor ( ) ;
} ;
var palette = AppConfig . whiteboardPalette || [
'red' , 'blue' , 'green' , 'white' , 'black' , 'purple' ,
'gray' , 'beige' , 'brown' , 'cyan' , 'darkcyan' , 'gold' , 'yellow' , 'pink'
] ;
$ ( '.cp-app-whiteboard-palette-color' ) . on ( 'click' , function ( ) {
var color = $ ( this ) . css ( 'background-color' ) ;
setColor ( color ) ;
} ) ;
APP . draw = true ;
var toggleDrawMode = function ( ) {
canvas . deactivateAll ( ) . renderAll ( ) ;
@ -191,74 +136,49 @@ define([
canvas . discardActiveGroup ( ) ;
}
canvas . renderAll ( ) ;
config. onLocal ( ) ;
framework. localChange ( ) ;
} ;
$deleteButton . click ( deleteSelection ) ;
$ ( window ) . on ( 'keyup' , function ( e ) {
if ( e . which === 46 ) { deleteSelection ( ) ; }
} ) ;
var setEditable = function ( bool ) {
APP . editable = bool ;
if ( readOnly && bool ) { return ; }
if ( bool ) { $controls . css ( 'display' , 'flex' ) ; }
else { $controls . hide ( ) ; }
canvas . isDrawingMode = bool ? APP . draw : false ;
if ( ! bool ) {
canvas . deactivateAll ( ) ;
canvas . renderAll ( ) ;
}
canvas . forEachObject ( function ( object ) {
object . selectable = bool ;
} ) ;
$canvasContainer . find ( 'canvas' ) . css ( 'border-color' , bool ? 'black' : 'red' ) ;
} ;
var saveImage = APP . saveImage = function ( ) {
var defaultName = "pretty-picture.png" ;
UI . prompt ( Messages . exportPrompt , defaultName , function ( filename ) {
if ( ! ( typeof ( filename ) === 'string' && filename ) ) { return ; }
$canvas [ 0 ] . toBlob ( function ( blob ) {
saveAs ( blob , filename ) ;
} ) ;
var pickColor = function ( current , cb ) {
var $picker = $ ( '<input>' , {
type : 'color' ,
value : '#FFFFFF' ,
} )
. on ( 'change' , function ( ) {
var color = this . value ;
cb ( color ) ;
} ) . appendTo ( $pickers ) ;
setTimeout ( function ( ) {
$picker . val ( current ) ;
$picker . click ( ) ;
} ) ;
} ;
APP . FM = common . createFileManager ( { } ) ;
APP . upload = function ( title ) {
var canvas = $canvas [ 0 ] ;
APP . canvas . deactivateAll ( ) . renderAll ( ) ;
canvas . toBlob ( function ( blob ) {
blob . name = title ;
APP . FM . handleFile ( blob ) ;
var setColor = function ( c ) {
c = Colors . rgb2hex ( c ) ;
brush . color = c ;
canvas . freeDrawingBrush . color = Colors . hex2rgba ( brush . color , brush . opacity ) ;
APP . $color . css ( {
'color' : c ,
} ) ;
createCursor ( ) ;
} ;
var initializing = true ;
var $bar = $ ( '#cp-toolbar' ) ;
var Title ;
var cpNfInner ;
var metadataMgr ;
config = {
readOnly : readOnly ,
patchTransformer : ChainPad . NaiveJSONTransformer ,
// cryptpad debug logging (default is 1)
// logLevel: 0,
validateContent : function ( content ) {
try {
JSON . parse ( content ) ;
return true ;
} catch ( e ) {
console . log ( "Failed to parse, rejecting patch" ) ;
return false ;
}
}
} ;
var palette = AppConfig . whiteboardPalette || [
'red' , 'blue' , 'green' , 'white' , 'black' , 'purple' ,
'gray' , 'beige' , 'brown' , 'cyan' , 'darkcyan' , 'gold' , 'yellow' , 'pink'
] ;
$ ( '.cp-app-whiteboard-palette-color' ) . on ( 'click' , function ( ) {
var color = $ ( this ) . css ( 'background-color' ) ;
setColor ( color ) ;
} ) ;
var addColorToPalette = function ( color , i ) {
if ( readOnly) { return ; }
if ( framework . isReadOnly ( ) ) { return ; }
var $color = $ ( '<span>' , {
'class' : 'cp-app-whiteboard-palette-color' ,
} )
@ -271,7 +191,7 @@ define([
} )
. on ( 'dblclick' , function ( e ) {
e . preventDefault ( ) ;
if ( ! APP . editable ) { return ; }
if ( framework . isLocked ( ) ) { return ; }
pickColor ( Colors . rgb2hex ( $color . css ( 'background-color' ) ) , function ( c ) {
$color . css ( {
'background-color' : c ,
@ -287,7 +207,7 @@ define([
var first = true ;
var updatePalette = function ( newPalette ) {
if ( first || stringify( palette ) !== string ify( newPalette ) ) {
if ( first || Sortify( palette ) !== Sort ify( newPalette ) ) {
palette = newPalette ;
$colors . html ( '<div class="hidden"> </div>' ) ;
palette . forEach ( addColorToPalette ) ;
@ -299,7 +219,7 @@ define([
var metadata = JSON . parse ( JSON . stringify ( metadataMgr . getMetadata ( ) ) ) ;
metadata . palette = newPalette ;
metadataMgr . updateMetadata ( metadata ) ;
config. onLocal ( ) ;
framework. localChange ( ) ;
} ;
var makeColorButton = function ( $container ) {
@ -312,7 +232,7 @@ define([
return ;
}
var $color = APP . $color = c ommon. createButton ( null , true , {
var $color = APP . $color = framework. _ . sfC ommon. createButton ( null , true , {
icon : 'fa-square' ,
title : Messages . canvas _chooseColor ,
name : 'color' ,
@ -331,33 +251,73 @@ define([
return $color ;
} ;
var stringifyInner = function ( textValue ) {
var obj = {
content : textValue ,
metadata : metadataMgr . getMetadataLazy ( )
} ;
// stringify the json and send it into chainpad
return stringify ( obj ) ;
updateLocalPalette ( palette ) ;
metadataMgr . onChange ( function ( ) {
var md = metadataMgr . getMetadata ( ) ;
if ( md . palette ) {
updateLocalPalette ( md . palette ) ;
}
} ) ;
return {
palette : palette ,
makeColorButton : makeColorButton ,
updateLocalPalette : updateLocalPalette ,
} ;
} ;
var mkHelpMenu = function ( framework ) {
var $appContainer = $ ( '#cp-app-whiteboard-container' ) ;
var helpMenu = framework . _ . sfCommon . createHelpMenu ( [ 'whiteboard' ] ) ;
$appContainer . prepend ( helpMenu . menu ) ;
framework . _ . toolbar . $drawer . append ( helpMenu . button ) ;
} ;
// Start of the main loop
var andThen2 = function ( framework ) {
var canvas = APP . canvas = new Fabric . Canvas ( 'cp-app-whiteboard-canvas' , {
containerClass : 'cp-app-whiteboard-canvas-container'
} ) ;
var $canvas = $ ( 'canvas' ) ;
var $canvasContainer = $ ( 'canvas' ) . parents ( '.cp-app-whiteboard-canvas-container' ) ;
var $controls = $ ( '#cp-app-whiteboard-controls' ) ;
var metadataMgr = framework . _ . cpNfInner . metadataMgr ;
var onLocal = config . onLocal = function ( ) {
if ( initializing ) { return ; }
if ( readOnly ) { return ; }
var content = stringifyInner ( canvas . toDatalessJSON ( ) ) ;
try {
APP . realtime . contentUpdate ( content ) ;
} catch ( e ) {
APP . unrecoverable = true ;
setEditable ( false ) ;
APP . toolbar . errorState ( true , e . message ) ;
var msg = Messages . chainpadError ;
UI . errorLoadingScreen ( msg , true , true ) ;
console . error ( e ) ;
var setEditable = function ( bool ) {
if ( bool ) { $controls . css ( 'display' , 'flex' ) ; }
else { $controls . hide ( ) ; }
canvas . isDrawingMode = bool ? APP . draw : false ;
if ( ! bool ) {
canvas . deactivateAll ( ) ;
canvas . renderAll ( ) ;
}
canvas . forEachObject ( function ( object ) {
object . selectable = bool ;
} ) ;
$canvasContainer . find ( 'canvas' ) . css ( 'border-color' , bool ? 'black' : 'red' ) ;
} ;
mkHelpMenu ( framework ) ;
var controls = mkControls ( framework , canvas ) ;
// ---------------------------------------------
// Whiteboard custom buttons
// ---------------------------------------------
var $rightside = framework . _ . toolbar . $rightside ;
APP . FM = framework . _ . sfCommon . createFileManager ( { } ) ;
APP . upload = function ( title ) {
var canvas = $canvas [ 0 ] ;
APP . canvas . deactivateAll ( ) . renderAll ( ) ;
canvas . toBlob ( function ( blob ) {
blob . name = title ;
APP . FM . handleFile ( blob ) ;
} ) ;
} ;
var addImageToCanvas = function ( img ) {
var w = img . width ;
var h = img . height ;
@ -370,313 +330,159 @@ define([
}
var cImg = new Fabric . Image ( img , { left : 0 , top : 0 , angle : 0 , } ) ;
APP . canvas . add ( cImg ) ;
onLocal ( ) ;
framework. localChange ( ) ;
} ;
var initThumbnails = function ( ) {
var oldThumbnailState ;
var privateDat = metadataMgr . getPrivateData ( ) ;
if ( ! privateDat . thumbnails ) { return ; }
var hash = privateDat . availableHashes . editHash ||
privateDat . availableHashes . viewHash ;
var href = privateDat . pathname + '#' + hash ;
var mkThumbnail = function ( ) {
if ( ! hash ) { return ; }
if ( initializing ) { return ; }
if ( ! APP . realtime ) { return ; }
var content = APP . realtime . getUserDoc ( ) ;
if ( content === oldThumbnailState ) { return ; }
var D = Thumb . getResizedDimensions ( $canvas [ 0 ] , 'pad' ) ;
Thumb . fromCanvas ( $canvas [ 0 ] , D , function ( err , b64 ) {
oldThumbnailState = content ;
Thumb . setPadThumbnail ( common , href , privateDat . channel , b64 ) ;
} ) ;
// Export to drive as PNG
framework . _ . sfCommon . createButton ( 'savetodrive' , true , { } ) . click ( function ( ) {
var defaultName = framework . _ . title . getTitle ( ) ;
UI . prompt ( Messages . exportPrompt , defaultName + '.png' , function ( name ) {
if ( name === null || ! name . trim ( ) ) { return ; }
APP . upload ( name ) ;
} ) ;
} ) . appendTo ( $rightside ) ;
// Embed image
var onUpload = function ( e ) {
var file = e . target . files [ 0 ] ;
var reader = new FileReader ( ) ;
reader . onload = function ( ) {
var img = new Image ( ) ;
img . onload = function ( ) {
addImageToCanvas ( img ) ;
} ;
img . src = reader . result ;
} ;
window . setInterval ( mkThumbnail , Thumb . UPDATE _INTERVAL ) ;
window . setTimeout ( mkThumbnail , Thumb . UPDATE _FIRST ) ;
reader . readAsDataURL ( file ) ;
} ;
config . onInit = function ( info ) {
updateLocalPalette ( palette ) ;
readOnly = metadataMgr . getPrivateData ( ) . readOnly ;
Title = common . createTitle ( { } ) ;
var configTb = {
displayed : [
'userlist' ,
'title' ,
'useradmin' ,
'spinner' ,
'newpad' ,
'share' ,
'limit' ,
'unpinnedWarning'
] ,
title : Title . getTitleConfig ( ) ,
metadataMgr : metadataMgr ,
readOnly : readOnly ,
realtime : info . realtime ,
sfCommon : common ,
$container : $bar ,
$contentContainer : $ ( '#cp-app-whiteboard-canvas-area' )
framework . _ . sfCommon . createButton ( '' , true , {
title : Messages . canvas _imageEmbed ,
icon : 'fa-file-image-o' ,
name : 'embedImage'
} ) . click ( function ( ) {
$ ( '<input>' , { type : 'file' } ) . on ( 'change' , onUpload ) . click ( ) ;
} ) . appendTo ( $rightside ) ;
if ( framework . _ . sfCommon . isLoggedIn ( ) ) {
var fileDialogCfg = {
onSelect : function ( data ) {
if ( data . type === 'file' ) {
var mt = '<media-tag src="' + data . src + '" data-crypto-key="cryptpad:' + data . key + '"></media-tag>' ;
framework . _ . sfCommon . displayMediatagImage ( $ ( mt ) , function ( err , $image ) {
Util . blobURLToImage ( $image . attr ( 'src' ) , function ( imgSrc ) {
var img = new Image ( ) ;
img . onload = function ( ) { addImageToCanvas ( img ) ; } ;
img . src = imgSrc ;
} ) ;
} ) ;
return ;
}
}
} ;
toolbar = APP . toolbar = Toolbar . create ( configTb ) ;
Title . setToolbar ( toolbar ) ;
var $rightside = toolbar . $rightside ;
var $drawer = toolbar . $drawer ;
/* save as template */
if ( ! metadataMgr . getPrivateData ( ) . isTemplate ) {
var templateObj = {
rt : info . realtime ,
getTitle : function ( ) { return metadataMgr . getMetadata ( ) . title ; }
framework . _ . sfCommon . initFilePicker ( fileDialogCfg ) ;
framework . _ . sfCommon . createButton ( 'mediatag' , true ) . click ( function ( ) {
var pickerCfg = {
types : [ 'file' ] ,
where : [ 'root' ] ,
filter : {
fileType : [ 'image/' ]
}
} ;
var $templateButton = common . createButton ( 'template' , true , templateObj ) ;
$rightside . append ( $templateButton ) ;
}
/* add an export button */
var $export = common . createButton ( 'export' , true , { } , saveImage ) ;
$drawer . append ( $export ) ;
if ( common . isLoggedIn ( ) ) {
common . createButton ( 'savetodrive' , true , { } , function ( ) { } )
. click ( function ( ) {
UI . prompt ( Messages . exportPrompt , document . title + '.png' ,
function ( name ) {
if ( name === null || ! name . trim ( ) ) { return ; }
APP . upload ( name ) ;
} ) ;
} ) . appendTo ( $rightside ) ;
common . createButton ( 'hashtag' , true ) . appendTo ( $rightside ) ;
}
var $forget = common . createButton ( 'forget' , true , { } , function ( err ) {
if ( err ) { return ; }
setEditable ( false ) ;
} ) ;
$rightside . append ( $forget ) ;
var $properties = common . createButton ( 'properties' , true ) ;
toolbar . $drawer . append ( $properties ) ;
var $appContainer = $ ( '#cp-app-whiteboard-container' ) ;
var helpMenu = common . createHelpMenu ( [ 'whiteboard' ] ) ;
$appContainer . prepend ( helpMenu . menu ) ;
toolbar . $drawer . append ( helpMenu . button ) ;
if ( ! readOnly ) {
makeColorButton ( $rightside ) ;
// Embed image
var onUpload = function ( e ) {
var file = e . target . files [ 0 ] ;
var reader = new FileReader ( ) ;
reader . onload = function ( ) {
var img = new Image ( ) ;
img . onload = function ( ) {
addImageToCanvas ( img ) ;
} ;
img . src = reader . result ;
} ;
reader . readAsDataURL ( file ) ;
} ;
common . createButton ( '' , true , {
title : Messages . canvas _imageEmbed ,
icon : 'fa-file-image-o' ,
name : 'embedImage'
} ) . click ( function ( ) {
$ ( '<input>' , { type : 'file' } ) . on ( 'change' , onUpload ) . click ( ) ;
} ) . appendTo ( $rightside ) ;
if ( common . isLoggedIn ( ) ) {
var fileDialogCfg = {
onSelect : function ( data ) {
if ( data . type === 'file' ) {
var mt = '<media-tag src="' + data . src + '" data-crypto-key="cryptpad:' + data . key + '"></media-tag>' ;
common . displayMediatagImage ( $ ( mt ) , function ( err , $image ) {
Util . blobURLToImage ( $image . attr ( 'src' ) , function ( imgSrc ) {
var img = new Image ( ) ;
img . onload = function ( ) { addImageToCanvas ( img ) ; } ;
img . src = imgSrc ;
} ) ;
} ) ;
return ;
}
}
} ;
common . initFilePicker ( fileDialogCfg ) ;
APP . $mediaTagButton = common . createButton ( 'mediatag' , true ) . click ( function ( ) {
var pickerCfg = {
types : [ 'file' ] ,
where : [ 'root' ] ,
filter : {
fileType : [ 'image/' ]
}
} ;
common . openFilePicker ( pickerCfg ) ;
} ) . appendTo ( $rightside ) ;
}
} else {
$colors . hide ( ) ;
$controls . hide ( ) ;
}
metadataMgr . onChange ( function ( ) {
var md = metadataMgr . getMetadata ( ) ;
if ( md . palette ) {
updateLocalPalette ( md . palette ) ;
}
} ) ;
} ;
config . onReady = function ( info ) {
if ( APP . realtime !== info . realtime ) {
APP . realtime = info . realtime ;
}
var userDoc = APP . realtime . getUserDoc ( ) ;
var isNew = false ;
var newDoc = '' ;
if ( userDoc === "" || userDoc === "{}" ) { isNew = true ; }
framework . _ . sfCommon . openFilePicker ( pickerCfg ) ;
} ) . appendTo ( $rightside ) ;
}
if ( userDoc !== "" ) {
var hjson = JSON . parse ( userDoc ) ;
if ( hjson && hjson . metadata ) {
metadataMgr . updateMetadata ( hjson . metadata ) ;
}
if ( typeof ( hjson ) !== 'object' || Array . isArray ( hjson ) ||
( hjson . metadata && typeof ( hjson . metadata . type ) !== 'undefined' &&
hjson . metadata . type !== 'whiteboard' ) ) {
var errorText = Messages . typeError ;
UI . errorLoadingScreen ( errorText ) ;
throw new Error ( errorText ) ;
}
newDoc = hjson . content ;
} else {
Title . updateTitle ( Title . defaultTitle ) ;
}
if ( framework . isReadOnly ( ) ) {
setEditable ( false ) ;
} else {
controls . makeColorButton ( $rightside ) ;
}
nThen ( function ( waitFor ) {
if ( newDoc ) {
canvas . loadFromJSON ( newDoc , waitFor ( function ( ) {
console . log ( 'loaded' ) ;
canvas . renderAll ( ) ;
} ) ) ;
}
} ) . nThen ( function ( ) {
setEditable ( ! readOnly ) ;
initializing = false ;
config . onLocal ( ) ;
UI . removeLoadingScreen ( ) ;
$ ( '#cp-app-whiteboard-clear' ) . on ( 'click' , function ( ) {
canvas . clear ( ) ;
framework . localChange ( ) ;
} ) ;
initThumbnails ( ) ;
// ---------------------------------------------
// End custom
// ---------------------------------------------
if ( readOnly ) { return ; }
framework . onEditableChange ( function ( ) {
var locked = framework . isLocked ( ) || framework . isReadOnly ( ) ;
setEditable ( ! locked ) ;
} ) ;
var privateDat = metadataMgr . getPrivateData ( ) ;
var skipTemp = Util . find ( privateDat ,
[ 'settings' , 'general' , 'creation' , 'noTemplate' ] ) ;
var skipCreation = Util . find ( privateDat , [ 'settings' , 'general' , 'creation' , 'skip' ] ) ;
if ( isNew && ( ! AppConfig . displayCreationScreen || ( ! skipTemp && skipCreation ) ) ) {
common . openTemplatePicker ( ) ;
}
framework . setFileExporter ( 'png' , function ( cb ) {
$canvas [ 0 ] . toBlob ( function ( blob ) {
cb ( blob ) ;
} ) ;
} ) ;
} ;
config . onRemote = function ( ) {
if ( initializing ) { return ; }
var userDoc = APP . realtime . getUserDoc ( ) ;
var json = JSON . parse ( userDoc ) ;
var remoteDoc = json . content ;
framework . setNormalizer ( function ( c ) {
return {
content : c . content
} ;
} ) ;
canvas . loadFromJSON ( remoteDoc , function ( ) {
framework . onContentUpdate ( function ( newContent , waitFor ) {
var content = newContent . content ;
canvas . loadFromJSON ( content , waitFor ( function ( ) {
canvas . renderAll ( ) ;
if ( json . metadata ) {
metadataMgr . updateMetadata ( json . metadata ) ;
}
} ) ;
var content = canvas . toDatalessJSON ( ) ;
if ( content !== remoteDoc ) { common . notify ( ) ; }
if ( readOnly ) { setEditable ( false ) ; }
} ;
config . onAbort = function ( ) {
if ( APP . unrecoverable ) { return ; }
// inform of network disconnect
setEditable ( false ) ;
toolbar . failed ( ) ;
UI . alert ( Messages . common _connectionLost , undefined , true ) ;
} ;
config . onConnectionChange = function ( info ) {
if ( APP . unrecoverable ) { return ; }
setEditable ( info . state ) ;
if ( info . state ) {
initializing = true ;
//UI.findOKButton().click();
} else {
//UI.alert(Messages.common_connectionLost, undefined, true);
}
} ;
config . onError = function ( err ) {
common . onServerError ( err , toolbar , function ( ) {
APP . unrecoverable = true ;
setEditable ( false ) ;
} ) ;
} ;
cpNfInner = common . startRealtime ( config ) ;
metadataMgr = cpNfInner . metadataMgr ;
cpNfInner . onInfiniteSpinner ( function ( ) {
if ( APP . unrecoverable ) { return ; }
setEditable ( false ) ;
UI . confirm ( Messages . realtime _unrecoverableError , function ( yes ) {
if ( ! yes ) { return ; }
common . gotoURL ( ) ;
} ) ;
} ) ) ;
} ) ;
canvas. on ( 'mouse:up' , onLocal ) ;
$ ( '#cp-app-whiteboard-clear' ) . on ( 'click' , function ( ) {
canvas . clear ( ) ;
onLocal ( ) ;
framework . setContentGetter ( function ( ) {
var content = canvas . toDatalessJSON ( ) ;
return {
content : content
} ;
} ) ;
$ ( '#save' ) . on ( 'click' , function ( ) {
saveImage ( ) ;
framework . onReady ( function ( ) {
var oldThumbnailState ;
var privateDat = metadataMgr . getPrivateData ( ) ;
if ( ! privateDat . thumbnails ) { return ; }
var hash = privateDat . availableHashes . editHash ||
privateDat . availableHashes . viewHash ;
var href = privateDat . pathname + '#' + hash ;
var mkThumbnail = function ( ) {
if ( ! hash ) { return ; }
if ( framework . getState ( ) !== 'READY' ) { return ; }
if ( ! framework . _ . cpNfInner . chainpad ) { return ; }
var content = framework . _ . cpNfInner . chainpad . getUserDoc ( ) ;
if ( content === oldThumbnailState ) { return ; }
var D = Thumb . getResizedDimensions ( $canvas [ 0 ] , 'pad' ) ;
Thumb . fromCanvas ( $canvas [ 0 ] , D , function ( err , b64 ) {
oldThumbnailState = content ;
Thumb . setPadThumbnail ( framework . _ . sfCommon , href , privateDat . channel , b64 ) ;
} ) ;
} ;
window . setInterval ( mkThumbnail , Thumb . UPDATE _INTERVAL ) ;
window . setTimeout ( mkThumbnail , Thumb . UPDATE _FIRST ) ;
} ) ;
common . onLogout ( function ( ) { setEditable ( false ) ; } ) ;
canvas . on ( 'mouse:up' , framework . localChange ) ;
framework . start ( ) ;
} ;
var main = function ( ) {
var common ;
// var framework;
nThen ( function ( waitFor ) {
$ ( waitFor ( function ( ) {
UI . addLoadingScreen ( ) ;
var $div = $ ( '<div>' ) . append ( Pages [ '/whiteboard/' ] ( ) ) ;
$ ( 'body' ) . append ( $div . html ( ) ) ;
} ) ) ;
SFCommon . create ( waitFor ( function ( c ) { APP . common = common = c ; } ) ) ;
} ) . nThen ( function ( waitFor ) {
common . getSframeChannel ( ) . onReady ( waitFor ( ) ) ;
} ) . nThen ( function ( waitFor ) {
common . handleNewFile ( waitFor ) ;
} ) . nThen ( function ( /*waitFor*/ ) {
andThen ( common ) ;
// Framework initialization
Framework . create ( {
patchTransformer : ChainPad . NaiveJSONTransformer ,
toolbarContainer : '#cp-toolbar' ,
contentContainer : '#cp-app-whiteboard-canvas-area' ,
} , waitFor ( function ( framework ) {
andThen2 ( framework ) ;
} ) ) ;
} ) ;
} ;
main ( ) ;