diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c3cb2b6..517cd25 100755
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -22,22 +22,28 @@ Stick to the conventions defined in other components as closely as possible.
In order to maintain a consistant code structure to the code across the application please follow the wordpress standard, or run any changes through [JSBeautifier] (http://jsbeautifier.org/) with the settings below.
{
- "indent_size": "1",
+ "brace_style": "collapse",
+ "break_chained_methods": false,
+ "comma_first": false,
+ "e4x": false,
+ "end_with_newline": true,
"indent_char": "\t",
+ "indent_empty_lines": true,
+ "indent_inner_html": true,
+ "indent_scripts": "normal",
+ "indent_size": "1",
+ "jslint_happy": false,
+ "keep_array_indentation": true,
"max_preserve_newlines": "5",
"preserve_newlines": true,
- "keep_array_indentation": true,
- "break_chained_methods": false,
- "indent_scripts": "normal",
- "brace_style": "collapse",
+ "space_after_anon_function": false,
+ "space_after_named_function": false,
"space_before_conditional": false,
+ "space_in_empty_paren": false,
+ "space_in_paren": true,
"unescape_strings": false,
- "jslint_happy": false,
- "end_with_newline": true,
- "wrap_line_length": "0",
- "indent_inner_html": true,
- "comma_first": false,
- "e4x": false
+ "unindent_chained_methods": true,
+ "wrap_line_length": "0"
}
If you have questions, please ask. Submit an issue or [contact us directly](mailto:support@telaaedifex.com).
diff --git a/components/autosave/init.js b/components/autosave/init.js
index e3889f3..d25847b 100755
--- a/components/autosave/init.js
+++ b/components/autosave/init.js
@@ -38,6 +38,7 @@
editor: null,
invalid_states: [ "", " ", null, undefined ],
path: curpath,
+ save_interval: null,
saving: false,
settings: {
autosave: true,
@@ -128,6 +129,30 @@
});
},
+ auto_save: function() {
+
+ /**
+ * When saving after every change, we encounter an issue where every
+ * once in a while the last change or last few changes will not get
+ * saved. Due to this, I decided to instead only save after the user
+ * has finished typing their changes.
+ *
+ * On every change to the editor, we set a timeout of half a second
+ * to see if the user is still typing. If they are, we clear the
+ * timeout and set it again. If they have stopped typing then the
+ * timout is triggered after 500 miliseconds and the file is saved.
+ */
+
+ let _this = codiad.auto_save;
+
+ if( _this.save_interval !== null ) {
+
+ clearTimeout( _this.save_interval );
+ _this.save_interval = null;
+ }
+ _this.save_interval = setTimeout( _this.save, 500 );
+ },
+
/**
*
* This is where the core functionality goes, any call, references,
@@ -135,9 +160,15 @@
*
*/
- auto_save: function() {
+ save: function() {
let _this = codiad.auto_save;
+
+ if( _this.saving ) {
+
+ return;
+ }
+
_this.saving = true;
let tabs = document.getElementsByClassName( "tab-item" );
let path = codiad.active.getPath();
@@ -193,7 +224,8 @@
_this.content = content;
codiad.active.save;
- codiad.filemanager.saveFile( path, content, localStorage.removeItem( path ), false );
+ //codiad.filemanager.saveFile( path, content, localStorage.removeItem( path ), false );
+ codiad.filemanager.saveFile( path, content, localStorage.removeItem( path ) );
let session = codiad.active.sessions[path];
if( typeof session != 'undefined' ) {
@@ -210,13 +242,6 @@
}
}
_this.saving = false;
-
- setTimeout(function() {
-
- //Call the function again after one second so that if we missed the last change we resave the file.
- let _this = codiad.auto_save;
- _this.auto_save();
- }, 1000);
},
reload_interval: async function() {
diff --git a/components/filemanager/init.js b/components/filemanager/init.js
index 651208b..5355a7b 100755
--- a/components/filemanager/init.js
+++ b/components/filemanager/init.js
@@ -3,29 +3,28 @@
* as-is and without warranty under the MIT License. See
* [root]/license.txt for more. This information must remain intact.
*/
-
- (function(global, $){
+( function( global, $ ) {
- var codiad = global.codiad;
+ var codiad = global.codiad;
+
+ $( window ).load( function() {
- $(window)
- .load(function() {
- codiad.filemanager.init();
- });
+ codiad.filemanager.init();
+ });
-
- codiad.filemanager = {
+ codiad.filemanager = {
auto_reload: false,
- clipboard: '',
- controller: 'components/filemanager/controller.php',
- dialog: 'components/filemanager/dialog.php',
- dialogUpload: 'components/filemanager/dialog_upload.php',
+ clipboard: '',
+ controller: 'components/filemanager/controller.php',
+ dialog: 'components/filemanager/dialog.php',
+ dialogUpload: 'components/filemanager/dialog_upload.php',
preview: null,
+ refresh_interval: null,
- init: async function() {
-
- this.noAudio = [
+ init: async function() {
+
+ this.noAudio = [
//Audio
'aac',
'aif',
@@ -33,15 +32,15 @@
'mp4',
'wav',
'ogg',
- ],
- this.noFiles = [
+ ];
+ this.noFiles = [
//Files
'exe',
'pdf',
'zip',
'tar',
'tar.gz',
- ],
+ ];
this.noImages = [
//Images
'ico',
@@ -51,914 +50,977 @@
'png',
'gif',
'bmp',
- ],
+ ];
-
- this.noOpen = this.noAudio.concat( this.noFiles, this.noImages ),
- this.noBrowser = this.noAudio.concat( this.noImages ),
-
- // Initialize node listener
- this.nodeListener();
- this.auto_reload = ( await codiad.settings.get_option( "codiad.filemanager.autoReloadPreview" ) == "true" );
-
- console.log( this.auto_reload );
-
- amplify.subscribe( 'settings.save', async function() {
-
- let option = ( await codiad.settings.get_option( "codiad.filemanager.autoReloadPreview" ) == "true" );
- if( option != codiad.filemanager.auto_reload ) {
-
- //codiad.auto_save.reload_interval();
- window.location.reload( true );
- }
+
+ this.noOpen = this.noAudio.concat( this.noFiles, this.noImages ),
+ this.noBrowser = this.noAudio.concat( this.noImages ),
+
+ // Initialize node listener
+ this.nodeListener();
+ this.auto_reload = ( await codiad.settings.get_option( "codiad.filemanager.autoReloadPreview" ) == "true" );
+
+ console.log( this.auto_reload );
+
+ amplify.subscribe( 'settings.save', async function() {
+
+ let option = ( await codiad.settings.get_option( "codiad.filemanager.autoReloadPreview" ) == "true" );
+ if( option != codiad.filemanager.auto_reload ) {
+
+ //codiad.auto_save.reload_interval();
+ window.location.reload( true );
+ }
});
-
- /* Subscribe to know when a file become active. */
+
+ /* Subscribe to know when a file become active. */
amplify.subscribe( 'active.onFocus', async function( path ) {
let _this = codiad.filemanager;
let editor = codiad.editor.getActive();
-
+
if( _this.auto_reload && editor !== null ) {
-
- codiad.editor.getActive().addEventListener( "change", _this.refreshPreview );
- }
+
+ codiad.editor.getActive().addEventListener( "change", _this.refreshPreview );
+ }
});
-
- // Load uploader
- $.loadScript("components/filemanager/upload_scripts/jquery.ui.widget.js", true);
- $.loadScript("components/filemanager/upload_scripts/jquery.iframe-transport.js", true);
- $.loadScript("components/filemanager/upload_scripts/jquery.fileupload.js", true);
- },
-
- //////////////////////////////////////////////////////////////////
- // Listen for dbclick events on nodes
- //////////////////////////////////////////////////////////////////
-
- nodeListener: function() {
- var _this = this;
-
- $('#file-manager').on('selectstart', false);
-
- $('#file-manager span')
- .live('click', function() { // Open or Expand
- if ($(this).parent().children("a").attr('data-type') == 'directory') {
- _this.index($(this).parent().children("a")
- .attr('data-path'));
- } else {
- _this.openFile($(this).parent().children("a")
- .attr('data-path'));
- }
- if (!$(this).hasClass('none')) {
- if ($(this).hasClass('plus')) {
- $(this).removeClass('plus')
- $(this).addClass('minus');
- } else {
- $(this).removeClass('minus')
- $(this).addClass('plus');
- }
- }
- });
- $('#file-manager a')
- .live('dblclick', function() { // Open or Expand
- if (!codiad.editor.settings.fileManagerTrigger) {
- if ($(this)
- .hasClass('directory')) {
- _this.index($(this)
- .attr('data-path'));
- } else {
- _this.openFile($(this)
- .attr('data-path'));
- }
- if (!$(this).parent().children("span").hasClass('none')) {
- if ($(this).parent().children("span").hasClass('plus')) {
- $(this).parent().children("span").removeClass('plus')
- $(this).parent().children("span").addClass('minus');
- } else {
- $(this).parent().children("span").removeClass('minus')
- $(this).parent().children("span").addClass('plus');
- }
- }
- }
- })
- .live('click', function() { // Open or Expand
- if (codiad.editor.settings.fileManagerTrigger) {
- if ($(this)
- .hasClass('directory')) {
- _this.index($(this)
- .attr('data-path'));
- } else {
- _this.openFile($(this)
- .attr('data-path'));
- }
- if (!$(this).parent().children("span").hasClass('none')) {
- if ($(this).parent().children("span").hasClass('plus')) {
- $(this).parent().children("span").removeClass('plus')
- $(this).parent().children("span").addClass('minus');
- } else {
- $(this).parent().children("span").removeClass('minus')
- $(this).parent().children("span").addClass('plus');
- }
- }
- }
- })
- .live("contextmenu", function(e) { // Context Menu
- e.preventDefault();
- _this.contextMenuShow(e, $(this)
- .attr('data-path'), $(this)
- .attr('data-type'), $(this)
- .html());
- $(this)
- .addClass('context-menu-active');
- });
- },
-
- //////////////////////////////////////////////////////////////////
- // Context Menu
- //////////////////////////////////////////////////////////////////
-
- contextMenuShow: function(e, path, type, name) {
- var _this = this;
- $('#context-menu a, #context-menu hr').hide();
- // Selective options
- switch (type) {
- case 'directory':
- $('#context-menu .directory-only, #context-menu .non-root, #context-menu .both').show();
- break;
- case 'file':
- $('#context-menu .file-only, #context-menu .non-root, #context-menu .both').show();
- break;
- case 'root':
- $('#context-menu .directory-only, #context-menu .root-only').show();
- break;
- case 'editor':
- $('#context-menu .editor-only').show();
- break;
- }
- if(codiad.project.isAbsPath($('#file-manager a[data-type="root"]').attr('data-path'))) {
- $('#context-menu .no-external').hide();
- } else if( type == "editor" ) {
- $('#context-menu .no-external').hide();
- } else {
- $('#context-menu .no-external').show();
- }
- // Show menu
- var top = e.pageY;
- if (top > $(window).height() - $('#context-menu').height()) {
- top -= $('#context-menu').height();
- }
- if (top < 10) {
- top = 10;
- }
- var max = $(window).height() - top - 10;
-
- $('#context-menu')
- .css({
- 'top': top + 'px',
- 'left': e.pageX + 'px',
- 'max-height': max + 'px'
- })
- .fadeIn(200)
- .attr('data-path', path)
- .attr('data-type', type)
- .attr('data-name', name);
- // Show faded 'paste' if nothing in clipboard
- if (this.clipboard === '') {
- $('#context-menu a[content="Paste"]')
- .addClass('disabled');
- } else {
- $('#context-menu a[data-action="paste"]')
- .removeClass('disabled');
- }
- // Hide menu
- /**
- * make sure that the user has moved their mouse far enough
- * away from the context menu to warrant a close.
- */
- $('#file-manager, #editor-region').on( 'mousemove', codiad.filemanager.contextCheckMouse );
- $('#context-menu, #editor-region').on( 'paste', codiad.editor.paste );
-
- /* Notify listeners. */
- amplify.publish('context-menu.onShow', {e: e, path: path, type: type});
- // Hide on click
- $('#context-menu a')
- .click(function() {
- _this.contextMenuHide();
- });
- },
+ // Load uploader
+ $.loadScript( "components/filemanager/upload_scripts/jquery.ui.widget.js", true );
+ $.loadScript( "components/filemanager/upload_scripts/jquery.iframe-transport.js", true );
+ $.loadScript( "components/filemanager/upload_scripts/jquery.fileupload.js", true );
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Listen for dbclick events on nodes
+ //////////////////////////////////////////////////////////////////
+
+ nodeListener: function() {
+
+ let _this = this;
+
+ $( '#file-manager' ).on( 'selectstart', false );
+
+ $( '#file-manager span' )
+ .live( 'click', function() { // Open or Expand
+ if( $( this ).parent().children( "a" ).attr( 'data-type' ) == 'directory' ) {
+ _this.index( $( this ).parent().children( "a" )
+ .attr( 'data-path' ) );
+ } else {
+ _this.openFile( $( this ).parent().children( "a" )
+ .attr( 'data-path' ) );
+ }
+ if( !$( this ).hasClass( 'none' ) ) {
+ if( $( this ).hasClass( 'plus' ) ) {
+ $( this ).removeClass( 'plus' )
+ $( this ).addClass( 'minus' );
+ } else {
+ $( this ).removeClass( 'minus' )
+ $( this ).addClass( 'plus' );
+ }
+ }
+ });
+ $( '#file-manager a' )
+ .live( 'dblclick', function() { // Open or Expand
+ if( !codiad.editor.settings.fileManagerTrigger ) {
+ if( $( this )
+ .hasClass( 'directory' ) ) {
+ _this.index( $( this )
+ .attr( 'data-path' ) );
+ } else {
+ _this.openFile( $( this )
+ .attr( 'data-path' ) );
+ }
+ if( !$( this ).parent().children( "span" ).hasClass( 'none' ) ) {
+ if( $( this ).parent().children( "span" ).hasClass( 'plus' ) ) {
+ $( this ).parent().children( "span" ).removeClass( 'plus' )
+ $( this ).parent().children( "span" ).addClass( 'minus' );
+ } else {
+ $( this ).parent().children( "span" ).removeClass( 'minus' )
+ $( this ).parent().children( "span" ).addClass( 'plus' );
+ }
+ }
+ }
+ })
+ .live( 'click', function() { // Open or Expand
+ if( codiad.editor.settings.fileManagerTrigger ) {
+ if( $( this )
+ .hasClass( 'directory' ) ) {
+ _this.index( $( this )
+ .attr( 'data-path' ) );
+ } else {
+ _this.openFile( $( this )
+ .attr( 'data-path' ) );
+ }
+ if( !$( this ).parent().children( "span" ).hasClass( 'none' ) ) {
+ if( $( this ).parent().children( "span" ).hasClass( 'plus' ) ) {
+ $( this ).parent().children( "span" ).removeClass( 'plus' )
+ $( this ).parent().children( "span" ).addClass( 'minus' );
+ } else {
+ $( this ).parent().children( "span" ).removeClass( 'minus' )
+ $( this ).parent().children( "span" ).addClass( 'plus' );
+ }
+ }
+ }
+ })
+ .live( "contextmenu", function( e ) { // Context Menu
+ e.preventDefault();
+ _this.contextMenuShow( e, $( this )
+ .attr( 'data-path' ), $( this )
+ .attr( 'data-type' ), $( this )
+ .html() );
+ $( this )
+ .addClass( 'context-menu-active' );
+ });
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Context Menu
+ //////////////////////////////////////////////////////////////////
+
+ contextMenuShow: function( e, path, type, name ) {
+ let _this = this;
+
+ $( '#context-menu a, #context-menu hr' ).hide();
+ // Selective options
+ switch ( type ) {
+ case 'directory':
+ $( '#context-menu .directory-only, #context-menu .non-root, #context-menu .both' ).show();
+ break;
+ case 'file':
+ $( '#context-menu .file-only, #context-menu .non-root, #context-menu .both' ).show();
+ break;
+ case 'root':
+ $( '#context-menu .directory-only, #context-menu .root-only' ).show();
+ break;
+ case 'editor':
+ $( '#context-menu .editor-only' ).show();
+ break;
+ }
+ if( codiad.project.isAbsPath( $( '#file-manager a[data-type="root"]' ).attr( 'data-path' ) ) ) {
+ $( '#context-menu .no-external' ).hide();
+ } else if( type == "editor" ) {
+ $( '#context-menu .no-external' ).hide();
+ } else {
+ $( '#context-menu .no-external' ).show();
+ }
+ // Show menu
+ var top = e.pageY;
+ if( top > $( window ).height() - $( '#context-menu' ).height() ) {
+ top -= $( '#context-menu' ).height();
+ }
+ if( top < 10 ) {
+ top = 10;
+ }
+ var max = $( window ).height() - top - 10;
+
+ $( '#context-menu' )
+ .css( {
+ 'top': top + 'px',
+ 'left': e.pageX + 'px',
+ 'max-height': max + 'px'
+ })
+ .fadeIn( 200 )
+ .attr( 'data-path', path )
+ .attr( 'data-type', type )
+ .attr( 'data-name', name );
+ // Show faded 'paste' if nothing in clipboard
+ if( this.clipboard === '' ) {
+ $( '#context-menu a[content="Paste"]' )
+ .addClass( 'disabled' );
+ } else {
+ $( '#context-menu a[data-action="paste"]' )
+ .removeClass( 'disabled' );
+ }
+ // Hide menu
+ /**
+ * make sure that the user has moved their mouse far enough
+ * away from the context menu to warrant a close.
+ */
+ $( '#file-manager, #editor-region' ).on( 'mousemove', codiad.filemanager.contextCheckMouse );
+ $( '#context-menu, #editor-region' ).on( 'paste', codiad.editor.paste );
+
+ /* Notify listeners. */
+ amplify.publish( 'context-menu.onShow', {
+ e: e,
+ path: path,
+ type: type
+ });
+ // Hide on click
+ $( '#context-menu a' )
+ .click( function() {
+ _this.contextMenuHide();
+ });
+ },
contextCheckMouse: function( e ) {
-
- let offset = $('#context-menu').offset();
- let bottom = offset.top + $('#context-menu').outerHeight( true ) + 20;
- let left = offset.left - 20;
- let right = offset.left + $('#context-menu').outerWidth( true ) + 20;
- let top = offset.top - 20;
-
- if( ( e.clientX > right || e.clientX < left ) || ( e.clientY > bottom || e.clientY < top ) ) {
-
- $('#file-manager, #editor-region').off( 'mousemove', codiad.filemanager.contextCheckMouse );
- $('#context-menu, #editor-region').off( 'paste', codiad.editor.paste );
- codiad.filemanager.contextMenuHide();
- }
- },
+
+ let offset = $( '#context-menu' ).offset();
+ let bottom = offset.top + $( '#context-menu' ).outerHeight( true ) + 20;
+ let left = offset.left - 20;
+ let right = offset.left + $( '#context-menu' ).outerWidth( true ) + 20;
+ let top = offset.top - 20;
+
+ if( ( e.clientX > right || e.clientX < left ) || ( e.clientY > bottom || e.clientY < top ) ) {
+
+ $( '#file-manager, #editor-region' ).off( 'mousemove', codiad.filemanager.contextCheckMouse );
+ $( '#context-menu, #editor-region' ).off( 'paste', codiad.editor.paste );
+ codiad.filemanager.contextMenuHide();
+ }
+ },
- contextMenuHide: function() {
- $('#context-menu')
- .fadeOut(200);
- $('#file-manager a')
- .removeClass('context-menu-active');
- /* Notify listeners. */
- amplify.publish('context-menu.onHide');
- },
-
- //////////////////////////////////////////////////////////////////
- // Return the node name (sans path)
- //////////////////////////////////////////////////////////////////
-
- getShortName: function(path) {
- return path.split('/')
- .pop();
- },
-
- //////////////////////////////////////////////////////////////////
- // Return extension
- //////////////////////////////////////////////////////////////////
-
- getExtension: function(path) {
- return path.split('.')
- .pop();
- },
-
- //////////////////////////////////////////////////////////////////
- // Return type
- //////////////////////////////////////////////////////////////////
-
- getType: function(path) {
-
- if( path.match( /\\/g ) ) {
-
- path = path.replace( '\\', '\\\\' );
- }
-
- return $('#file-manager a[data-path="' + path + '"]').attr('data-type');
- },
-
- //////////////////////////////////////////////////////////////////
- // Create node in file tree
- //////////////////////////////////////////////////////////////////
-
- createObject: function(parent, path, type) {
- // NODE FORMAT:
{short_name}
- var parentNode = $('#file-manager a[data-path="' + parent + '"]');
- if (!$('#file-manager a[data-path="' + path + '"]')
- .length) { // Doesn't already exist
- if (parentNode.hasClass('open') && parentNode.hasClass('directory')) { // Only append node if parent is open (and a directory)
- var shortName = this.getShortName(path);
- if (type == 'directory') {
- var appendage = '' + shortName + '';
- } else {
- var appendage = '' + shortName + '';
- }
- if (parentNode.siblings('ul')
- .length) { // UL exists, other children to play with
- parentNode.siblings('ul')
- .append(appendage);
- } else {
- $('')
- .insertAfter(parentNode);
- }
- } else {
- parentNode.parent().children('span').removeClass('none');
- parentNode.parent().children('span').addClass('plus');
- }
- }
- },
-
- //////////////////////////////////////////////////////////////////
- // Loop out all files and folders in directory path
- //////////////////////////////////////////////////////////////////
-
- indexFiles: [],
-
- index: function(path, rescan) {
- var _this = this;
- if (rescan === undefined) {
- rescan = false;
- }
- node = $('#file-manager a[data-path="' + path + '"]');
- if (node.hasClass('open') && !rescan) {
- node.parent('li')
- .children('ul')
- .slideUp(300, function() {
- $(this)
- .remove();
- node.removeClass('open');
- });
- } else {
- node.addClass('loading');
- $.get(this.controller + '?action=index&path=' + encodeURIComponent(path), function(data) {
- node.addClass('open');
- var objectsResponse = codiad.jsend.parse(data);
- if (objectsResponse != 'error') {
- /* Notify listener */
- _this.indexFiles = objectsResponse.index;
- amplify.publish("filemanager.onIndex", {path: path, files: _this.indexFiles});
- var files = _this.indexFiles;
- if (files.length > 0) {
- if (node.parent().children('span').hasClass('plus')) {
- node.parent().children('span').removeClass('plus').addClass('minus');
- }
- var display = 'display:none;';
- if (rescan) {
- display = '';
- }
- var appendage = '';
- $.each(files, function(index) {
- var ext = '';
- var name = files[index].name.replace(path, '');
- var nodeClass = 'none';
- name = name.split('/')
- .join(' ');
- if (files[index].type == 'file') {
- var ext = ' ext-' + name.split('.')
- .pop();
- }
- if(files[index].type == 'directory' && files[index].size > 0) {
- nodeClass = 'plus';
- }
- appendage += '- ' + name + '
';
- });
- appendage += '
';
- if (rescan) {
- node.parent('li')
- .children('ul')
- .remove();
- }
- $(appendage)
- .insertAfter(node);
- if (!rescan) {
- node.siblings('ul')
- .slideDown(300);
- }
- }
- }
- node.removeClass('loading');
- if (rescan && _this.rescanChildren.length > _this.rescanCounter) {
- _this.rescan(_this.rescanChildren[_this.rescanCounter++]);
- } else {
- _this.rescanChildren = [];
- _this.rescanCounter = 0;
- }
- });
- }
- },
-
- rescanChildren: [],
-
- rescanCounter: 0,
-
- rescan: function(path) {
- var _this = this;
- if (this.rescanCounter === 0) {
- // Create array of open directories
- node = $('#file-manager a[data-path="' + path + '"]');
- node.parent().find('a.open').each(function() {
- _this.rescanChildren.push($(this).attr('data-path'));
- });
- }
-
- this.index(path, true);
- },
-
- //////////////////////////////////////////////////////////////////
- // Open File
- //////////////////////////////////////////////////////////////////
-
- openFile: function(path, focus) {
-
- /* Notify listeners. */
- amplify.publish('filemanager.onFileWillOpen', {path: path});
-
- if (focus === undefined) {
- focus = true;
- }
- var node = $('#file-manager a[data-path="' + path + '"]');
- var ext = this.getExtension(path);
- if ($.inArray(ext.toLowerCase(), this.noOpen) < 0) {
- node.addClass('loading');
- $.get(this.controller + '?action=open&path=' + encodeURIComponent(path), function(data) {
- var openResponse = codiad.jsend.parse(data);
- if (openResponse != 'error') {
- node.removeClass('loading');
- codiad.active.open(path, openResponse.content, openResponse.mtime, false, focus);
- }
- });
- } else {
- if(!codiad.project.isAbsPath(path)) {
- if ($.inArray(ext.toLowerCase(), this.noBrowser) < 0) {
- this.download(path);
- } else {
- this.openInModal(path);
- }
- } else {
- codiad.message.error(i18n('Unable to open file in Browser while using absolute path.'));
- }
- }
- },
-
- //////////////////////////////////////////////////////////////////
- // Open in browser
- //////////////////////////////////////////////////////////////////
-
- openInBrowser: function(path) {
-
- let _this = this;
-
- $.ajax({
- url: this.controller + '?action=open_in_browser&path=' + encodeURIComponent(path),
- success: function(data) {
- var openIBResponse = codiad.jsend.parse(data);
- if (openIBResponse != 'error') {
-
- _this.preview = window.open( openIBResponse.url, '_newtab' );
-
- let editor = codiad.editor.getActive();
-
- if( _this.auto_reload && editor !== null ) {
-
- codiad.editor.getActive().addEventListener( "change", _this.refreshPreview );
- }
-
-
- }
- },
- async: false
- });
- },
-
- refreshPreview: function( event ) {
-
- _this = codiad.filemanager;
-
- if( _this.preview == null ) {
-
- return;
- }
-
- try {
-
- if( ( typeof _this.preview.location.reload ) == "undefined" ) {
-
- _this.preview = null;
- codiad.editor.getActive().removeEventListener( "change", _this.refreshPreview );
- return;
- }
- _this.preview.location.reload( true );
- } catch( e ) {
-
- console.log( e );
- codiad.message.error( 'Please close your previously opened preview window.' );
- _this.preview = null;
- codiad.editor.getActive().removeEventListener( "change", _this.refreshPreview );
- }
- },
-
- openInModal: function(path) {
-
- let type = "";
- var ext = this.getExtension(path).toLowerCase();
-
- if ( this.noAudio.includes(ext) ) {
-
- type = 'music_preview';
- } else if ( this.noImages.includes(ext) ) {
-
- type = 'preview';
- }
-
- codiad.modal.load(250, this.dialog, {
- action: type,
- path: path
- });
- },
- saveModifications: function(path, data, callbacks, save=true){
- callbacks = callbacks || {};
- var _this = this, action, data;
- var notifySaveErr = function() {
- codiad.message.error(i18n('File could not be saved'));
- if (typeof callbacks.error === 'function') {
- var context = callbacks.context || _this;
- callbacks.error.apply(context, [data]);
- }
- }
- $.post(this.controller + '?action=modify&path=' + encodeURIComponent(path), data, function(resp){
- resp = $.parseJSON(resp);
- if (resp.status == 'success') {
- if ( save === true ) {
- codiad.message.success(i18n('File saved'));
- }
- if (typeof callbacks.success === 'function'){
- var context = callbacks.context || _this;
- callbacks.success.call(context, resp.data.mtime);
- }
- } else {
- if (resp.message == 'Client is out of sync'){
- var reload = confirm(
- "Server has a more updated copy of the file. Would "+
- "you like to refresh the contents ? Pressing no will "+
- "cause your changes to override the server's copy upon "+
- "next save."
- );
- if (reload) {
- codiad.active.close(path);
- codiad.active.removeDraft(path);
- _this.openFile(path);
- } else {
- var session = codiad.editor.getActive().getSession();
- session.serverMTime = null;
- session.untainted = null;
- }
- } else codiad.message.error(i18n('File could not be saved'));
- if (typeof callbacks.error === 'function') {
- var context = callbacks.context || _this;
- callbacks.error.apply(context, [resp.data]);
- }
- }
- }).error(notifySaveErr);
- },
- //////////////////////////////////////////////////////////////////
- // Save file
- //////////////////////////////////////////////////////////////////
+ contextMenuHide: function() {
+ $( '#context-menu' )
+ .fadeOut( 200 );
+ $( '#file-manager a' )
+ .removeClass( 'context-menu-active' );
+ /* Notify listeners. */
+ amplify.publish( 'context-menu.onHide' );
+ },
- saveFile: function(path, content, callbacks, save=true) {
- this.saveModifications(path, {content: content}, callbacks, save);
- },
+ //////////////////////////////////////////////////////////////////
+ // Return the node name (sans path)
+ //////////////////////////////////////////////////////////////////
- savePatch: function(path, patch, mtime, callbacks, alerts) {
- if (patch.length > 0)
- this.saveModifications(path, {patch: patch, mtime: mtime}, callbacks, alerts);
- else if (typeof callbacks.success === 'function'){
- var context = callbacks.context || this;
- callbacks.success.call(context, mtime);
- }
- },
+ getShortName: function( path ) {
+ return path.split( '/' )
+ .pop();
+ },
- //////////////////////////////////////////////////////////////////
- // Create Object
- //////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////
+ // Return extension
+ //////////////////////////////////////////////////////////////////
- createNode: function(path, type) {
- codiad.modal.load(250, this.dialog, {
- action: 'create',
- type: type,
- path: path
- });
- $('#modal-content form')
- .live('submit', function(e) {
- let project = codiad.project.getCurrent();
- e.preventDefault();
- var shortName = $('#modal-content form input[name="object_name"]')
- .val();
- var path = $('#modal-content form input[name="path"]')
- .val();
- var type = $('#modal-content form input[name="type"]')
- .val();
- var createPath = path + '/' + shortName;
- $.get(codiad.filemanager.controller + '?action=create&path=' + encodeURIComponent(createPath) + '&type=' + type, function(data) {
- var createResponse = codiad.jsend.parse(data);
- if (createResponse != 'error') {
- codiad.message.success(type.charAt(0)
- .toUpperCase() + type.slice(1) + ' Created');
- codiad.modal.unload();
- // Add new element to filemanager screen
- codiad.filemanager.createObject(path, createPath, type);
- if(type == 'file') {
- codiad.filemanager.openFile(createPath, true);
- }
-
- codiad.filemanager.rescan( project );
-
- /* Notify listeners. */
- amplify.publish('filemanager.onCreate', {createPath: createPath, path: path, shortName: shortName, type: type});
- }
- });
- });
- },
-
- //////////////////////////////////////////////////////////////////
- // Copy to Clipboard
- //////////////////////////////////////////////////////////////////
-
- copyNode: function(path) {
- this.clipboard = path;
- codiad.message.success(i18n('Copied to Clipboard'));
- },
-
- //////////////////////////////////////////////////////////////////
- // Paste
- //////////////////////////////////////////////////////////////////
-
- pasteNode: function(path) {
- var _this = this;
- if (this.clipboard == '') {
- codiad.message.error(i18n('Nothing in Your Clipboard'));
- } else if (path == this.clipboard) {
- codiad.message.error(i18n('Cannot Paste Directory Into Itself'));
- } else {
- let project = codiad.project.getCurrent();
- var shortName = _this.getShortName(_this.clipboard);
- if ($('#file-manager a[data-path="' + path + '/' + shortName + '"]')
- .length) { // Confirm overwrite?
- codiad.modal.load(400, this.dialog, {
- action: 'overwrite',
- path: path + '/' + shortName
- });
- $('#modal-content form')
- .live('submit', function(e) {
- e.preventDefault();
- var duplicate = false;
- if($('#modal-content form select[name="or_action"]').val()==1){
- duplicate=true; console.log('Dup!');
- }
- _this.processPasteNode(path,duplicate);
- });
- } else { // No conflicts; proceed...
- _this.processPasteNode(path,false);
- }
-
- codiad.filemanager.rescan( project );
- }
- },
+ getExtension: function( path ) {
+ return path.split( '.' )
+ .pop();
+ },
- processPasteNode: function(path,duplicate) {
- var _this = this;
- var shortName = this.getShortName(this.clipboard);
- var type = this.getType(this.clipboard);
-
- $.get(this.controller + '?action=duplicate&path=' +
- encodeURIComponent(this.clipboard) + '&destination=' +
- encodeURIComponent(path + '/' + shortName) + '&duplicate=' + encodeURIComponent( duplicate ), function(data) {
- var pasteResponse = codiad.jsend.parse(data);
- if (pasteResponse != 'error') {
- _this.createObject(path, path + '/' + shortName, type);
- codiad.modal.unload();
- /* Notify listeners. */
- amplify.publish('filemanager.onPaste', {path: path, shortName: shortName, duplicate: duplicate});
- }
- });
- },
+ //////////////////////////////////////////////////////////////////
+ // Return type
+ //////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////
- // Rename
- //////////////////////////////////////////////////////////////////
+ getType: function( path ) {
+
+ if( path.match( /\\/g ) ) {
+
+ path = path.replace( '\\', '\\\\' );
+ }
+
+ return $( '#file-manager a[data-path="' + path + '"]' ).attr( 'data-type' );
+ },
- renameNode: function(path) {
- var shortName = this.getShortName(path);
- var type = this.getType(path);
- var _this = this;
- codiad.modal.load(250, this.dialog, { action: 'rename', path: path, short_name: shortName, type: type});
- $('#modal-content form')
- .live('submit', function(e) {
- let project = codiad.project.getCurrent();
- e.preventDefault();
- var newName = $('#modal-content form input[name="object_name"]')
- .val();
- // Build new path
- var arr = path.split('/');
- var temp = new Array();
- for (i = 0; i < arr.length - 1; i++) {
- temp.push(arr[i])
- }
- var newPath = temp.join('/') + '/' + newName;
- $.get(_this.controller, { action: 'modify', path: path, new_name: newName} , function(data) {
- var renameResponse = codiad.jsend.parse(data);
- let renamedMessage = "";
- if (renameResponse != 'error') {
-
- if( type == undefined ) {
-
- renamedMessage = 'Successfully Renamed'
- } else {
-
- renamedMessage = type.charAt(0).toUpperCase() + type.slice(1) + ' Renamed'
- }
-
- codiad.message.success(renamedMessage);
- var node = $('#file-manager a[data-path="' + path + '"]');
- // Change pathing and name for node
- node.attr('data-path', newPath)
- .html(newName);
- if (type == 'file') { // Change icons for file
- curExtClass = 'ext-' + _this.getExtension(path);
- newExtClass = 'ext-' + _this.getExtension(newPath);
- $('#file-manager a[data-path="' + newPath + '"]')
- .removeClass(curExtClass)
- .addClass(newExtClass);
- } else { // Change pathing on any sub-files/directories
- _this.repathSubs(path, newPath);
- }
- // Change any active files
- codiad.active.rename(path, newPath);
- codiad.modal.unload();
- codiad.filemanager.rescan( project );
- /* Notify listeners. */
- amplify.publish('filemanager.onRename', {path: path, newPath: newPath, project: project });
- }
- });
- });
- },
-
- repathSubs: function(oldPath, newPath) {
- $('#file-manager a[data-path="' + newPath + '"]')
- .siblings('ul')
- .find('a')
- .each(function() {
- // Hit the children, hit 'em hard
- var curPath = $(this)
- .attr('data-path');
- var revisedPath = curPath.replace(oldPath, newPath);
- $(this)
- .attr('data-path', revisedPath);
- });
- },
-
- //////////////////////////////////////////////////////////////////
- // Delete
- //////////////////////////////////////////////////////////////////
-
- deleteNode: function(path) {
- var _this = this;
- codiad.modal.load(400, this.dialog, {
- action: 'delete',
- path: path
- });
- $('#modal-content form')
- .live('submit', function(e) {
- e.preventDefault();
- $.get(_this.controller + '?action=delete&path=' + encodeURIComponent(path), function(data) {
- var deleteResponse = codiad.jsend.parse(data);
- if (deleteResponse != 'error') {
- var node = $('#file-manager a[data-path="' + path + '"]');
- let parent_path = node.parent().parent().prev().attr('data-path');
- node.parent('li').remove();
- // Close any active files
- $('#active-files a')
- .each(function() {
- var curPath = $(this)
- .attr('data-path');
- if (curPath.indexOf(path) == 0) {
- codiad.active.remove(curPath);
- }
- });
- /* Notify listeners. */
- amplify.publish('filemanager.onDelete', {deletePath: path, path: parent_path });
- }
- codiad.modal.unload();
- });
- });
- },
+ //////////////////////////////////////////////////////////////////
+ // Create node in file tree
+ //////////////////////////////////////////////////////////////////
- deleteInnerNode: function(path) {
- var _this = this;
- codiad.modal.load(400, this.dialog, {
- action: 'delete',
- path: path
- });
- $('#modal-content form')
- .live('submit', function(e) {
- e.preventDefault();
- $.get(_this.controller + '?action=deleteInner&path=' + encodeURIComponent(path), function(data) {
- var deleteResponse = codiad.jsend.parse(data);
- if (deleteResponse != 'error') {
- var node = $('#file-manager a[data-path="' + path + '"]').parent('ul').remove();
+ createObject: function( parent, path, type ) {
+ // NODE FORMAT: {short_name}
+ var parentNode = $( '#file-manager a[data-path="' + parent + '"]' );
+ if( !$( '#file-manager a[data-path="' + path + '"]' )
+ .length ) { // Doesn't already exist
+ if( parentNode.hasClass( 'open' ) && parentNode.hasClass( 'directory' ) ) { // Only append node if parent is open (and a directory)
+ var shortName = this.getShortName( path );
+ if( type == 'directory' ) {
+ var appendage = '' + shortName + '';
+ } else {
+ var appendage = '' + shortName + '';
+ }
+ if( parentNode.siblings( 'ul' )
+ .length ) { // UL exists, other children to play with
+ parentNode.siblings( 'ul' )
+ .append( appendage );
+ } else {
+ $( '' )
+ .insertAfter( parentNode );
+ }
+ } else {
+ parentNode.parent().children( 'span' ).removeClass( 'none' );
+ parentNode.parent().children( 'span' ).addClass( 'plus' );
+ }
+ }
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Loop out all files and folders in directory path
+ //////////////////////////////////////////////////////////////////
+
+ indexFiles: [],
+
+ index: function( path, rescan ) {
+ let _this = this;
+ if( rescan === undefined ) {
+ rescan = false;
+ }
+ node = $( '#file-manager a[data-path="' + path + '"]' );
+ if( node.hasClass( 'open' ) && !rescan ) {
+ node.parent( 'li' )
+ .children( 'ul' )
+ .slideUp( 300, function() {
+ $( this )
+ .remove();
+ node.removeClass( 'open' );
+ });
+ } else {
+ node.addClass( 'loading' );
+ $.get( this.controller + '?action=index&path=' + encodeURIComponent( path ), function( data ) {
+ node.addClass( 'open' );
+ var objectsResponse = codiad.jsend.parse( data );
+ if( objectsResponse != 'error' ) {
+ /* Notify listener */
+ _this.indexFiles = objectsResponse.index;
+ amplify.publish( "filemanager.onIndex", {
+ path: path,
+ files: _this.indexFiles
+ });
+ var files = _this.indexFiles;
+ if( files.length > 0 ) {
+ if( node.parent().children( 'span' ).hasClass( 'plus' ) ) {
+ node.parent().children( 'span' ).removeClass( 'plus' ).addClass( 'minus' );
+ }
+ var display = 'display:none;';
+ if( rescan ) {
+ display = '';
+ }
+ var appendage = '';
+ $.each( files, function( index ) {
+ var ext = '';
+ var name = files[ index ].name.replace( path, '' );
+ var nodeClass = 'none';
+ name = name.split( '/' )
+ .join( ' ' );
+ if( files[ index ].type == 'file' ) {
+ var ext = ' ext-' + name.split( '.' )
+ .pop();
+ }
+ if( files[ index ].type == 'directory' && files[ index ].size > 0 ) {
+ nodeClass = 'plus';
+ }
+ appendage += '- ' + name + '
';
+ });
+ appendage += '
';
+ if( rescan ) {
+ node.parent( 'li' )
+ .children( 'ul' )
+ .remove();
+ }
+ $( appendage )
+ .insertAfter( node );
+ if( !rescan ) {
+ node.siblings( 'ul' )
+ .slideDown( 300 );
+ }
+ }
+ }
+ node.removeClass( 'loading' );
+ if( rescan && _this.rescanChildren.length > _this.rescanCounter ) {
+ _this.rescan( _this.rescanChildren[ _this.rescanCounter++ ] );
+ } else {
+ _this.rescanChildren = [];
+ _this.rescanCounter = 0;
+ }
+ });
+ }
+ },
+
+ rescanChildren: [],
+
+ rescanCounter: 0,
+
+ rescan: function( path ) {
+ let _this = this;
+ if( this.rescanCounter === 0 ) {
+ // Create array of open directories
+ node = $( '#file-manager a[data-path="' + path + '"]' );
+ node.parent().find( 'a.open' ).each( function() {
+ _this.rescanChildren.push( $( this ).attr( 'data-path' ) );
+ });
+ }
+
+ this.index( path, true );
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Open File
+ //////////////////////////////////////////////////////////////////
+
+ openFile: function( path, focus ) {
+
+ /* Notify listeners. */
+ amplify.publish( 'filemanager.onFileWillOpen', {
+ path: path
+ });
+
+ if( focus === undefined ) {
+ focus = true;
+ }
+ var node = $( '#file-manager a[data-path="' + path + '"]' );
+ var ext = this.getExtension( path );
+ if( $.inArray( ext.toLowerCase(), this.noOpen ) < 0 ) {
+ node.addClass( 'loading' );
+ $.get( this.controller + '?action=open&path=' + encodeURIComponent( path ), function( data ) {
+ var openResponse = codiad.jsend.parse( data );
+ if( openResponse != 'error' ) {
+ node.removeClass( 'loading' );
+ codiad.active.open( path, openResponse.content, openResponse.mtime, false, focus );
+ }
+ });
+ } else {
+ if( !codiad.project.isAbsPath( path ) ) {
+ if( $.inArray( ext.toLowerCase(), this.noBrowser ) < 0 ) {
+ this.download( path );
+ } else {
+ this.openInModal( path );
+ }
+ } else {
+ codiad.message.error( i18n( 'Unable to open file in Browser while using absolute path.' ) );
+ }
+ }
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Open in browser
+ //////////////////////////////////////////////////////////////////
+
+ openInBrowser: function( path ) {
+
+ let _this = this;
+
+ $.ajax( {
+ url: this.controller + '?action=open_in_browser&path=' + encodeURIComponent( path ),
+ success: function( data ) {
+ var openIBResponse = codiad.jsend.parse( data );
+ if( openIBResponse != 'error' ) {
- // Close any active files
- $('#active-files a')
- .each(function() {
- var curPath = $(this)
- .attr('data-path');
- if (curPath.indexOf(path) == 0) {
- codiad.active.remove(curPath);
- }
- });
-
- //Rescan Folder
- node.parent()
- .find('a.open')
- .each(function() {
- _this.rescanChildren.push($(this)
- .attr('data-path'));
- });
-
- /* Notify listeners. */
- amplify.publish('filemanager.onDelete', {deletePath: path + "/*", path: path });
- }
- codiad.modal.unload();
- });
- });
- },
- //////////////////////////////////////////////////////////////////
- // Search
- //////////////////////////////////////////////////////////////////
-
- search: function(path) {
- codiad.modal.load(500, this.dialog,{
- action: 'search',
- path: path
- });
- codiad.modal.load_process.done( async function() {
- var lastSearched = JSON.parse( await codiad.settings.get_option("lastSearched"));
- if(lastSearched) {
- $('#modal-content form input[name="search_string"]').val(lastSearched.searchText);
- $('#modal-content form input[name="search_file_type"]').val(lastSearched.fileExtension);
- $('#modal-content form select[name="search_type"]').val(lastSearched.searchType);
- if(lastSearched.searchResults != '') {
- $('#filemanager-search-results').slideDown().html(lastSearched.searchResults);
- }
- }
- });
- codiad.modal.hideOverlay();
- var _this = this;
- $('#modal-content form')
- .live('submit', function(e) {
- $('#filemanager-search-processing')
- .show();
- e.preventDefault();
- searchString = $('#modal-content form input[name="search_string"]')
- .val();
- fileExtensions=$('#modal-content form input[name="search_file_type"]')
- .val();
- searchFileType=$.trim(fileExtensions);
- if (searchFileType != '') {
- //season the string to use in find command
- searchFileType = "\\(" + searchFileType.replace(/\s+/g, "\\|") + "\\)";
- }
- searchType = $('#modal-content form select[name="search_type"]')
- .val();
- $.post(_this.controller + '?action=search&path=' + encodeURIComponent(path) + '&type=' + searchType, {
- search_string: searchString,
- search_file_type: searchFileType
- }, function(data) {
- searchResponse = codiad.jsend.parse(data);
- var results = '';
- if (searchResponse != 'error') {
- $.each(searchResponse.index, function(key, val) {
- // Cleanup file format
- if(val['file'].substr(-1) == '/') {
- val['file'] = val['file'].substr(0, str.length - 1);
- }
- val['file'] = val['file'].replace('//','/');
- // Add result
- results += '';
- });
- $('#filemanager-search-results')
- .slideDown()
- .html(results);
- } else {
- $('#filemanager-search-results')
- .slideUp();
- }
- _this.saveSearchResults(searchString, searchType, fileExtensions, results);
- $('#filemanager-search-processing')
- .hide();
- });
- });
- },
-
- /////////////////////////////////////////////////////////////////
- // saveSearchResults
- /////////////////////////////////////////////////////////////////
- saveSearchResults: function(searchText, searchType, fileExtensions, searchResults) {
- var lastSearched = {
- searchText: searchText,
- searchType: searchType,
- fileExtension: fileExtensions,
- searchResults: searchResults
- };
- localStorage.setItem("lastSearched", JSON.stringify(lastSearched));
- },
- //////////////////////////////////////////////////////////////////
- // Upload
- //////////////////////////////////////////////////////////////////
-
- uploadToNode: function(path) {
- codiad.modal.load(500, this.dialogUpload, {path: path});
- },
-
- //////////////////////////////////////////////////////////////////
- // Download
- //////////////////////////////////////////////////////////////////
-
- download: function(path) {
- var type = this.getType(path);
- $('#download')
- .attr('src', 'components/filemanager/download.php?path=' + encodeURIComponent(path) + '&type=' + type);
- }
- };
-
-})(this, jQuery);
+ _this.preview = window.open( openIBResponse.url, '_newtab' );
+
+ let editor = codiad.editor.getActive();
+
+ if( _this.auto_reload && editor !== null ) {
+
+ codiad.editor.getActive().addEventListener( "change", _this.refreshPreview );
+ }
+
+
+ }
+ },
+ async: false
+ });
+ },
+
+ refreshPreview: function( event ) {
+
+ let _this = codiad.filemanager;
+
+ /**
+ * When reloading after every change, we encounter performance issues
+ * in the editor. Therefore, we implement the same logic as the
+ * auto_save module where we only reload after the user has finished
+ * changing their document.
+ */
+
+ if( _this.refresh_interval !== null ) {
+
+ clearTimeout( _this.refresh_interval );
+ _this.refresh_interval = null;
+ }
+ _this.refresh_interval = setTimeout( function() {
+
+ if( _this.preview == null ) {
+
+ return;
+ }
+
+ try {
+
+ if( ( typeof _this.preview.location.reload ) == "undefined" ) {
+
+ _this.preview = null;
+ codiad.editor.getActive().removeEventListener( "change", _this.refreshPreview );
+ return;
+ }
+ _this.preview.location.reload( true );
+ } catch ( e ) {
+
+ console.log( e );
+ codiad.message.error( 'Please close your previously opened preview window.' );
+ _this.preview = null;
+ codiad.editor.getActive().removeEventListener( "change", _this.refreshPreview );
+ }
+ }, 500 );
+ },
+
+ openInModal: function( path ) {
+
+ let type = "";
+ var ext = this.getExtension( path ).toLowerCase();
+
+ if( this.noAudio.includes( ext ) ) {
+
+ type = 'music_preview';
+ } else if( this.noImages.includes( ext ) ) {
+
+ type = 'preview';
+ }
+
+ codiad.modal.load( 250, this.dialog, {
+ action: type,
+ path: path
+ });
+ },
+ saveModifications: function( path, data, callbacks, save = true ) {
+
+ callbacks = callbacks || {};
+ let _this = this, action;
+ var notifySaveErr = function() {
+ codiad.message.error( i18n( 'File could not be saved' ) );
+ if( typeof callbacks.error === 'function' ) {
+ var context = callbacks.context || _this;
+ callbacks.error.apply( context, [ data ] );
+ }
+ }
+ $.post( this.controller + '?action=modify&path=' + encodeURIComponent( path ), data, function( resp ) {
+ resp = $.parseJSON( resp );
+ if( resp.status == 'success' ) {
+ if( save === true ) {
+ codiad.message.success( i18n( 'File saved' ) );
+ }
+ if( typeof callbacks.success === 'function' ) {
+ var context = callbacks.context || _this;
+ callbacks.success.call( context, resp.data.mtime );
+ }
+ } else {
+ if( resp.message == 'Client is out of sync' ) {
+ var reload = confirm(
+ "Server has a more updated copy of the file. Would " +
+ "you like to refresh the contents ? Pressing no will " +
+ "cause your changes to override the server's copy upon " +
+ "next save."
+ );
+ if( reload ) {
+ codiad.active.close( path );
+ codiad.active.removeDraft( path );
+ _this.openFile( path );
+ } else {
+ var session = codiad.editor.getActive().getSession();
+ session.serverMTime = null;
+ session.untainted = null;
+ }
+ } else codiad.message.error( i18n( 'File could not be saved' ) );
+ if( typeof callbacks.error === 'function' ) {
+ var context = callbacks.context || _this;
+ callbacks.error.apply( context, [ resp.data ] );
+ }
+ }
+ }).error( notifySaveErr );
+ },
+ //////////////////////////////////////////////////////////////////
+ // Save file
+ //////////////////////////////////////////////////////////////////
+
+ saveFile: function( path, content, callbacks, save = true ) {
+ this.saveModifications( path, {
+ content: content
+ }, callbacks, save );
+ },
+
+ savePatch: function( path, patch, mtime, callbacks, alerts ) {
+ if( patch.length > 0 )
+ this.saveModifications( path, {
+ patch: patch,
+ mtime: mtime
+ }, callbacks, alerts );
+ else if( typeof callbacks.success === 'function' ) {
+ var context = callbacks.context || this;
+ callbacks.success.call( context, mtime );
+ }
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Create Object
+ //////////////////////////////////////////////////////////////////
+
+ createNode: function( path, type ) {
+ codiad.modal.load( 250, this.dialog, {
+ action: 'create',
+ type: type,
+ path: path
+ });
+ $( '#modal-content form' )
+ .live( 'submit', function( e ) {
+ let project = codiad.project.getCurrent();
+ e.preventDefault();
+ var shortName = $( '#modal-content form input[name="object_name"]' )
+ .val();
+ var path = $( '#modal-content form input[name="path"]' )
+ .val();
+ var type = $( '#modal-content form input[name="type"]' )
+ .val();
+ var createPath = path + '/' + shortName;
+ $.get( codiad.filemanager.controller + '?action=create&path=' + encodeURIComponent( createPath ) + '&type=' + type, function( data ) {
+ var createResponse = codiad.jsend.parse( data );
+ if( createResponse != 'error' ) {
+ codiad.message.success( type.charAt( 0 )
+ .toUpperCase() + type.slice( 1 ) + ' Created' );
+ codiad.modal.unload();
+ // Add new element to filemanager screen
+ codiad.filemanager.createObject( path, createPath, type );
+ if( type == 'file' ) {
+ codiad.filemanager.openFile( createPath, true );
+ }
+
+ codiad.filemanager.rescan( project );
+
+ /* Notify listeners. */
+ amplify.publish( 'filemanager.onCreate', {
+ createPath: createPath,
+ path: path,
+ shortName: shortName,
+ type: type
+ });
+ }
+ });
+ });
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Copy to Clipboard
+ //////////////////////////////////////////////////////////////////
+
+ copyNode: function( path ) {
+ this.clipboard = path;
+ codiad.message.success( i18n( 'Copied to Clipboard' ) );
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Paste
+ //////////////////////////////////////////////////////////////////
+
+ pasteNode: function( path ) {
+ let _this = this;
+ if( this.clipboard == '' ) {
+ codiad.message.error( i18n( 'Nothing in Your Clipboard' ) );
+ } else if( path == this.clipboard ) {
+ codiad.message.error( i18n( 'Cannot Paste Directory Into Itself' ) );
+ } else {
+ let project = codiad.project.getCurrent();
+ var shortName = _this.getShortName( _this.clipboard );
+ if( $( '#file-manager a[data-path="' + path + '/' + shortName + '"]' )
+ .length ) { // Confirm overwrite?
+ codiad.modal.load( 400, this.dialog, {
+ action: 'overwrite',
+ path: path + '/' + shortName
+ });
+ $( '#modal-content form' )
+ .live( 'submit', function( e ) {
+ e.preventDefault();
+ var duplicate = false;
+ if( $( '#modal-content form select[name="or_action"]' ).val() == 1 ) {
+ duplicate = true;
+ console.log( 'Dup!' );
+ }
+ _this.processPasteNode( path, duplicate );
+ });
+ } else { // No conflicts; proceed...
+ _this.processPasteNode( path, false );
+ }
+
+ codiad.filemanager.rescan( project );
+ }
+ },
+
+ processPasteNode: function( path, duplicate ) {
+ let _this = this;
+ var shortName = this.getShortName( this.clipboard );
+ var type = this.getType( this.clipboard );
+
+ $.get( this.controller + '?action=duplicate&path=' +
+ encodeURIComponent( this.clipboard ) + '&destination=' +
+ encodeURIComponent( path + '/' + shortName ) + '&duplicate=' + encodeURIComponent( duplicate ),
+ function( data ) {
+ var pasteResponse = codiad.jsend.parse( data );
+ if( pasteResponse != 'error' ) {
+ _this.createObject( path, path + '/' + shortName, type );
+ codiad.modal.unload();
+ /* Notify listeners. */
+ amplify.publish( 'filemanager.onPaste', {
+ path: path,
+ shortName: shortName,
+ duplicate: duplicate
+ });
+ }
+ });
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Rename
+ //////////////////////////////////////////////////////////////////
+
+ renameNode: function( path ) {
+ var shortName = this.getShortName( path );
+ var type = this.getType( path );
+ let _this = this;
+ codiad.modal.load( 250, this.dialog, {
+ action: 'rename',
+ path: path,
+ short_name: shortName,
+ type: type
+ });
+ $( '#modal-content form' )
+ .live( 'submit', function( e ) {
+ let project = codiad.project.getCurrent();
+ e.preventDefault();
+ var newName = $( '#modal-content form input[name="object_name"]' )
+ .val();
+ // Build new path
+ var arr = path.split( '/' );
+ var temp = new Array();
+ for( i = 0; i < arr.length - 1; i++ ) {
+ temp.push( arr[ i ] )
+ }
+ var newPath = temp.join( '/' ) + '/' + newName;
+ $.get( _this.controller, {
+ action: 'modify',
+ path: path,
+ new_name: newName
+ }, function( data ) {
+ var renameResponse = codiad.jsend.parse( data );
+ let renamedMessage = "";
+ if( renameResponse != 'error' ) {
+
+ if( type == undefined ) {
+
+ renamedMessage = 'Successfully Renamed'
+ } else {
+
+ renamedMessage = type.charAt( 0 ).toUpperCase() + type.slice( 1 ) + ' Renamed'
+ }
+
+ codiad.message.success( renamedMessage );
+ var node = $( '#file-manager a[data-path="' + path + '"]' );
+ // Change pathing and name for node
+ node.attr( 'data-path', newPath )
+ .html( newName );
+ if( type == 'file' ) { // Change icons for file
+ curExtClass = 'ext-' + _this.getExtension( path );
+ newExtClass = 'ext-' + _this.getExtension( newPath );
+ $( '#file-manager a[data-path="' + newPath + '"]' )
+ .removeClass( curExtClass )
+ .addClass( newExtClass );
+ } else { // Change pathing on any sub-files/directories
+ _this.repathSubs( path, newPath );
+ }
+ // Change any active files
+ codiad.active.rename( path, newPath );
+ codiad.modal.unload();
+ codiad.filemanager.rescan( project );
+ /* Notify listeners. */
+ amplify.publish( 'filemanager.onRename', {
+ path: path,
+ newPath: newPath,
+ project: project
+ });
+ }
+ });
+ });
+ },
+
+ repathSubs: function( oldPath, newPath ) {
+ $( '#file-manager a[data-path="' + newPath + '"]' )
+ .siblings( 'ul' )
+ .find( 'a' )
+ .each( function() {
+ // Hit the children, hit 'em hard
+ var curPath = $( this )
+ .attr( 'data-path' );
+ var revisedPath = curPath.replace( oldPath, newPath );
+ $( this )
+ .attr( 'data-path', revisedPath );
+ });
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Delete
+ //////////////////////////////////////////////////////////////////
+
+ deleteNode: function( path ) {
+ let _this = this;
+ codiad.modal.load( 400, this.dialog, {
+ action: 'delete',
+ path: path
+ });
+ $( '#modal-content form' )
+ .live( 'submit', function( e ) {
+ e.preventDefault();
+ $.get( _this.controller + '?action=delete&path=' + encodeURIComponent( path ), function( data ) {
+ var deleteResponse = codiad.jsend.parse( data );
+ if( deleteResponse != 'error' ) {
+ var node = $( '#file-manager a[data-path="' + path + '"]' );
+ let parent_path = node.parent().parent().prev().attr( 'data-path' );
+ node.parent( 'li' ).remove();
+ // Close any active files
+ $( '#active-files a' )
+ .each( function() {
+ var curPath = $( this )
+ .attr( 'data-path' );
+ if( curPath.indexOf( path ) == 0 ) {
+ codiad.active.remove( curPath );
+ }
+ });
+ /* Notify listeners. */
+ amplify.publish( 'filemanager.onDelete', {
+ deletePath: path,
+ path: parent_path
+ });
+ }
+ codiad.modal.unload();
+ });
+ });
+ },
+
+ deleteInnerNode: function( path ) {
+ let _this = this;
+ codiad.modal.load( 400, this.dialog, {
+ action: 'delete',
+ path: path
+ });
+ $( '#modal-content form' )
+ .live( 'submit', function( e ) {
+ e.preventDefault();
+ $.get( _this.controller + '?action=deleteInner&path=' + encodeURIComponent( path ), function( data ) {
+ var deleteResponse = codiad.jsend.parse( data );
+ if( deleteResponse != 'error' ) {
+ var node = $( '#file-manager a[data-path="' + path + '"]' ).parent( 'ul' ).remove();
+
+ // Close any active files
+ $( '#active-files a' )
+ .each( function() {
+ var curPath = $( this )
+ .attr( 'data-path' );
+ if( curPath.indexOf( path ) == 0 ) {
+ codiad.active.remove( curPath );
+ }
+ });
+
+ //Rescan Folder
+ node.parent()
+ .find( 'a.open' )
+ .each( function() {
+ _this.rescanChildren.push( $( this )
+ .attr( 'data-path' ) );
+ });
+
+ /* Notify listeners. */
+ amplify.publish( 'filemanager.onDelete', {
+ deletePath: path + "/*",
+ path: path
+ });
+ }
+ codiad.modal.unload();
+ });
+ });
+ },
+ //////////////////////////////////////////////////////////////////
+ // Search
+ //////////////////////////////////////////////////////////////////
+
+ search: function( path ) {
+ codiad.modal.load( 500, this.dialog, {
+ action: 'search',
+ path: path
+ });
+ codiad.modal.load_process.done( async function() {
+ var lastSearched = JSON.parse( await codiad.settings.get_option( "lastSearched" ) );
+ if( lastSearched ) {
+ $( '#modal-content form input[name="search_string"]' ).val( lastSearched.searchText );
+ $( '#modal-content form input[name="search_file_type"]' ).val( lastSearched.fileExtension );
+ $( '#modal-content form select[name="search_type"]' ).val( lastSearched.searchType );
+ if( lastSearched.searchResults != '' ) {
+ $( '#filemanager-search-results' ).slideDown().html( lastSearched.searchResults );
+ }
+ }
+ });
+ codiad.modal.hideOverlay();
+ let _this = this;
+ $( '#modal-content form' )
+ .live( 'submit', function( e ) {
+ $( '#filemanager-search-processing' )
+ .show();
+ e.preventDefault();
+ searchString = $( '#modal-content form input[name="search_string"]' )
+ .val();
+ fileExtensions = $( '#modal-content form input[name="search_file_type"]' )
+ .val();
+ searchFileType = $.trim( fileExtensions );
+ if( searchFileType != '' ) {
+ //season the string to use in find command
+ searchFileType = "\\(" + searchFileType.replace( /\s+/g, "\\|" ) + "\\)";
+ }
+ searchType = $( '#modal-content form select[name="search_type"]' )
+ .val();
+ $.post( _this.controller + '?action=search&path=' + encodeURIComponent( path ) + '&type=' + searchType, {
+ search_string: searchString,
+ search_file_type: searchFileType
+ }, function( data ) {
+ searchResponse = codiad.jsend.parse( data );
+ var results = '';
+ if( searchResponse != 'error' ) {
+ $.each( searchResponse.index, function( key, val ) {
+ // Cleanup file format
+ if( val[ 'file' ].substr( -1 ) == '/' ) {
+ val[ 'file' ] = val[ 'file' ].substr( 0, str.length - 1 );
+ }
+ val[ 'file' ] = val[ 'file' ].replace( '//', '/' );
+ // Add result
+ results += '';
+ });
+ $( '#filemanager-search-results' )
+ .slideDown()
+ .html( results );
+ } else {
+ $( '#filemanager-search-results' )
+ .slideUp();
+ }
+ _this.saveSearchResults( searchString, searchType, fileExtensions, results );
+ $( '#filemanager-search-processing' )
+ .hide();
+ });
+ });
+ },
+
+ /////////////////////////////////////////////////////////////////
+ // saveSearchResults
+ /////////////////////////////////////////////////////////////////
+ saveSearchResults: function( searchText, searchType, fileExtensions, searchResults ) {
+ var lastSearched = {
+ searchText: searchText,
+ searchType: searchType,
+ fileExtension: fileExtensions,
+ searchResults: searchResults
+ };
+ localStorage.setItem( "lastSearched", JSON.stringify( lastSearched ) );
+ },
+ //////////////////////////////////////////////////////////////////
+ // Upload
+ //////////////////////////////////////////////////////////////////
+
+ uploadToNode: function( path ) {
+ codiad.modal.load( 500, this.dialogUpload, {
+ path: path
+ });
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Download
+ //////////////////////////////////////////////////////////////////
+
+ download: function( path ) {
+ var type = this.getType( path );
+ $( '#download' )
+ .attr( 'src', 'components/filemanager/download.php?path=' + encodeURIComponent( path ) + '&type=' + type );
+ }
+ };
+
+})( this, jQuery );
\ No newline at end of file