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 = ''; - 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 = ''; + 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 += '
    Line ' + val['line'] + ': ' + val['file'] + '
    '; - }); - $('#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 += '
    Line ' + val[ 'line' ] + ': ' + val[ 'file' ] + '
    '; + }); + $( '#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