Added ability to include ace extensions, like syntax highlighting and other features

This commit is contained in:
Marco Dickert 2018-03-20 17:26:50 +01:00
parent 2a37becfa6
commit bca92a839d
9 changed files with 304 additions and 118 deletions

1
.gitattributes vendored
View File

@ -1,3 +1,4 @@
ifm.php -diff
ifm.min.php -diff
build/* -diff
src/includes/ace.js -diff

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
.*.swp
*.zip
misc
src/includes/ace/*

File diff suppressed because one or more lines are too long

View File

@ -8,17 +8,22 @@
chdir( realpath( dirname( __FILE__ ) ) );
// php source files
$IFM_SRC_PHP = array(
0 => "src/main.php",
1 => "src/ifmarchive.php",
2 => "src/htpasswd.php"
);
$IFM_BUILD_STANDALONE = "ifm.php";
$IFM_BUILD_STANDALONE_COMPRESSED = "build/ifm.min.php";
$IFM_BUILD_LIB_PHP = "build/libifm.php";
// output files
define( "IFM_STANDALONE", "ifm.php" );
define( "IFM_STANDALONE_GZ", "build/ifm.min.php" );
define( "IFM_LIB", "build/libifm.php" );
// get options
$options = getopt( null, array( "language::" ) );
// process languages
$vars['languages'] = isset( $options['language'] ) ? explode( ',', $options['language'] ) : array( "en" );
$vars['defaultlanguage'] = $vars['languages'][0];
$vars['languageincludes'] = "";
@ -52,6 +57,23 @@ preg_match_all( "/\@\@\@file:([^\@]+)\@\@\@/", $compiled, $includes, PREG_SET_OR
foreach( $includes as $file )
$compiled = str_replace( $file[0], file_get_contents( $file[1] ), $compiled );
/**
* Process ace includes
*/
$includes = NULL;
$vars['ace_includes'] = "";
preg_match_all( "/\@\@\@acedir:([^\@]+)\@\@\@/", $compiled, $includes, PREG_SET_ORDER );
foreach( $includes as $dir ) {
$dircontent = "";
foreach( glob( $dir[1]."/*" ) as $file ) {
if( is_file( $file ) && is_readable( $file ) ) {
$vars['ace_includes'] .= "|" . substr( basename( $file ), 0, strrpos( basename( $file ), "." ) );
$dircontent .= file_get_contents( $file )."\n\n";
}
}
$compiled = str_replace( $dir[0], $dircontent, $compiled );
}
/**
* Process variable includes
*/
@ -61,10 +83,11 @@ foreach( $includes as $var )
$compiled = str_replace( $var[0], $vars[$var[1]], $compiled );
/**
* Build standalone script
* Build versions
*/
file_put_contents( $IFM_BUILD_STANDALONE, $compiled );
file_put_contents( $IFM_BUILD_STANDALONE, '
// build standalone ifm
file_put_contents( IFM_STANDALONE, $compiled );
file_put_contents( IFM_STANDALONE, '
/**
* start IFM
*/
@ -72,12 +95,13 @@ $ifm = new IFM();
$ifm->run();
', FILE_APPEND );
/**
* Build compressed standalone script
* file_put_contents( $IFM_BUILD_STANDALONE_COMPRESSED, '<?php eval( gzdecode( file_get_contents( __FILE__, false, null, 85 ) ) ); exit(0); ?>' . gzencode( file_get_contents( "ifm.php", false, null, 5 ) ) );
/* // build compressed ifm
file_put_contents(
IFM_STANDALONE_GZ,
'<?php eval( gzdecode( file_get_contents( __FILE__, false, null, 85 ) ) ); exit(0); ?>'
. gzencode( file_get_contents( "ifm.php", false, null, 5 ) )
);
*/
/**
* Build library
*/
file_put_contents( $IFM_BUILD_LIB_PHP, $compiled );
// build lib
file_put_contents( IFM_LIB, $compiled );

141
ifm.php

File diff suppressed because one or more lines are too long

View File

@ -456,14 +456,21 @@ function IFM( params ) {
ihatethisfuckingpopoverworkaround.$tip.find( '.popover-content' ).empty();
var aceSession = self.editor.getSession();
var template = document.createElement( 'template');
template.innerHTML = Mustache.render( self.templates.file_editoroptions, {
wordwrap: ( aceSession.getOption( 'wrap' ) == 'off' ? false : true ),
softtabs: aceSession.getOption( 'useSoftTabs' ),
tabsize: aceSession.getOption( 'tabSize' ),
i18n: self.i18n
});
var content = template.content.childNodes;
var content = self.getNodesFromString(
Mustache.render(
self.templates.file_editoroptions,
{
wordwrap: ( aceSession.getOption( 'wrap' ) == 'off' ? false : true ),
softtabs: aceSession.getOption( 'useSoftTabs' ),
tabsize: aceSession.getOption( 'tabSize' ),
ace_includes: self.ace,
ace_mode_selected: function() {
return ( aceSession.$modeId == "ace/mode/"+this ) ? 'selected="selected"' : '';
},
i18n: self.i18n
}
)
);
content.forEach( function( el ) {
if( el.id == "editor-wordwrap" )
el.addEventListener( 'change', function( e ) {
@ -491,6 +498,11 @@ function IFM( params ) {
self.editor.getSession().setValue(content);
self.editor.focus();
self.editor.on("change", function() { self.fileChanged = true; });
if( self.inArray( "ext-modelist", self.ace.files ) ) {
var mode = ace.require( "ace/ext/modelist" ).getModeForPath( filename ).mode;
if( self.inArray( mode, self.ace.modes.map( x => "ace/mode/"+x ) ) )
self.editor.getSession().setMode( mode );
}
};
/**
@ -1238,12 +1250,18 @@ function IFM( params ) {
return false;
};
this.getNodesFromString = function( s ) {
this.getNodeFromString = function( s ) {
var template = document.createElement( 'template');
template.innerHTML = s;
return template.content.childNodes[0];
};
this.getNodesFromString = function( s ) {
var template = document.createElement( 'template');
template.innerHTML = s;
return template.content.childNodes;
};
/**
* Adds a task to the taskbar.
*
@ -1255,7 +1273,7 @@ function IFM( params ) {
return false;
}
if( ! document.querySelector( "footer" ) ) {
var newFooter = self.getNodesFromString( Mustache.render( self.templates.footer, { i18n: self.i18n } ) );
var newFooter = self.getNodeFromString( Mustache.render( self.templates.footer, { i18n: self.i18n } ) );
newFooter.addEventListener( 'click', function( e ) {
if( e.target.name == 'showAll' ) {
if( newFooter.style.maxHeight == '80%' ) {
@ -1273,7 +1291,7 @@ function IFM( params ) {
task.id = "wq-"+task.id;
task.type = task.type || "info";
var wq = document.getElementById( 'waitqueue' );
wq.prepend( self.getNodesFromString( Mustache.render( self.templates.task, task ) ) );
wq.prepend( self.getNodeFromString( Mustache.render( self.templates.task, task ) ) );
document.getElementsByName( 'taskCount' )[0].innerText = wq.children.length;
};
@ -1612,6 +1630,14 @@ function IFM( params ) {
dataType: "json",
success: function(d) {
self.config = d;
if( self.config.ace_includes ) {
self.ace = {};
self.ace.files = self.config.ace_includes.split( '|' ).filter( x => x != "" );
self.ace.modes = self.ace.files
.filter( function(f){ if( f.substr(0,5)=="mode-" ) return f; } )
.map( function(f){ return f.substr(5); } )
self.ace.modes.unshift( "text" );
}
self.log( "configuration loaded" );
self.initLoadTemplates();
},

File diff suppressed because one or more lines are too long

View File

@ -105,6 +105,12 @@ class IFM {
// load config from passed array
$this->config = array_merge( $this->config, $config );
// get list of ace includes
$this->config['ace_includes'] = <<<'f00bar'
@@@vars:ace_includes@@@
f00bar;
// templates
$templates = array();
$templates['app'] = <<<'f00bar'
@@@file:src/templates/app.html@@@
@ -201,17 +207,20 @@ f00bar;
}
public function getJS() {
print '
<script>';?> @@@file:src/includes/ace.js@@@ <?php print '</script>
<script>';?> @@@file:src/includes/jquery.min.js@@@ <?php print '</script>
<script>';?> @@@file:src/includes/bootstrap.min.js@@@ <?php print '</script>
<script>';?> @@@file:src/includes/bootstrap-notify.min.js@@@ <?php print '</script>
<script>';?> @@@file:src/includes/bootstrap-treeview.min.js@@@ <?php print '</script>
<script>';?> @@@file:src/includes/datatables.min.js@@@ <?php print '</script>
<script>';?> @@@file:src/includes/BootstrapMenu.min.js@@@ <?php print '</script>
<script>';?> @@@file:src/includes/mustache.min.js@@@ <?php print '</script>
<script>';?> @@@file:src/ifm.js@@@ <?php print '</script>
';
echo <<<'f00bar'
<script>
@@@file:src/includes/jquery.min.js@@@
@@@file:src/includes/bootstrap.min.js@@@
@@@file:src/includes/bootstrap-notify.min.js@@@
@@@file:src/includes/bootstrap-treeview.min.js@@@
@@@file:src/includes/datatables.min.js@@@
@@@file:src/includes/BootstrapMenu.min.js@@@
@@@file:src/includes/mustache.min.js@@@
@@@file:src/includes/ace.js@@@
@@@acedir:src/includes/ace@@@
@@@file:src/ifm.js@@@
</script>
f00bar;
}
public function getHTMLHeader() {

View File

@ -9,3 +9,10 @@
{{/softtabs}}
> {{i18n.soft_tabs}}</input>
<div class="input-group"><span class="input-group-addon">{{i18n.tab_size}}</span><input class="form-control" type="text" size="2" id="editor-tabsize" title="{{i18n.tab_size}}" value="{{tabsize}}"></div>
{{#ace_includes}}
<select class="form-control selectpicker" data-toggle="dropdown" data-live-search="true" data-size="15" name="folder_id">
{{#modes}}
<option value="mode-{{.}}" {{{ace_mode_selected}}}>{{.}}</option>
{{/modes}}
</select>
{{/ace_includes}}