/* * Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.html or http://cksource.com/ckfinder/license * * The software, this file and its contents are subject to the CKFinder * License. Please read the license.txt file before using, installing, copying, * modifying or distribute this file or part of its contents. The contents of * this file is part of the Source Code of CKFinder. */ CKFinder.addPlugin( 'fileeditor', function( api ) { var regexExt = /^(.*)\.([^\.]+)$/, regexTextExt = /^(txt|css|html|htm|js|asp|cfm|cfc|ascx|php|inc|xml|xslt|xsl|cs)$/i, regexCodeMirrorExt = /^(css|html|htm|js|xml|xsl|php|cs)$/i, codemirror, file, fileLoaded = false, doc; var codemirrorPath = CKFinder.getPluginPath( 'fileeditor' ) + 'codemirror/'; var codeMirrorParsers = { css : codemirrorPath + 'mode/css/css.js', js : codemirrorPath + 'mode/javascript/javascript.js', html : [ codemirrorPath + 'mode/xml/xml.js', codemirrorPath + 'mode/javascript/javascript.js', codemirrorPath + 'mode/css/css.js', codemirrorPath + 'mode/htmlmixed/htmlmixed.js' ], xml : codemirrorPath + 'mode/xml/xml.js', php : [ codemirrorPath + 'mode/xml/xml.js', codemirrorPath + 'mode/javascript/javascript.js', codemirrorPath + 'mode/css/css.js', codemirrorPath + 'mode/clike/clike.js', codemirrorPath + 'mode/php/php.js' ], c : codemirrorPath + 'mode/clike/clike.js' }; codeMirrorParsers.htm = codeMirrorParsers.html; codeMirrorParsers.xsl = codeMirrorParsers.xml; codeMirrorParsers.cs = codeMirrorParsers.c; codeMirrorParsers.cpp = codeMirrorParsers.c; var codeMirrorModes = { js : 'javascript', htm : 'htmlmixed', html : 'htmlmixed', xsl : 'xml', c : 'clike', cs : 'clike', cpp : 'clike' }; CKFinder.dialog.add( 'fileEditor', function( api ) { var height, width; var saveButton = (function() { return { id : 'save', label : api.lang.Fileeditor.save, type : 'button', onClick : function ( evt ) { if ( !fileLoaded ) return true; var dialog = evt.data.dialog; var content = codemirror ? codemirror.getValue() : doc.getById( 'fileContent' ).getValue(); api.connector.sendCommandPost( 'SaveFile', null, { content : content, fileName : file.name }, function( xml ) { if ( xml.checkError() ) return false; api.openMsgDialog( '', api.lang.Fileeditor.fileSaveSuccess ); dialog.hide(); return undefined; }, file.folder.type, file.folder ); return false; } }; })(); if ( api.inPopup ) { width = api.document.documentElement.offsetWidth; height = api.document.documentElement.offsetHeight; } else { var parentWindow = ( api.document.parentWindow || api.document.defaultView ).parent; width = parentWindow.innerWidth ? parentWindow.innerWidth : parentWindow.document.documentElement.clientWidth; height = parentWindow.innerHeight ? parentWindow.innerHeight : parentWindow.document.documentElement.clientHeight; } var cssWidth = parseInt( width, 10 ) * 0.6 - 10, cssHeight = parseInt( height, 10 ) * 0.7 - 20; return { title : api.getSelectedFile().name, minWidth : parseInt( width, 10 ) * 0.6, minHeight : parseInt( height, 10 ) * 0.7, onHide : function() { if ( fileLoaded ) { var fileContent = doc.getById( 'fileContent' ); if ( fileContent ) fileContent.remove(); } }, onShow : function() { var dialog = this; doc = dialog.getElement().getDocument(); var win = doc.getWindow(); doc.getById( 'fileArea' ).setHtml( '

' + api.lang.Fileeditor.loadingFile + '

' ); file = api.getSelectedFile(); var enableCodeMirror = regexCodeMirrorExt.test( file.ext ); this.setTitle( file.name ); if ( enableCodeMirror && win.$.CodeMirror === undefined ) doc.appendStyleSheet( codemirrorPath + 'lib/codemirror.css' ); // If CKFinder is runninng under a different domain than baseUrl, then the following call will fail: // CKFinder.ajax.load( file.getUrl() + '?t=' + (new Date().getTime()), function( data )... var url = api.connector.composeUrl( 'DownloadFile', { FileName : file.name, format : 'text', t : new Date().getTime() }, file.folder.type, file.folder ); CKFinder.ajax.load( url, function( data ) { if ( data === null || ( file.size > 0 && data === '' ) ) { api.openMsgDialog( '', api.lang.Fileeditor.fileOpenError ); dialog.hide(); return; } else fileLoaded = true; var fileArea = doc.getById( 'fileArea' ); fileArea.setStyle( 'height', '100%' ); fileArea.setHtml( '' ); if ( CKFinder.env.opera ) doc.getById( 'fileContent' ).setHtml( CKFinder.tools.htmlEncode( data ) ); else doc.getById( 'fileContent' ).setText( data ); codemirror = null; if ( enableCodeMirror ) { CKFinder.scriptLoader.load( codemirrorPath + 'lib/codemirror.js', function() { CKFinder.scriptLoader.load( codeMirrorParsers[ file.ext ], function() { codemirror = win.$.CodeMirror.fromTextArea( doc.getById( 'fileContent' ).$, { mode : codeMirrorModes[ file.ext ] || file.ext } ); // TODO get rid of ugly buttons and provide something better var undoB = doc.createElement( 'button', { attributes: { 'label' : api.lang.common.undo } } ); undoB.on( 'click', function() { codemirror.undo(); }); undoB.setHtml( api.lang.common.undo ); undoB.appendTo( doc.getById( 'fileArea' ) ); var redoB = doc.createElement( 'button', { attributes: { 'label' : api.lang.common.redo } } ); redoB.on( 'click', function() { codemirror.redo(); }); redoB.setHtml( api.lang.common.redo ); redoB.appendTo( doc.getById( 'fileArea' ) ); }, this, false, doc.getHead() ); }, this, false, doc.getHead() ); } }); }, contents : [ { id : 'tab1', label : '', title : '', expand : true, padding : 0, elements : [ { type : 'html', id : 'htmlLoader', html : '' + '' + '
' } ] } ], // TODO http://dev.fckeditor.net/ticket/4750 buttons : [ saveButton, CKFinder.dialog.cancelButton ] }; } ); api.addFileContextMenuOption( { label : api.lang.Fileeditor.contextMenuName, command : 'fileEditor' } , function( api, file ) { api.openDialog( 'fileEditor' ); }, function ( file ) { var maxSize = 1024; if ( typeof ( CKFinder.config.fileeditorMaxSize ) != 'undefined' ) maxSize = CKFinder.config.fileeditorMaxSize; // Disable for images, binary files, large files etc. if ( regexTextExt.test( file.ext ) && file.size <= maxSize ) return file.folder.acl.fileDelete ? true : -1; return false; }); } );