diff --git a/components/active/init.js b/components/active/init.js
index 369ad15..1c5a035 100755
--- a/components/active/init.js
+++ b/components/active/init.js
@@ -4,1014 +4,1022 @@
* warranty under the MIT License. See [root]/license.txt for more.
* This information must remain intact.
*/
-
-(function(global, $) {
-
- var EditSession = ace.require('ace/edit_session')
- .EditSession;
- var UndoManager = ace.require('ace/undomanager')
- .UndoManager;
-
- var codiad = global.codiad;
-
- $(function() {
- codiad.active.init();
- });
-
- //////////////////////////////////////////////////////////////////
- //
- // Active Files Component for Codiad
- // ---------------------------------
- // Track and manage EditSession instaces of files being edited.
- //
- //////////////////////////////////////////////////////////////////
-
- codiad.active = {
-
- controller: 'components/active/controller.php',
-
- // Path to EditSession instance mapping
- sessions: {},
-
- // History of opened files
- history: [],
+( function( global, $ ) {
+
+ var EditSession = ace.require( 'ace/edit_session' )
+ .EditSession;
+ var UndoManager = ace.require( 'ace/undomanager' )
+ .UndoManager;
+
+ var codiad = global.codiad;
+
+ $( function() {
+ codiad.active.init();
+ });
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Active Files Component for Codiad
+ // ---------------------------------
+ // Track and manage EditSession instaces of files being edited.
+ //
+ //////////////////////////////////////////////////////////////////
+
+ codiad.active = {
+
+ controller: 'components/active/controller.php',
+
+ // Path to EditSession instance mapping
+ sessions: {},
+
+ // History of opened files
+ history: [],
// List of active file positions
positions: {},
-
- //////////////////////////////////////////////////////////////////
- //
- // Check if a file is open.
- //
- // Parameters:
- // path - {String}
- //
- //////////////////////////////////////////////////////////////////
-
- isOpen: function(path) {
- return !!this.sessions[path];
- },
-
- open: function(path, content, mtime, inBackground, focus) {
-
- //if( this. ) {
-
-
- //}
- /* Notify listeners. */
- amplify.publish('active.onFileWillOpen', {path: path, content: content});
-
- if (focus === undefined) {
- focus = true;
- }
-
- var _this = this;
-
- if (this.isOpen(path)) {
- if(focus) this.focus(path);
- return;
- }
- var ext = codiad.filemanager.getExtension(path);
- var mode = codiad.editor.selectMode( path );
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Check if a file is open.
+ //
+ // Parameters:
+ // path - {String}
+ //
+ //////////////////////////////////////////////////////////////////
+
+ isOpen: function( path ) {
+ return !!this.sessions[path];
+ },
+
+ open: function( path, content, mtime, inBackground, focus ) {
- var fn = function() {
-
- //var Mode = require('ace/mode/' + mode)
- // .Mode;
-
- // TODO: Ask for user confirmation before recovering
- // And maybe show a diff
- var draft = _this.checkDraft(path);
- if (draft) {
- content = draft;
- codiad.message.success(i18n('Recovered unsaved content for: ') + path);
- }
-
- //var session = new EditSession(content, new Mode());
- var session = new EditSession(content);
- session.setMode(mode.mode);
- session.setUndoManager(new UndoManager());
-
- session.path = path;
- session.serverMTime = mtime;
- _this.sessions[path] = session;
- session.untainted = content.slice(0);
- if (!inBackground && focus) {
- codiad.editor.setSession(session);
- }
- _this.add(path, session, focus);
-
- if( ! ( _this.positions[`${path}`] === undefined ) && focus ) {
-
- _this.setPosition( _this.positions[`${path}`] );
- }
-
- /* Notify listeners. */
- amplify.publish('active.onOpen', path);
- };
-
- // Assuming the mode file has no dependencies
- $.loadScript('components/editor/ace-editor/mode-' + mode.name + '.js',
- fn);
- },
-
- init: function() {
-
- var _this = this;
-
- _this.initTabDropdownMenu();
- _this.updateTabDropdownVisibility();
-
- // Focus from list.
- $('#list-active-files a')
- .live('click', function(e) {
- e.stopPropagation();
- _this.focus($(this).parent('li').attr('data-path'));
- });
-
- // Focus on left button click from dropdown.
- $('#dropdown-list-active-files a')
- .live('click', function(e) {
- if(e.which == 1) {
- /* Do not stop propagation of the event,
- * it will be catch by the dropdown menu
- * and close it. */
- _this.focus($(this).parent('li').attr('data-path'));
- }
- });
-
- // Focus on left button mousedown from tab.
- $('#tab-list-active-files li.tab-item>a.label')
- .live('mousedown', function(e) {
- if(e.which == 1) {
- e.stopPropagation();
- _this.focus($(this).parent('li').attr('data-path'));
- }
- });
+ //if( this. ) {
- // Remove from list.
- $('#list-active-files a>span')
- .live('click', function(e) {
- e.stopPropagation();
- _this.remove($(this)
- .parent('a')
- .parent('li')
- .attr('data-path'));
- });
-
- // Remove from dropdown.
- $('#dropdown-list-active-files a>span')
- .live('click', function(e) {
- e.stopPropagation();
- /* Get the active editor before removing anything. Remove the
- * tab, then put back the focus on the previously active
- * editor if it was not removed. */
- var activePath = _this.getPath();
- var pathToRemove = $(this).parents('li').attr('data-path');
- _this.remove(pathToRemove);
- if (activePath !== null && activePath !== pathToRemove) {
- _this.focus(activePath);
- }
- _this.updateTabDropdownVisibility();
- });
-
- // Remove from tab.
- $('#tab-list-active-files a.close')
- .live('click', function(e) {
- e.stopPropagation();
- /* Get the active editor before removing anything. Remove the
- * tab, then put back the focus on the previously active
- * editor if it was not removed. */
- var activePath = _this.getPath();
- var pathToRemove = $(this).parent('li').attr('data-path');
- _this.remove(pathToRemove);
- if (activePath !== null && activePath !== pathToRemove) {
- _this.focus(activePath);
- }
- _this.updateTabDropdownVisibility();
- });
-
- // Remove from middle button click on dropdown.
- $('#dropdown-list-active-files li')
- .live('mouseup', function(e) {
- if (e.which == 2) {
- e.stopPropagation();
- /* Get the active editor before removing anything. Remove the
- * tab, then put back the focus on the previously active
- * editor if it was not removed. */
- var activePath = _this.getPath();
- var pathToRemove = $(this).attr('data-path');
- _this.remove(pathToRemove);
- if (activePath !== null && activePath !== pathToRemove) {
- _this.focus(activePath);
- }
- _this.updateTabDropdownVisibility();
- }
- });
-
- // Remove from middle button click on tab.
- $('.tab-item')
- .live('mouseup', function(e) {
- if (e.which == 2) {
- e.stopPropagation();
- /* Get the active editor before removing anything. Remove the
- * tab, then put back the focus on the previously active
- * editor if it was not removed. */
- var activePath = _this.getPath();
- var pathToRemove = $(this).attr('data-path');
- _this.remove(pathToRemove);
- if (activePath !== null && activePath !== pathToRemove) {
- _this.focus(activePath);
- }
- _this.updateTabDropdownVisibility();
- }
- });
-
- // Make list sortable
- $('#list-active-files')
- .sortable({
- placeholder: 'active-sort-placeholder',
- tolerance: 'intersect',
- start: function(e, ui) {
- ui.placeholder.height(ui.item.height());
- }
- });
-
- // Make dropdown sortable.
- $('#dropdown-list-active-files')
- .sortable({
- axis: 'y',
- tolerance: 'pointer',
- start: function(e, ui) {
- ui.placeholder.height(ui.item.height());
- }
- });
-
- // Make tabs sortable.
- $('#tab-list-active-files')
- .sortable({
- items: '> li',
- axis: 'x',
- tolerance: 'pointer',
- containment: 'parent',
- start: function(e, ui) {
- ui.placeholder.css('background', 'transparent');
- ui.helper.css('width', '200px');
- },
- stop: function(e, ui) {
- // Reset css
- ui.item.css('z-index', '')
- ui.item.css('position', '')
- }
- });
- /* Woaw, so tricky! At initialization, the tab-list is empty, so
- * it is not marked as float so it is not detected as an horizontal
- * list by the sortable plugin. Workaround is to mark it as
- * floating at initialization time. See bug report
- * http://bugs.jqueryui.com/ticket/6702. */
- $('#tab-list-active-files').data('sortable').floating = true;
-
- // Open saved-state active files on load
- $.get(_this.controller + '?action=list', function(data) {
- var listResponse = codiad.jsend.parse(data);
- if (listResponse !== null) {
- $.each(listResponse, function(index, data) {
-
- codiad.active.positions[`${data.path}`] = JSON.parse( data.position );
- codiad.filemanager.openFile(data.path, data.focused);
- });
- }
- });
- // Prompt if a user tries to close window without saving all filess
- window.onbeforeunload = function(e) {
-
- codiad.active.uploadPositions();
- if ($('#list-active-files li.changed')
- .length > 0) {
- var e = e || window.event;
- var errMsg = i18n('You have unsaved files.');
-
- // For IE and Firefox prior to version 4
- if (e) {
- e.returnValue = errMsg;
- }
-
- // For rest
- return errMsg;
- }
- };
- },
-
- //////////////////////////////////////////////////////////////////
- // Drafts
- //////////////////////////////////////////////////////////////////
-
- checkDraft: function(path) {
- var draft = localStorage.getItem(path);
- if (draft !== null) {
- return draft;
- } else {
- return false;
- }
- },
-
- removeDraft: function(path) {
- localStorage.removeItem(path);
- },
-
- //////////////////////////////////////////////////////////////////
- // Get active editor path
- //////////////////////////////////////////////////////////////////
-
- getPath: function() {
- try {
- return codiad.editor.getActive()
- .getSession()
- .path;
- } catch (e) {
- return null;
- }
- },
-
- //////////////////////////////////////////////////////////////////
- // Check if opened by another user
- //////////////////////////////////////////////////////////////////
-
- check: function(path) {
- $.get(this.controller + '?action=check&path=' + encodeURIComponent(path),
-
- function(data) {
- var checkResponse = codiad.jsend.parse(data);
- });
- },
-
- //////////////////////////////////////////////////////////////////
- // Add newly opened file to list
- //////////////////////////////////////////////////////////////////
-
- add: function(path, session, focus) {
- if (focus === undefined) {
- focus = true;
- }
-
- var listThumb = this.createListThumb(path);
- session.listThumb = listThumb;
- $('#list-active-files').append(listThumb);
-
- /* If the tab list would overflow with the new tab. Move the
- * first tab to dropdown, then add a new tab. */
- if (this.isTabListOverflowed(true)) {
- var tab = $('#tab-list-active-files li:first-child');
- this.moveTabToDropdownMenu(tab);
- }
-
- var tabThumb = this.createTabThumb(path);
- $('#tab-list-active-files').append(tabThumb);
- session.tabThumb = tabThumb;
-
- this.updateTabDropdownVisibility();
-
- $.get(this.controller + '?action=add&path=' + encodeURIComponent(path));
-
- if(focus) {
- this.focus(path);
- }
-
- // Mark draft as changed
- if (this.checkDraft(path)) {
- this.markChanged(path);
- }
- },
-
- //////////////////////////////////////////////////////////////////
- // Focus on opened file
- //////////////////////////////////////////////////////////////////
-
- focus: function(path, moveToTabList) {
- if (moveToTabList === undefined) {
- moveToTabList = true;
- }
-
- /* Notify listeners. */
- amplify.publish('active.onWillFocus', path);
-
- this.highlightEntry(path, moveToTabList);
-
- if(path != this.getPath()) {
-
- let _this = this;
- codiad.editor.setSession(this.sessions[path]);
- this.history.push(path);
- $.get(this.controller, {'action':'focused', 'path':path}, function() {
-
- if( ! ( _this.positions[`${path}`] === undefined ) ) {
-
- _this.setPosition( _this.positions[`${path}`] );
- }
- });
- }
-
- /* Check for users registered on the file. */
- this.check(path);
+ //}
+ /* Notify listeners. */
+ amplify.publish( 'active.onFileWillOpen', {
+ path: path,
+ content: content
+ });
- /* Notify listeners. */
- amplify.publish('active.onFocus', path);
- },
-
- highlightEntry: function(path, moveToTabList) {
- if (moveToTabList === undefined) {
- moveToTabList = true;
- }
-
- $('#list-active-files li')
- .removeClass('active');
-
- $('#tab-list-active-files li')
- .removeClass('active');
-
- $('#dropdown-list-active-files li')
- .removeClass('active');
-
- var session = this.sessions[path];
-
- if($('#dropdown-list-active-files').has(session.tabThumb).length > 0) {
- if(moveToTabList) {
- /* Get the menu item as a tab, and put the last tab in
- * dropdown. */
- var menuItem = session.tabThumb;
- this.moveDropdownMenuItemToTab(menuItem, true);
-
- var tab = $('#tab-list-active-files li:last-child');
- this.moveTabToDropdownMenu(tab);
- } else {
- /* Show the dropdown menu if needed */
- this.showTabDropdownMenu();
- }
- }
- else if(this.history.length > 0) {
- var prevPath = this.history[this.history.length-1];
- var prevSession = this.sessions[prevPath];
- if($('#dropdown-list-active-files').has(prevSession.tabThumb).length > 0) {
- /* Hide the dropdown menu if needed */
- this.hideTabDropdownMenu();
- }
- }
-
- session.tabThumb.addClass('active');
- session.listThumb.addClass('active');
- },
-
- //////////////////////////////////////////////////////////////////
- // Mark changed
- //////////////////////////////////////////////////////////////////
-
- markChanged: function(path) {
- this.sessions[path].listThumb.addClass('changed');
- this.sessions[path].tabThumb.addClass('changed');
- },
-
- //////////////////////////////////////////////////////////////////
- // Save active editor
- //////////////////////////////////////////////////////////////////
-
- save: function(path, alerts=true) {
- /* Notify listeners. */
- amplify.publish('active.onSave', path);
-
- var _this = this;
- if ((path && !this.isOpen(path)) || (!path && !codiad.editor.getActive())) {
- codiad.message.error(i18n('No Open Files to save'));
- return;
- }
- var session;
- if (path) session = this.sessions[path];
- else session = codiad.editor.getActive()
- .getSession();
- var content = session.getValue();
- var path = session.path;
- var handleSuccess = function(mtime){
- var session = codiad.active.sessions[path];
- if(typeof session != 'undefined') {
- session.untainted = newContent;
- session.serverMTime = mtime;
- if (session.listThumb) session.listThumb.removeClass('changed');
- if (session.tabThumb) session.tabThumb.removeClass('changed');
- }
- _this.removeDraft(path);
- }
- // Replicate the current content so as to avoid
- // discrepancies due to content changes during
- // computation of diff
-
- var newContent = content.slice(0);
- if (session.serverMTime && session.untainted){
- codiad.workerManager.addTask({
- taskType: 'diff',
- id: path,
- original: session.untainted,
- changed: newContent
- }, function(success, patch){
- if (success) {
- codiad.filemanager.savePatch(path, patch, session.serverMTime, {
- success: handleSuccess
- }, alerts);
- } else {
- codiad.filemanager.saveFile(path, newContent, {
- success: handleSuccess
- }, alerts);
- }
- }, this);
- } else {
- codiad.filemanager.saveFile(path, newContent, {
- success: handleSuccess
- }, alert);
- }
- },
-
- //////////////////////////////////////////////////////////////////
- // Save all files
- //////////////////////////////////////////////////////////////////
-
- saveAll: function() {
- var _this = this;
- for(var session in _this.sessions) {
- if (_this.sessions[session].listThumb.hasClass('changed')) {
- codiad.active.save(session);
- }
- }
- },
-
- //////////////////////////////////////////////////////////////////
- // Remove file
- //////////////////////////////////////////////////////////////////
-
- remove: function(path) {
- if (!this.isOpen(path)) return;
- var session = this.sessions[path];
- var closeFile = true;
- if (session.listThumb.hasClass('changed')) {
- codiad.modal.load(450, 'components/active/dialog.php?action=confirm&path=' + encodeURIComponent(path));
- closeFile = false;
- }
- if (closeFile) {
- this.close(path);
- }
- },
-
- removeAll: function(discard) {
- discard = discard || false;
- /* Notify listeners. */
- amplify.publish('active.onRemoveAll');
-
- var _this = this;
- var changed = false;
-
- var opentabs = new Array();
- for(var session in _this.sessions) {
- opentabs[session] = session;
- if (_this.sessions[session].listThumb.hasClass('changed')) {
- changed = true;
- }
- }
- if(changed && !discard) {
- codiad.modal.load(450, 'components/active/dialog.php?action=confirmAll');
- return;
- }
-
- for(var tab in opentabs) {
- var session = this.sessions[tab];
-
- session.tabThumb.remove();
- _this.updateTabDropdownVisibility();
-
- session.listThumb.remove();
-
- /* Remove closed path from history */
- var history = [];
- $.each(this.history, function(index) {
- if(this != tab) history.push(this);
- })
- this.history = history
-
- delete this.sessions[tab];
- this.removeDraft(tab);
- }
- codiad.editor.exterminate();
- $('#list-active-files').html('');
- $.get(this.controller + '?action=removeall');
- },
-
- close: function(path) {
- /* Notify listeners. */
- amplify.publish('active.onClose', path);
-
- var _this = this;
- var session = this.sessions[path];
-
- /* Animate only if the tabThumb if a tab, not a dropdown item. */
- if(session.tabThumb.hasClass('tab-item')) {
- session.tabThumb.css({'z-index': 1});
- session.tabThumb.animate({
- top: $('#editor-top-bar').height() + 'px'
- }, 300, function() {
- session.tabThumb.remove();
- _this.updateTabDropdownVisibility();
- });
- } else {
- session.tabThumb.remove();
- _this.updateTabDropdownVisibility();
- }
-
- session.listThumb.remove();
-
- /* Remove closed path from history */
- var history = [];
- $.each(this.history, function(index) {
- if(this != path) history.push(this);
- })
- this.history = history
-
- /* Select all the tab tumbs except the one which is to be removed. */
- var tabThumbs = $('#tab-list-active-files li[data-path!="' + path + '"]');
-
- if (tabThumbs.length == 0) {
- codiad.editor.exterminate();
- } else {
-
- var nextPath = '';
- if(this.history.length > 0) {
- nextPath = this.history[this.history.length - 1];
- } else {
- nextPath = $(tabThumbs[0]).attr('data-path');
- }
- var nextSession = this.sessions[nextPath];
- codiad.editor.removeSession(session, nextSession);
-
- this.focus(nextPath);
- }
- delete this.sessions[path];
- $.get(this.controller + '?action=remove&path=' + encodeURIComponent(path));
- this.removeDraft(path);
- },
-
- //////////////////////////////////////////////////////////////////
- // Process rename
- //////////////////////////////////////////////////////////////////
-
- rename: function(oldPath, newPath) {
- var switchSessions = function(oldPath, newPath) {
- var tabThumb = this.sessions[oldPath].tabThumb;
- tabThumb.attr('data-path', newPath);
- var title = newPath;
- if (codiad.project.isAbsPath(newPath)) {
- title = newPath.substring(1);
- }
- tabThumb.find('.label')
- .text(title);
- this.sessions[newPath] = this.sessions[oldPath];
- this.sessions[newPath].path = newPath;
- delete this.sessions[oldPath];
- //Rename history
- for (var i = 0; i < this.history.length; i++) {
- if (this.history[i] === oldPath) {
- this.history[i] = newPath;
- }
- }
- };
- if (this.sessions[oldPath]) {
- // A file was renamed
- switchSessions.apply(this, [oldPath, newPath]);
- // pass new sessions instance to setactive
- for (var k = 0; k < codiad.editor.instances.length; k++) {
- if (codiad.editor.instances[k].getSession().path === newPath) {
- codiad.editor.setActive(codiad.editor.instances[k]);
- }
- }
-
- var newSession = this.sessions[newPath];
-
- // Change Editor Mode
- var mode = codiad.editor.selectMode(newPath);
+ if( focus === undefined ) {
+ focus = true;
+ }
+
+ var _this = this;
+
+ if( this.isOpen( path ) ) {
+ if( focus ) this.focus( path );
+ return;
+ }
+ var ext = codiad.filemanager.getExtension( path );
+ var mode = codiad.editor.selectMode( path );
+
+ var fn = function() {
- // handle async mode change
- var fn = function() {
- codiad.editor.setModeDisplay(newSession);
- newSession.removeListener('changeMode', fn);
- }
-
- newSession.on("changeMode", fn);
- newSession.setMode( mode.mode );
- } else {
- // A folder was renamed
- var newKey;
- for (var key in this.sessions) {
- newKey = key.replace(oldPath, newPath);
- if (newKey !== key) {
- switchSessions.apply(this, [key, newKey]);
- }
- }
- }
- $.get(this.controller + '?action=rename&old_path=' + encodeURIComponent(oldPath) + '&new_path=' + encodeURIComponent(newPath), function() {
- /* Notify listeners. */
- amplify.publish('active.onRename', {"oldPath": oldPath, "newPath": newPath});
- });
- },
-
- //////////////////////////////////////////////////////////////////
- // Open in Browser
- //////////////////////////////////////////////////////////////////
-
- openInBrowser: function() {
- var path = this.getPath();
- if (path) {
- codiad.filemanager.openInBrowser(path);
- } else {
- codiad.message.error('No Open Files');
- }
- },
-
- //////////////////////////////////////////////////////////////////
- // Get Selected Text
- //////////////////////////////////////////////////////////////////
-
- getSelectedText: function() {
- var path = this.getPath();
- var session = this.sessions[path];
-
- if (path && this.isOpen(path)) {
- return session.getTextRange(
- codiad.editor.getActive()
- .getSelectionRange());
- } else {
- codiad.message.error(i18n('No Open Files or Selected Text'));
- }
- },
-
- //////////////////////////////////////////////////////////////////
- // Insert Text
- //////////////////////////////////////////////////////////////////
-
- insertText: function(val) {
- codiad.editor.getActive()
- .insert(val);
- },
-
- //////////////////////////////////////////////////////////////////
- // Goto Line
- //////////////////////////////////////////////////////////////////
-
- gotoLine: function(line) {
- codiad.editor.getActive()
- .gotoLine(line, 0, true);
- },
-
- //////////////////////////////////////////////////////////////////
- // Move Up (Key Combo)
- //////////////////////////////////////////////////////////////////
-
- move: function(dir) {
-
- var num = $('#tab-list-active-files li').length;
- if (num === 0) return;
-
- var newActive = null;
- var active = null;
-
- if (dir == 'up') {
-
- // If active is in the tab list
- active = $('#tab-list-active-files li.active');
- if(active.length > 0) {
- // Previous or rotate to the end
- newActive = active.prev('li');
- if (newActive.length === 0) {
- newActive = $('#dropdown-list-active-files li:last-child')
- if (newActive.length === 0) {
- newActive = $('#tab-list-active-files li:last-child')
- }
- }
- }
-
- // If active is in the dropdown list
- active = $('#dropdown-list-active-files li.active');
- if(active.length > 0) {
- // Previous
- newActive = active.prev('li');
- if (newActive.length === 0) {
- newActive = $('#tab-list-active-files li:last-child')
- }
- }
-
- } else {
-
- // If active is in the tab list
- active = $('#tab-list-active-files li.active');
- if(active.length > 0) {
- // Next or rotate to the beginning
- newActive = active.next('li');
- if (newActive.length === 0) {
- newActive = $('#dropdown-list-active-files li:first-child');
- if (newActive.length === 0) {
- newActive = $('#tab-list-active-files li:first-child')
- }
- }
- }
-
- // If active is in the dropdown list
- active = $('#dropdown-list-active-files li.active');
- if(active.length > 0) {
- // Next or rotate to the beginning
- newActive = active.next('li');
- if (newActive.length === 0) {
- newActive = $('#tab-list-active-files li:first-child')
- }
- }
-
- }
-
- if(newActive) this.focus(newActive.attr('data-path'), false);
- },
-
- //////////////////////////////////////////////////////////////////
- // Dropdown Menu
- //////////////////////////////////////////////////////////////////
-
- initTabDropdownMenu: function() {
- var _this = this;
-
- var menu = $('#dropdown-list-active-files');
- var button = $('#tab-dropdown-button');
- var closebutton = $('#tab-close-button');
-
- menu.appendTo($('body'));
-
- button.click(function(e) {
- e.stopPropagation();
- _this.toggleTabDropdownMenu();
- });
-
- closebutton.click(function(e) {
- e.stopPropagation();
- _this.removeAll();
- });
- },
-
- showTabDropdownMenu: function() {
- var menu = $('#dropdown-list-active-files');
- if(!menu.is(':visible')) this.toggleTabDropdownMenu();
- },
-
- hideTabDropdownMenu: function() {
- var menu = $('#dropdown-list-active-files');
- if(menu.is(':visible')) this.toggleTabDropdownMenu();
- },
-
- toggleTabDropdownMenu: function() {
- var _this = this;
- var menu = $('#dropdown-list-active-files');
-
- menu.css({
- top: $("#editor-top-bar").height() + 'px',
- right: '20px',
- width: '200px'
- });
-
- menu.slideToggle('fast');
-
- if(menu.is(':visible')) {
- // handle click-out autoclosing
- var fn = function() {
- menu.hide();
- $(window).off('click', fn)
- }
- $(window).on('click', fn);
- }
- },
-
- moveTabToDropdownMenu: function(tab, prepend) {
- if (prepend === undefined) {
- prepend = false;
- }
-
- tab.remove();
- path = tab.attr('data-path');
-
- var tabThumb = this.createMenuItemThumb(path);
- if(prepend) $('#dropdown-list-active-files').prepend(tabThumb);
- else $('#dropdown-list-active-files').append(tabThumb);
-
- if(tab.hasClass("changed")) {
- tabThumb.addClass("changed");
- }
-
- if(tab.hasClass("active")) {
- tabThumb.addClass("active");
- }
-
- this.sessions[path].tabThumb = tabThumb;
- },
-
- moveDropdownMenuItemToTab: function(menuItem, prepend) {
- if (prepend === undefined) {
- prepend = false;
- }
-
- menuItem.remove();
- path = menuItem.attr('data-path');
-
- var tabThumb = this.createTabThumb(path);
- if(prepend) $('#tab-list-active-files').prepend(tabThumb);
- else $('#tab-list-active-files').append(tabThumb);
-
- if(menuItem.hasClass("changed")) {
- tabThumb.addClass("changed");
- }
-
- if(menuItem.hasClass("active")) {
- tabThumb.addClass("active");
- }
-
- this.sessions[path].tabThumb = tabThumb;
- },
-
- isTabListOverflowed: function(includeFictiveTab) {
- if (includeFictiveTab === undefined) {
- includeFictiveTab = false;
- }
-
- var tabs = $('#tab-list-active-files li');
- var count = tabs.length
- if (includeFictiveTab) count += 1;
- if (count <= 1) return false;
-
- var width = 0;
- tabs.each(function(index) {
- width += $(this).outerWidth(true);
- })
- if (includeFictiveTab) {
- width += $(tabs[tabs.length-1]).outerWidth(true);
- }
-
- /* If we subtract the width of the left side bar, of the right side
- * bar handle and of the tab dropdown handle to the window width,
- * do we have enough room for the tab list? Its kind of complicated
- * to handle all the offsets, so afterwards we add a fixed offset
- * just t be sure. */
- var lsbarWidth = $(".sidebar-handle").width();
- if (codiad.sidebars.isLeftSidebarOpen) {
- lsbarWidth = $("#sb-left").width();
- }
-
- var rsbarWidth = $(".sidebar-handle").width();
- if (codiad.sidebars.isRightSidebarOpen) {
- rsbarWidth = $("#sb-right").width();
- }
-
- var tabListWidth = $("#tab-list-active-files").width();
- var dropdownWidth = $('#tab-dropdown').width();
- var closeWidth = $('#tab-close').width();
- var room = window.innerWidth - lsbarWidth - rsbarWidth - dropdownWidth - closeWidth - width - 30;
- return (room < 0);
- },
-
- updateTabDropdownVisibility: function() {
- while(this.isTabListOverflowed()) {
- var tab = $('#tab-list-active-files li:last-child');
- if (tab.length == 1) this.moveTabToDropdownMenu(tab, true);
- else break;
- }
-
- while(!this.isTabListOverflowed(true)) {
- var menuItem = $('#dropdown-list-active-files li:first-child');
- if (menuItem.length == 1) this.moveDropdownMenuItemToTab(menuItem);
- else break;
- }
-
- if ($('#dropdown-list-active-files li').length > 0) {
- $('#tab-dropdown').show();
- } else {
- $('#tab-dropdown').hide();
- // Be sure to hide the menu if it is opened.
- $('#dropdown-list-active-files').hide();
- }
- if ($('#tab-list-active-files li').length > 1) {
- $('#tab-close').show();
- } else {
- $('#tab-close').hide();
- }
- },
+ //var Mode = require('ace/mode/' + mode)
+ // .Mode;
+
+ // TODO: Ask for user confirmation before recovering
+ // And maybe show a diff
+ var draft = _this.checkDraft( path );
+ if( draft ) {
+ content = draft;
+ codiad.message.success( i18n( 'Recovered unsaved content for: ' ) + path );
+ }
+
+ //var session = new EditSession(content, new Mode());
+ var session = new EditSession( content );
+ session.setMode( mode.mode );
+ session.setUndoManager( new UndoManager() );
+
+ session.path = path;
+ session.serverMTime = mtime;
+ _this.sessions[path] = session;
+ session.untainted = content.slice( 0 );
+ if( !inBackground && focus ) {
+ codiad.editor.setSession( session );
+ }
+ _this.add( path, session, focus );
+
+ if( !( _this.positions[`${path}`] === undefined ) && focus ) {
+
+ _this.setPosition( _this.positions[`${path}`] );
+ }
+
+ /* Notify listeners. */
+ amplify.publish( 'active.onOpen', path );
+ };
+
+ // Assuming the mode file has no dependencies
+ $.loadScript( 'components/editor/ace-editor/mode-' + mode.name + '.js',
+ fn );
+ },
+
+ init: function() {
+
+ var _this = this;
+
+ _this.initTabDropdownMenu();
+ _this.updateTabDropdownVisibility();
+
+ // Focus from list.
+ $( '#list-active-files a' )
+ .live( 'click', function( e ) {
+ e.stopPropagation();
+ _this.focus( $( this ).parent( 'li' ).attr( 'data-path' ) );
+ });
+
+ // Focus on left button click from dropdown.
+ $( '#dropdown-list-active-files a' )
+ .live( 'click', function( e ) {
+ if( e.which == 1 ) {
+ /* Do not stop propagation of the event,
+ * it will be catch by the dropdown menu
+ * and close it. */
+ _this.focus( $( this ).parent( 'li' ).attr( 'data-path' ) );
+ }
+ });
+
+ // Focus on left button mousedown from tab.
+ $( '#tab-list-active-files li.tab-item>a.label' )
+ .live( 'mousedown', function( e ) {
+ if( e.which == 1 ) {
+ e.stopPropagation();
+ _this.focus( $( this ).parent( 'li' ).attr( 'data-path' ) );
+ }
+ });
+
+ // Remove from list.
+ $( '#list-active-files a>span' )
+ .live( 'click', function( e ) {
+ e.stopPropagation();
+ _this.remove( $( this )
+ .parent( 'a' )
+ .parent( 'li' )
+ .attr( 'data-path' ) );
+ });
+
+ // Remove from dropdown.
+ $( '#dropdown-list-active-files a>span' )
+ .live( 'click', function( e ) {
+ e.stopPropagation();
+ /* Get the active editor before removing anything. Remove the
+ * tab, then put back the focus on the previously active
+ * editor if it was not removed. */
+ var activePath = _this.getPath();
+ var pathToRemove = $( this ).parents( 'li' ).attr( 'data-path' );
+ _this.remove( pathToRemove );
+ if( activePath !== null && activePath !== pathToRemove ) {
+ _this.focus( activePath );
+ }
+ _this.updateTabDropdownVisibility();
+ });
+
+ // Remove from tab.
+ $( '#tab-list-active-files a.close' )
+ .live( 'click', function( e ) {
+ e.stopPropagation();
+ /* Get the active editor before removing anything. Remove the
+ * tab, then put back the focus on the previously active
+ * editor if it was not removed. */
+ var activePath = _this.getPath();
+ var pathToRemove = $( this ).parent( 'li' ).attr( 'data-path' );
+ _this.remove( pathToRemove );
+ if( activePath !== null && activePath !== pathToRemove ) {
+ _this.focus( activePath );
+ }
+ _this.updateTabDropdownVisibility();
+ });
+
+ // Remove from middle button click on dropdown.
+ $( '#dropdown-list-active-files li' )
+ .live( 'mouseup', function( e ) {
+ if( e.which == 2 ) {
+ e.stopPropagation();
+ /* Get the active editor before removing anything. Remove the
+ * tab, then put back the focus on the previously active
+ * editor if it was not removed. */
+ var activePath = _this.getPath();
+ var pathToRemove = $( this ).attr( 'data-path' );
+ _this.remove( pathToRemove );
+ if( activePath !== null && activePath !== pathToRemove ) {
+ _this.focus( activePath );
+ }
+ _this.updateTabDropdownVisibility();
+ }
+ });
+
+ // Remove from middle button click on tab.
+ $( '.tab-item' )
+ .live( 'mouseup', function( e ) {
+ if( e.which == 2 ) {
+ e.stopPropagation();
+ /* Get the active editor before removing anything. Remove the
+ * tab, then put back the focus on the previously active
+ * editor if it was not removed. */
+ var activePath = _this.getPath();
+ var pathToRemove = $( this ).attr( 'data-path' );
+ _this.remove( pathToRemove );
+ if( activePath !== null && activePath !== pathToRemove ) {
+ _this.focus( activePath );
+ }
+ _this.updateTabDropdownVisibility();
+ }
+ });
+
+ // Make list sortable
+ $( '#list-active-files' )
+ .sortable( {
+ placeholder: 'active-sort-placeholder',
+ tolerance: 'intersect',
+ start: function( e, ui ) {
+ ui.placeholder.height( ui.item.height() );
+ }
+ });
+
+ // Make dropdown sortable.
+ $( '#dropdown-list-active-files' )
+ .sortable( {
+ axis: 'y',
+ tolerance: 'pointer',
+ start: function( e, ui ) {
+ ui.placeholder.height( ui.item.height() );
+ }
+ });
+
+ // Make tabs sortable.
+ $( '#tab-list-active-files' )
+ .sortable( {
+ items: '> li',
+ axis: 'x',
+ tolerance: 'pointer',
+ containment: 'parent',
+ start: function( e, ui ) {
+ ui.placeholder.css( 'background', 'transparent' );
+ ui.helper.css( 'width', '200px' );
+ },
+ stop: function( e, ui ) {
+ // Reset css
+ ui.item.css( 'z-index', '' )
+ ui.item.css( 'position', '' )
+ }
+ });
+ /* Woaw, so tricky! At initialization, the tab-list is empty, so
+ * it is not marked as float so it is not detected as an horizontal
+ * list by the sortable plugin. Workaround is to mark it as
+ * floating at initialization time. See bug report
+ * http://bugs.jqueryui.com/ticket/6702. */
+ $( '#tab-list-active-files' ).data( 'sortable' ).floating = true;
+
+ // Open saved-state active files on load
+ $.get( _this.controller + '?action=list', function( data ) {
+ var listResponse = codiad.jsend.parse( data );
+ if( listResponse !== null ) {
+ $.each( listResponse, function( index, data ) {
+
+ codiad.active.positions[`${data.path}`] = JSON.parse( data.position );
+ codiad.filemanager.openFile( data.path, data.focused );
+ });
+ }
+ });
+
+ // Prompt if a user tries to close window without saving all filess
+ window.onbeforeunload = function( e ) {
+
+ codiad.active.uploadPositions();
+ if( $( '#list-active-files li.changed' )
+ .length > 0 ) {
+ var e = e || window.event;
+ var errMsg = i18n( 'You have unsaved files.' );
+
+ // For IE and Firefox prior to version 4
+ if( e ) {
+ e.returnValue = errMsg;
+ }
+
+ // For rest
+ return errMsg;
+ }
+ };
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Drafts
+ //////////////////////////////////////////////////////////////////
+
+ checkDraft: function( path ) {
+ var draft = localStorage.getItem( path );
+ if( draft !== null ) {
+ return draft;
+ } else {
+ return false;
+ }
+ },
+
+ removeDraft: function( path ) {
+ localStorage.removeItem( path );
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Get active editor path
+ //////////////////////////////////////////////////////////////////
+
+ getPath: function() {
+ try {
+ return codiad.editor.getActive()
+ .getSession()
+ .path;
+ } catch ( e ) {
+ return null;
+ }
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Check if opened by another user
+ //////////////////////////////////////////////////////////////////
+
+ check: function( path ) {
+ $.get( this.controller + '?action=check&path=' + encodeURIComponent( path ),
+
+ function( data ) {
+ var checkResponse = codiad.jsend.parse( data );
+ });
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Add newly opened file to list
+ //////////////////////////////////////////////////////////////////
+
+ add: function( path, session, focus ) {
+ if( focus === undefined ) {
+ focus = true;
+ }
+
+ var listThumb = this.createListThumb( path );
+ session.listThumb = listThumb;
+ $( '#list-active-files' ).append( listThumb );
+
+ /* If the tab list would overflow with the new tab. Move the
+ * first tab to dropdown, then add a new tab. */
+ if( this.isTabListOverflowed( true ) ) {
+ var tab = $( '#tab-list-active-files li:first-child' );
+ this.moveTabToDropdownMenu( tab );
+ }
+
+ var tabThumb = this.createTabThumb( path );
+ $( '#tab-list-active-files' ).append( tabThumb );
+ session.tabThumb = tabThumb;
+
+ this.updateTabDropdownVisibility();
+
+ $.get( this.controller + '?action=add&path=' + encodeURIComponent( path ) );
+
+ if( focus ) {
+ this.focus( path );
+ }
+
+ // Mark draft as changed
+ if( this.checkDraft( path ) ) {
+ this.markChanged( path );
+ }
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Focus on opened file
+ //////////////////////////////////////////////////////////////////
+
+ focus: function( path, moveToTabList ) {
+ if( moveToTabList === undefined ) {
+ moveToTabList = true;
+ }
+
+ /* Notify listeners. */
+ amplify.publish( 'active.onWillFocus', path );
+
+ this.highlightEntry( path, moveToTabList );
+
+ if( path != this.getPath() ) {
+
+ let _this = this;
+ codiad.editor.setSession( this.sessions[path] );
+ this.history.push( path );
+ $.get( this.controller, {
+ 'action': 'focused',
+ 'path': path
+ }, function() {
+
+ if( !( _this.positions[`${path}`] === undefined ) ) {
+
+ _this.setPosition( _this.positions[`${path}`] );
+ }
+ });
+ }
+
+ /* Check for users registered on the file. */
+ this.check( path );
+
+ /* Notify listeners. */
+ amplify.publish( 'active.onFocus', path );
+ },
+
+ highlightEntry: function( path, moveToTabList ) {
+ if( moveToTabList === undefined ) {
+ moveToTabList = true;
+ }
+
+ $( '#list-active-files li' )
+ .removeClass( 'active' );
+
+ $( '#tab-list-active-files li' )
+ .removeClass( 'active' );
+
+ $( '#dropdown-list-active-files li' )
+ .removeClass( 'active' );
+
+ var session = this.sessions[path];
+
+ if( $( '#dropdown-list-active-files' ).has( session.tabThumb ).length > 0 ) {
+ if( moveToTabList ) {
+ /* Get the menu item as a tab, and put the last tab in
+ * dropdown. */
+ var menuItem = session.tabThumb;
+ this.moveDropdownMenuItemToTab( menuItem, true );
+
+ var tab = $( '#tab-list-active-files li:last-child' );
+ this.moveTabToDropdownMenu( tab );
+ } else {
+ /* Show the dropdown menu if needed */
+ this.showTabDropdownMenu();
+ }
+ } else if( this.history.length > 0 ) {
+ var prevPath = this.history[this.history.length - 1];
+ var prevSession = this.sessions[prevPath];
+ if( $( '#dropdown-list-active-files' ).has( prevSession.tabThumb ).length > 0 ) {
+ /* Hide the dropdown menu if needed */
+ this.hideTabDropdownMenu();
+ }
+ }
+
+ session.tabThumb.addClass( 'active' );
+ session.listThumb.addClass( 'active' );
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Mark changed
+ //////////////////////////////////////////////////////////////////
+
+ markChanged: function( path ) {
+ this.sessions[path].listThumb.addClass( 'changed' );
+ this.sessions[path].tabThumb.addClass( 'changed' );
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Save active editor
+ //////////////////////////////////////////////////////////////////
+
+ save: function( path, alerts = true ) {
+ /* Notify listeners. */
+ amplify.publish( 'active.onSave', path );
+
+ var _this = this;
+ if( ( path && !this.isOpen( path ) ) || ( !path && !codiad.editor.getActive() ) ) {
+ codiad.message.error( i18n( 'No Open Files to save' ) );
+ return;
+ }
+ var session;
+ if( path ) session = this.sessions[path];
+ else session = codiad.editor.getActive()
+ .getSession();
+ var content = session.getValue();
+ var path = session.path;
+ var handleSuccess = function( mtime ) {
+ var session = codiad.active.sessions[path];
+ if( typeof session != 'undefined' ) {
+ session.untainted = newContent;
+ session.serverMTime = mtime;
+ if( session.listThumb ) session.listThumb.removeClass( 'changed' );
+ if( session.tabThumb ) session.tabThumb.removeClass( 'changed' );
+ }
+ _this.removeDraft( path );
+ }
+ // Replicate the current content so as to avoid
+ // discrepancies due to content changes during
+ // computation of diff
+
+ var newContent = content.slice( 0 );
+ if( session.serverMTime && session.untainted ) {
+ codiad.workerManager.addTask( {
+ taskType: 'diff',
+ id: path,
+ original: session.untainted,
+ changed: newContent
+ }, function( success, patch ) {
+ if( success ) {
+ codiad.filemanager.savePatch( path, patch, session.serverMTime, {
+ success: handleSuccess
+ }, alerts );
+ } else {
+ codiad.filemanager.saveFile( path, newContent, {
+ success: handleSuccess
+ }, alerts );
+ }
+ }, this );
+ } else {
+ codiad.filemanager.saveFile( path, newContent, {
+ success: handleSuccess
+ }, alert );
+ }
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Save all files
+ //////////////////////////////////////////////////////////////////
+
+ saveAll: function() {
+ var _this = this;
+ for( var session in _this.sessions ) {
+ if( _this.sessions[session].listThumb.hasClass( 'changed' ) ) {
+ codiad.active.save( session );
+ }
+ }
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Remove file
+ //////////////////////////////////////////////////////////////////
+
+ remove: function( path ) {
+ if( !this.isOpen( path ) ) return;
+ var session = this.sessions[path];
+ var closeFile = true;
+ if( session.listThumb.hasClass( 'changed' ) ) {
+ codiad.modal.load( 450, 'components/active/dialog.php?action=confirm&path=' + encodeURIComponent( path ) );
+ closeFile = false;
+ }
+ if( closeFile ) {
+ this.close( path );
+ }
+ },
+
+ removeAll: function( discard ) {
+ discard = discard || false;
+ /* Notify listeners. */
+ amplify.publish( 'active.onRemoveAll' );
+
+ var _this = this;
+ var changed = false;
+
+ var opentabs = new Array();
+ for( var session in _this.sessions ) {
+ opentabs[session] = session;
+ if( _this.sessions[session].listThumb.hasClass( 'changed' ) ) {
+ changed = true;
+ }
+ }
+ if( changed && !discard ) {
+ codiad.modal.load( 450, 'components/active/dialog.php?action=confirmAll' );
+ return;
+ }
+
+ for( var tab in opentabs ) {
+ var session = this.sessions[tab];
+
+ session.tabThumb.remove();
+ _this.updateTabDropdownVisibility();
+
+ session.listThumb.remove();
+
+ /* Remove closed path from history */
+ var history = [];
+ $.each( this.history, function( index ) {
+ if( this != tab ) history.push( this );
+ })
+ this.history = history
+
+ delete this.sessions[tab];
+ this.removeDraft( tab );
+ }
+ codiad.editor.exterminate();
+ $( '#list-active-files' ).html( '' );
+ $.get( this.controller + '?action=removeall' );
+ },
+
+ close: function( path ) {
+ /* Notify listeners. */
+ amplify.publish( 'active.onClose', path );
+
+ var _this = this;
+ var session = this.sessions[path];
+
+ /* Animate only if the tabThumb if a tab, not a dropdown item. */
+ if( session.tabThumb.hasClass( 'tab-item' ) ) {
+ session.tabThumb.css( {
+ 'z-index': 1
+ });
+ session.tabThumb.animate( {
+ top: $( '#editor-top-bar' ).height() + 'px'
+ }, 300, function() {
+ session.tabThumb.remove();
+ _this.updateTabDropdownVisibility();
+ });
+ } else {
+ session.tabThumb.remove();
+ _this.updateTabDropdownVisibility();
+ }
+
+ session.listThumb.remove();
+
+ /* Remove closed path from history */
+ var history = [];
+ $.each( this.history, function( index ) {
+ if( this != path ) history.push( this );
+ })
+ this.history = history
+
+ /* Select all the tab tumbs except the one which is to be removed. */
+ var tabThumbs = $( '#tab-list-active-files li[data-path!="' + path + '"]' );
+
+ if( tabThumbs.length == 0 ) {
+ codiad.editor.exterminate();
+ } else {
+
+ var nextPath = '';
+ if( this.history.length > 0 ) {
+ nextPath = this.history[this.history.length - 1];
+ } else {
+ nextPath = $( tabThumbs[0] ).attr( 'data-path' );
+ }
+ var nextSession = this.sessions[nextPath];
+ codiad.editor.removeSession( session, nextSession );
+
+ this.focus( nextPath );
+ }
+ delete this.sessions[path];
+ $.get( this.controller + '?action=remove&path=' + encodeURIComponent( path ) );
+ this.removeDraft( path );
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Process rename
+ //////////////////////////////////////////////////////////////////
+
+ rename: function( oldPath, newPath ) {
+ var switchSessions = function( oldPath, newPath ) {
+ var tabThumb = this.sessions[oldPath].tabThumb;
+ tabThumb.attr( 'data-path', newPath );
+ var title = newPath;
+ if( codiad.project.isAbsPath( newPath ) ) {
+ title = newPath.substring( 1 );
+ }
+ tabThumb.find( '.label' )
+ .text( title );
+ this.sessions[newPath] = this.sessions[oldPath];
+ this.sessions[newPath].path = newPath;
+ delete this.sessions[oldPath];
+ //Rename history
+ for( var i = 0; i < this.history.length; i++ ) {
+ if( this.history[i] === oldPath ) {
+ this.history[i] = newPath;
+ }
+ }
+ };
+ if( this.sessions[oldPath] ) {
+ // A file was renamed
+ switchSessions.apply( this, [oldPath, newPath] );
+ // pass new sessions instance to setactive
+ for( var k = 0; k < codiad.editor.instances.length; k++ ) {
+ if( codiad.editor.instances[k].getSession().path === newPath ) {
+ codiad.editor.setActive( codiad.editor.instances[k] );
+ }
+ }
+
+ var newSession = this.sessions[newPath];
+
+ // Change Editor Mode
+ var mode = codiad.editor.selectMode( newPath );
+
+ // handle async mode change
+ var fn = function() {
+ codiad.editor.setModeDisplay( newSession );
+ newSession.removeListener( 'changeMode', fn );
+ }
+
+ newSession.on( "changeMode", fn );
+ newSession.setMode( mode.mode );
+ } else {
+ // A folder was renamed
+ var newKey;
+ for( var key in this.sessions ) {
+ newKey = key.replace( oldPath, newPath );
+ if( newKey !== key ) {
+ switchSessions.apply( this, [key, newKey] );
+ }
+ }
+ }
+ $.get( this.controller + '?action=rename&old_path=' + encodeURIComponent( oldPath ) + '&new_path=' + encodeURIComponent( newPath ), function() {
+ /* Notify listeners. */
+ amplify.publish( 'active.onRename', {
+ "oldPath": oldPath,
+ "newPath": newPath
+ });
+ });
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Open in Browser
+ //////////////////////////////////////////////////////////////////
+
+ openInBrowser: function() {
+ var path = this.getPath();
+ if( path ) {
+ codiad.filemanager.openInBrowser( path );
+ } else {
+ codiad.message.error( 'No Open Files' );
+ }
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Get Selected Text
+ //////////////////////////////////////////////////////////////////
+
+ getSelectedText: function() {
+ var path = this.getPath();
+ var session = this.sessions[path];
+
+ if( path && this.isOpen( path ) ) {
+ return session.getTextRange(
+ codiad.editor.getActive()
+ .getSelectionRange() );
+ } else {
+ codiad.message.error( i18n( 'No Open Files or Selected Text' ) );
+ }
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Insert Text
+ //////////////////////////////////////////////////////////////////
+
+ insertText: function( val ) {
+ codiad.editor.getActive()
+ .insert( val );
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Goto Line
+ //////////////////////////////////////////////////////////////////
+
+ gotoLine: function( line ) {
+ codiad.editor.getActive()
+ .gotoLine( line, 0, true );
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Move Up (Key Combo)
+ //////////////////////////////////////////////////////////////////
+
+ move: function( dir ) {
+
+ var num = $( '#tab-list-active-files li' ).length;
+ if( num === 0 ) return;
+
+ var newActive = null;
+ var active = null;
+
+ if( dir == 'up' ) {
+
+ // If active is in the tab list
+ active = $( '#tab-list-active-files li.active' );
+ if( active.length > 0 ) {
+ // Previous or rotate to the end
+ newActive = active.prev( 'li' );
+ if( newActive.length === 0 ) {
+ newActive = $( '#dropdown-list-active-files li:last-child' )
+ if( newActive.length === 0 ) {
+ newActive = $( '#tab-list-active-files li:last-child' )
+ }
+ }
+ }
+
+ // If active is in the dropdown list
+ active = $( '#dropdown-list-active-files li.active' );
+ if( active.length > 0 ) {
+ // Previous
+ newActive = active.prev( 'li' );
+ if( newActive.length === 0 ) {
+ newActive = $( '#tab-list-active-files li:last-child' )
+ }
+ }
+
+ } else {
+
+ // If active is in the tab list
+ active = $( '#tab-list-active-files li.active' );
+ if( active.length > 0 ) {
+ // Next or rotate to the beginning
+ newActive = active.next( 'li' );
+ if( newActive.length === 0 ) {
+ newActive = $( '#dropdown-list-active-files li:first-child' );
+ if( newActive.length === 0 ) {
+ newActive = $( '#tab-list-active-files li:first-child' )
+ }
+ }
+ }
+
+ // If active is in the dropdown list
+ active = $( '#dropdown-list-active-files li.active' );
+ if( active.length > 0 ) {
+ // Next or rotate to the beginning
+ newActive = active.next( 'li' );
+ if( newActive.length === 0 ) {
+ newActive = $( '#tab-list-active-files li:first-child' )
+ }
+ }
+
+ }
+
+ if( newActive ) this.focus( newActive.attr( 'data-path' ), false );
+ },
+
+ //////////////////////////////////////////////////////////////////
+ // Dropdown Menu
+ //////////////////////////////////////////////////////////////////
+
+ initTabDropdownMenu: function() {
+ var _this = this;
+
+ var menu = $( '#dropdown-list-active-files' );
+ var button = $( '#tab-dropdown-button' );
+ var closebutton = $( '#tab-close-button' );
+
+ menu.appendTo( $( 'body' ) );
+
+ button.click( function( e ) {
+ e.stopPropagation();
+ _this.toggleTabDropdownMenu();
+ });
+
+ closebutton.click( function( e ) {
+ e.stopPropagation();
+ _this.removeAll();
+ });
+ },
+
+ showTabDropdownMenu: function() {
+ var menu = $( '#dropdown-list-active-files' );
+ if( !menu.is( ':visible' ) ) this.toggleTabDropdownMenu();
+ },
+
+ hideTabDropdownMenu: function() {
+ var menu = $( '#dropdown-list-active-files' );
+ if( menu.is( ':visible' ) ) this.toggleTabDropdownMenu();
+ },
+
+ toggleTabDropdownMenu: function() {
+ var _this = this;
+ var menu = $( '#dropdown-list-active-files' );
+
+ menu.css( {
+ top: $( "#editor-top-bar" ).height() + 'px',
+ right: '20px',
+ width: '200px'
+ });
+
+ menu.slideToggle( 'fast' );
+
+ if( menu.is( ':visible' ) ) {
+ // handle click-out autoclosing
+ var fn = function() {
+ menu.hide();
+ $( window ).off( 'click', fn )
+ }
+ $( window ).on( 'click', fn );
+ }
+ },
+
+ moveTabToDropdownMenu: function( tab, prepend ) {
+ if( prepend === undefined ) {
+ prepend = false;
+ }
+
+ tab.remove();
+ path = tab.attr( 'data-path' );
+
+ var tabThumb = this.createMenuItemThumb( path );
+ if( prepend ) $( '#dropdown-list-active-files' ).prepend( tabThumb );
+ else $( '#dropdown-list-active-files' ).append( tabThumb );
+
+ if( tab.hasClass( "changed" ) ) {
+ tabThumb.addClass( "changed" );
+ }
+
+ if( tab.hasClass( "active" ) ) {
+ tabThumb.addClass( "active" );
+ }
+
+ this.sessions[path].tabThumb = tabThumb;
+ },
+
+ moveDropdownMenuItemToTab: function( menuItem, prepend ) {
+ if( prepend === undefined ) {
+ prepend = false;
+ }
+
+ menuItem.remove();
+ path = menuItem.attr( 'data-path' );
+
+ var tabThumb = this.createTabThumb( path );
+ if( prepend ) $( '#tab-list-active-files' ).prepend( tabThumb );
+ else $( '#tab-list-active-files' ).append( tabThumb );
+
+ if( menuItem.hasClass( "changed" ) ) {
+ tabThumb.addClass( "changed" );
+ }
+
+ if( menuItem.hasClass( "active" ) ) {
+ tabThumb.addClass( "active" );
+ }
+
+ this.sessions[path].tabThumb = tabThumb;
+ },
+
+ isTabListOverflowed: function( includeFictiveTab ) {
+ if( includeFictiveTab === undefined ) {
+ includeFictiveTab = false;
+ }
+
+ var tabs = $( '#tab-list-active-files li' );
+ var count = tabs.length
+ if( includeFictiveTab ) count += 1;
+ if( count <= 1 ) return false;
+
+ var width = 0;
+ tabs.each( function( index ) {
+ width += $( this ).outerWidth( true );
+ })
+ if( includeFictiveTab ) {
+ width += $( tabs[tabs.length - 1] ).outerWidth( true );
+ }
+
+ /* If we subtract the width of the left side bar, of the right side
+ * bar handle and of the tab dropdown handle to the window width,
+ * do we have enough room for the tab list? Its kind of complicated
+ * to handle all the offsets, so afterwards we add a fixed offset
+ * just t be sure. */
+ var lsbarWidth = $( ".sidebar-handle" ).width();
+ if( codiad.sidebars.isLeftSidebarOpen ) {
+ lsbarWidth = $( "#sb-left" ).width();
+ }
+
+ var rsbarWidth = $( ".sidebar-handle" ).width();
+ if( codiad.sidebars.isRightSidebarOpen ) {
+ rsbarWidth = $( "#sb-right" ).width();
+ }
+
+ var tabListWidth = $( "#tab-list-active-files" ).width();
+ var dropdownWidth = $( '#tab-dropdown' ).width();
+ var closeWidth = $( '#tab-close' ).width();
+ var room = window.innerWidth - lsbarWidth - rsbarWidth - dropdownWidth - closeWidth - width - 30;
+ return ( room < 0 );
+ },
+
+ updateTabDropdownVisibility: function() {
+ while( this.isTabListOverflowed() ) {
+ var tab = $( '#tab-list-active-files li:last-child' );
+ if( tab.length == 1 ) this.moveTabToDropdownMenu( tab, true );
+ else break;
+ }
+
+ while( !this.isTabListOverflowed( true ) ) {
+ var menuItem = $( '#dropdown-list-active-files li:first-child' );
+ if( menuItem.length == 1 ) this.moveDropdownMenuItemToTab( menuItem );
+ else break;
+ }
+
+ if( $( '#dropdown-list-active-files li' ).length > 0 ) {
+ $( '#tab-dropdown' ).show();
+ } else {
+ $( '#tab-dropdown' ).hide();
+ // Be sure to hide the menu if it is opened.
+ $( '#dropdown-list-active-files' ).hide();
+ }
+ if( $( '#tab-list-active-files li' ).length > 1 ) {
+ $( '#tab-close' ).show();
+ } else {
+ $( '#tab-close' ).hide();
+ }
+ },
uploadPositions: function() {
- $.ajax({
+ $.ajax( {
type: 'POST',
url: codiad.active.controller + '?action=save_positions',
data: {
positions: ( JSON.stringify( codiad.active.positions ) )
},
- success: function( data ) {
- },
+ success: function( data ) {},
});
},
@@ -1025,7 +1033,7 @@
this.positions[path] = position;
},
- getPosition: function( path=null, live=false ) {
+ getPosition: function( path = null, live = false ) {
if( path === null ) {
@@ -1036,7 +1044,7 @@
let position = null;
let session = codiad.active.sessions[path];
- for( let i = codiad.editor.instances.length;i--; ) {
+ for( let i = codiad.editor.instances.length; i--; ) {
if( codiad.editor.instances[i].getSession().path == path ) {
@@ -1049,7 +1057,7 @@
position = editor.getCursorPosition();
} else {
- if( ! this.positions[path] === undefined ) {
+ if( !this.positions[path] === undefined ) {
position = this.positions[path].position;
}
@@ -1067,7 +1075,7 @@
return position;
},
- setPosition: function( cursor=null ) {
+ setPosition: function( cursor = null ) {
let editor = codiad.editor.getActive();
@@ -1079,36 +1087,36 @@
editor.scrollToLine( cursor.row, true, true, function() {});
editor.moveCursorTo( cursor.row, cursor.column );
},
- //////////////////////////////////////////////////////////////////
- // Factory
- //////////////////////////////////////////////////////////////////
-
- splitDirectoryAndFileName: function(path) {
- var index = path.lastIndexOf('/');
- return {
- fileName: path.substring(index + 1),
- directory: (path.indexOf('/') == 0)? path.substring(1, index + 1):path.substring(0, index + 1)
- }
- },
-
- createListThumb: function(path) {
- return $('
' + path + '
');
- },
-
- createTabThumb: function(path) {
- split = this.splitDirectoryAndFileName(path);
- return $(''
- + split.directory + '' + split.fileName + ''
- + 'x');
- },
-
- createMenuItemThumb: function(path) {
- split = this.splitDirectoryAndFileName(path);
- return $(''
- + split.directory + '' + split.fileName + ''
- + '
');
- },
-
- };
-
-})(this, jQuery);
+ //////////////////////////////////////////////////////////////////
+ // Factory
+ //////////////////////////////////////////////////////////////////
+
+ splitDirectoryAndFileName: function( path ) {
+ var index = path.lastIndexOf( '/' );
+ return {
+ fileName: path.substring( index + 1 ),
+ directory: ( path.indexOf( '/' ) == 0 ) ? path.substring( 1, index + 1 ) : path.substring( 0, index + 1 )
+ }
+ },
+
+ createListThumb: function( path ) {
+ return $( '' + path + '
' );
+ },
+
+ createTabThumb: function( path ) {
+ split = this.splitDirectoryAndFileName( path );
+ return $( '' +
+ split.directory + '' + split.fileName + '' +
+ 'x' );
+ },
+
+ createMenuItemThumb: function( path ) {
+ split = this.splitDirectoryAndFileName( path );
+ return $( '' +
+ split.directory + '' + split.fileName + '' +
+ '
' );
+ },
+
+ };
+
+})( this, jQuery );
diff --git a/components/editor/init.js b/components/editor/init.js
index aa1a700..8f3514b 100755
--- a/components/editor/init.js
+++ b/components/editor/init.js
@@ -1,1603 +1,1606 @@
-/*
- * Copyright (c) Codiad & Kent Safranski (codiad.com), distributed
- * as-is and without warranty under the MIT License. See
- * [root]/license.txt for more. This information must remain intact.
- */
-
-(function(global, $) {
-
- // Classes from Ace
- var VirtualRenderer = ace.require('ace/virtual_renderer').VirtualRenderer;
- var Editor = ace.require('ace/editor').Editor;
- var EditSession = ace.require('ace/edit_session').EditSession;
- var ModeList = ace.require("ace/ext/modelist");
- var UndoManager = ace.require("ace/undomanager").UndoManager;
-
- // Editor modes that have been loaded
- var editorModes = {};
-
- var codiad = global.codiad;
- codiad._cursorPoll = null;
-
- var separatorWidth = 3;
-
- $(function(){
- codiad.editor.init();
- });
-
- function SplitContainer(root, children, splitType) {
- var _this = this;
-
- this.root = root;
- this.splitType = splitType;
- this.childContainers = {};
- this.childElements = {};
- this.splitProp = 0.5;
-
- this.setChild(0, children[0]);
- this.setChild(1, children[1]);
-
- this.splitter = $('')
- .addClass('splitter')
- .appendTo(root)
- .draggable({
- axis: (splitType === 'horizontal' ? 'x' : 'y'),
- drag: function(e, ui){
- if (_this.splitType === 'horizontal') {
- var w1, w2;
- w1 = ui.position.left - separatorWidth/2;
- w2 = _this.root.width() - ui.position.left
- - separatorWidth/2;
- _this.splitProp = w1 / _this.root.width();
- _this.childElements[0]
- .width(w1)
- .trigger('h-resize', [true, true]);
- _this.childElements[1]
- .width(w2)
- .css('left', w1 + separatorWidth + 'px')
- .trigger('h-resize', [true, true]);
- _this.splitProp = ui.position.left / _this.root.width();
- } else {
- var h1, h2;
- h1 = ui.position.top - separatorWidth/2;
- h2 = _this.root.width() - ui.position.top
- - separatorWidth/2;
- _this.splitProp = h1 / _this.root.height();
- _this.childElements[0]
- .height(h1)
- .trigger('v-resize', [true, true]);
- _this.childElements[1]
- .height(h2)
- .css('top', h1 + separatorWidth + 'px')
- .trigger('v-resize', [true, true]);
- }
- }
- });
-
- if (splitType === 'horizontal') {
- this.splitter
- .addClass('h-splitter')
- .width(separatorWidth)
- .height(root.height());
- } else if (splitType === 'vertical') {
- this.splitter
- .addClass('v-splitter')
- .height(separatorWidth)
- .width(root.width());
- }
-
- this.root.on('h-resize', function(e, percolateUp, percolateDown){
- e.stopPropagation();
- if (_this.splitType === 'horizontal') {
- var w1, w2;
- w1 = _this.root.width() * _this.splitProp
- - separatorWidth / 2;
- w2 = _this.root.width() * (1 - _this.splitProp)
- - separatorWidth / 2;
- _this.childElements[0]
- .width(w1);
- _this.childElements[1]
- .width(w2)
- .css('left', w1 + separatorWidth);
- _this.splitter.css('left', w1);
- } else if (_this.splitType === 'vertical') {
- var w = _this.root.width();
- _this.childElements[0]
- .width(w);
- _this.childElements[1]
- .width(w);
- _this.splitter.width(w);
- }
- if (percolateUp) {
- _this.root.parent('.editor-wrapper')
- .trigger('h-resize', [true ,false]);
- }
- if (! percolateDown) return;
- if (_this.childContainers[0]) {
- _this.childContainers[0].root
- .trigger('h-resize', [false, true]);
- } else if (_this.childContainers[1]) {
- _this.childContainers[1].root
- .trigger('h-resize', [false, true]);
- }
- });
-
- this.root.on('v-resize', function(e, percolateUp, percolateDown){
- e.stopPropagation();
- if (_this.splitType === 'horizontal') {
- var h = _this.root.height();
- _this.childElements[0]
- .height(h);
- _this.childElements[1]
- .height(h);
- _this.splitter.height(h);
- } else if (_this.splitType === 'vertical') {
- var h1 = _this.root.height() * _this.splitProp
- - separatorWidth / 2;
- var h2 = _this.root.height() * (1 - _this.splitProp)
- - separatorWidth / 2;
- _this.childElements[0]
- .height(h1);
- _this.childElements[1]
- .height(h2)
- .css('top', h1+separatorWidth);
- _this.splitter.css('top', h1);
- }
- if (percolateUp) {
- _this.root.parent('.editor-wrapper')
- .trigger('v-resize', [true ,false]);
- }
- if (! percolateDown) return;
- if (_this.childContainers[0]) {
- _this.childContainers[0].root
- .trigger('v-resize', [false, true]);
- } else if (_this.childContainers[1]) {
- _this.childContainers[1].root
- .trigger('v-resize', [false, true]);
- }
- });
-
- this.root
- .trigger('h-resize', [false, false])
- .trigger('v-resize', [false, false]);
- }
-
- SplitContainer.prototype = {
- setChild: function(idx, el){
-
- if (el instanceof SplitContainer) {
- this.childElements[idx] = el.root;
- this.childContainers[idx] = el;
- el.idx = idx;
- } else {
- this.childElements[idx] = el;
- }
-
- this.childElements[idx].appendTo(this.root);
- this.cssInit(this.childElements[idx], idx);
- },
- cssInit: function(el, idx){
- var props = {};
- var h1, h2, w1, w2, rh, rw;
-
- rh = this.root.height();
- rw = this.root.width();
-
- if (this.splitType === 'horizontal') {
-
- w1 = rw * this.splitProp - separatorWidth / 2;
- w2 = rw * (1 - this.splitProp) - separatorWidth / 2;
-
- if (idx === 0) {
- props = {
- left: 0,
- width: w1,
- height: rh,
- top: 0
- };
- } else {
- props = {
- left: w1 + separatorWidth,
- width: w2,
- height: rh,
- top: 0
- };
- }
-
- } else if (this.splitType === 'vertical') {
-
- h1 = rh * this.splitProp - separatorWidth / 2;
- h2 = rh * (1 - this.splitProp) - separatorWidth / 2;
-
- if (idx === 0) {
- props = {
- top: 0,
- height: h1,
- width: rw,
- left: 0
- };
- } else {
- props = {
- top: h1 + separatorWidth,
- height: h2,
- width: rw,
- left: 0
- };
- }
-
- }
-
- el.css(props);
- }
- };
-
- //////////////////////////////////////////////////////////////////
- //
- // Editor Component for Codiad
- // ---------------------------
- // Manage the lifecycle of Editor instances
- //
- //////////////////////////////////////////////////////////////////
-
- codiad.editor = {
-
- /// Editor instances - One instance corresponds to an editor
- /// pane in the user interface. Different EditSessions
- /// (ace/edit_session)
- instances: [],
-
- /// Currently focussed editor
- activeInstance: null,
-
- // Settings for Editor instances
- settings: {
- autocomplete: false,
- theme: 'twilight',
- fontSize: '13px',
- printMargin: false,
- printMarginColumn: 80,
- highlightLine: true,
- indentGuides: true,
- wrapMode: false,
- softTabs: false,
- persistentModal: true,
- rightSidebarTrigger: false,
- fileManagerTrigger: false,
- tabSize: 4
- },
-
- multi_line: false,
-
- rootContainer: null,
-
- fileExtensionTextMode: {},
-
- init: function(){
- this.createSplitMenu();
- this.createModeMenu();
-
- var er = $('#editor-region');
-
- er.on('h-resize-init', function(){
- $('#editor-region > .editor-wrapper')
- .width($(this).width())
- .trigger('h-resize');
-
- }).on('v-resize-init', function(){
- $('#editor-region > .editor-wrapper')
- .height($(this).height())
- .trigger('v-resize');
- });
-
- $("#root-editor-wrapper").live("contextmenu", function( e ) {
-
- // Context Menu
- e.preventDefault();
- _this = codiad.editor
-
- if( _this.getActive() ) {
-
- let path = codiad.active.getPath();
- $(e.target).attr('data-path', path);
- codiad.filemanager.contextMenuShow( e, path, 'editor', 'editor');
- $(this).addClass('context-menu-active');
- }
- });
-
- $(window).resize(function(){
- $('#editor-region')
- .trigger('h-resize-init')
- .trigger('v-resize-init');
- });
-
- //Load settings when initially starting up that way the first editor
- //we open doesn't have the default settings.
- this.getSettings();
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Retrieve editor settings from database
- //
- //////////////////////////////////////////////////////////////////
-
- getSettings: async function() {
-
- let boolVal = null;
- let _this = this;
- let options = [
- 'editor.fontSize',
- 'editor.overScroll',
- 'editor.printMarginColumn',
- 'editor.tabSize',
- 'editor.theme',
- ];
- let bool_options = [
- 'editor.autocomplete',
- 'settings.autosave',
- 'editor.printMargin',
- 'editor.highlightLine',
- 'editor.indentGuides',
- 'editor.wrapMode',
- 'editor.rightSidebarTrigger',
- 'editor.fileManagerTrigger',
- 'editor.softTabs',
- 'editor.persistentModal',
- ];
-
- let user_settings = await codiad.settings.get_options();
-
- //console.log( user_settings );
-
- $.each( options, function( idx, key ) {
-
- let localValue = user_settings['codiad.' + key];
- if ( localValue != null ) {
-
- _this.settings[key.split('.').pop()] = localValue;
- }
- });
-
- $.each( bool_options, async function(idx, key) {
-
- let localValue = user_settings['codiad.' + key];
- if ( localValue != null ) {
-
- _this.settings[key.split('.').pop()] = (localValue == 'true');
- }
- });
- },
-
- /////////////////////////////////////////////////////////////////
- //
- // Apply configuration settings
- //
- // Parameters:
- // i - {Editor}
- //
- /////////////////////////////////////////////////////////////////
-
- applySettings: function(i) {
- // Check user-specified settings
- this.getSettings();
-
- // Apply the current configuration settings:
- i.setTheme('ace/theme/' + this.settings.theme);
- i.setFontSize(this.settings.fontSize);
- i.setPrintMarginColumn(this.settings.printMarginColumn);
- i.setShowPrintMargin(this.settings.printMargin);
- i.setHighlightActiveLine(this.settings.highlightLine);
- i.setDisplayIndentGuides(this.settings.indentGuides);
- i.getSession().setUseWrapMode(this.settings.wrapMode);
- this.setTabSize(this.settings.tabSize, i);
- this.setSoftTabs(this.settings.softTabs, i);
- this.setOverScroll(this.settings.overScroll, i);
- i.setOptions({
- enableBasicAutocompletion: true,
- enableSnippets: true,
- enableLiveAutocompletion: this.settings.autocomplete
- });
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Create a new editor instance attached to given session
- //
- // Parameters:
- // session - {EditSession} Session to be used for new Editor instance
- //
- //////////////////////////////////////////////////////////////////
-
- addInstance: function(session, where) {
- var el = $('
');
- var chType, chArr = [], sc = null, chIdx = null;
- var _this = this;
-
- if (this.instances.length == 0) {
- // el.appendTo($('#editor-region'));
- el.appendTo($('#root-editor-wrapper'));
- } else {
-
- var ch = this.activeInstance.el;
- var root;
-
- chIdx = (where === 'top' || where === 'left') ? 0 : 1;
- chType = (where === 'top' || where === 'bottom') ?
- 'vertical' : 'horizontal';
-
- chArr[chIdx] = el;
- chArr[1 - chIdx] = ch;
-
- root = $('
')
- .height(ch.height())
- .width(ch.width())
- .addClass('editor-wrapper-' + chType)
- .appendTo(ch.parent());
-
- sc = new SplitContainer(root, chArr, chType);
-
- if (this.instances.length > 1) {
- var pContainer = this.activeInstance.splitContainer;
- var idx = this.activeInstance.splitIdx;
- pContainer.setChild(idx, sc);
- }
- }
-
- ace.require("ace/ext/language_tools");
- var i = ace.edit(el[0]);
- var resizeEditor = function(){
- i.resize();
- };
-
- if (sc) {
- i.splitContainer = sc;
- i.splitIdx = chIdx;
-
- this.activeInstance.splitContainer = sc;
- this.activeInstance.splitIdx = 1 - chIdx;
-
- sc.root
- .on('h-resize', resizeEditor)
- .on('v-resize', resizeEditor);
-
- if (this.instances.length === 1) {
- var re = function(){
- _this.instances[0].resize();
- };
- sc.root
- .on('h-resize', re)
- .on('v-resize', re);
- }
- }
-
- i.el = el;
- this.setSession(session, i);
-
- this.changeListener(i);
- this.cursorTracking(i);
- this.clickListener(i);
- this.bindKeys(i);
-
- this.instances.push(i);
-
- i.on('focus', function(){
- _this.focus(i);
- });
-
- return i;
- },
-
- createSplitMenu: function(){
- var _this = this;
- var _splitOptionsMenu = $('#split-options-menu');
-
- this.initMenuHandler($('#split'),_splitOptionsMenu);
-
- $('#split-horizontally a').click(function(e){
- e.stopPropagation();
- _this.addInstance(_this.activeInstance.getSession(), 'bottom');
- _splitOptionsMenu.hide();
- });
-
- $('#split-vertically a').click(function(e){
- e.stopPropagation();
- _this.addInstance(_this.activeInstance.getSession(), 'right');
- _splitOptionsMenu.hide();
- });
-
- $('#merge-all a').click(function(e){
- e.stopPropagation();
- var s = _this.activeInstance.getSession();
- _this.exterminate();
- _this.addInstance(s);
- _splitOptionsMenu.hide();
- });
- },
-
- createModeMenu: function(){
- var _this = this;
- var _thisMenu = $('#changemode-menu');
- var modeColumns = new Array();
- var modeOptions = new Array();
- var maxOptionsColumn = 15;
- var firstOption = 0;
-
- this.initMenuHandler($('#current-mode'),_thisMenu);
-
- var modes = Object.keys( ModeList.modesByName ).sort();
-
- $.each(modes, function(i){
- modeOptions.push('
'+modes[i]+'');
- });
-
- var html = '
';
- while(true) {
- html += '';
- if ((modeOptions.length-firstOption) < maxOptionsColumn) {
- max = modeOptions.length;
- } else {
- max = firstOption + maxOptionsColumn;
- }
- var currentcolumn = modeOptions.slice(firstOption, max);
- for (var option in currentcolumn) {
- html += currentcolumn[option];
- }
- html += ' | ';
- firstOption = firstOption + maxOptionsColumn;
- if(firstOption >= modeOptions.length) {
- break;
- }
- }
-
- html += '
';
- _thisMenu.html(html);
-
- $('#changemode-menu a').click(function(e){
- e.stopPropagation();
- var newMode = "ace/mode/" + $(e.currentTarget).text();
- var actSession = _this.activeInstance.getSession();
-
- // handle async mode change
- var fn = function(){
- _this.setModeDisplay(actSession);
- actSession.removeListener('changeMode', fn);
- };
- actSession.on("changeMode", fn);
-
- actSession.setMode(newMode);
- _thisMenu.hide();
-
- });
- },
-
- initMenuHandler: function(button,menu){
- var _this = this;
- var thisButton = button;
- var thisMenu = menu;
-
- thisMenu.appendTo($('body'));
-
- thisButton.click(function(e){
- var wh = $(window).height();
-
- e.stopPropagation();
-
- // close other menus
- _this.closeMenus(thisMenu);
-
- thisMenu.css({
- // display: 'block',
- bottom: ( (wh - $(this).offset().top) + 8) + 'px',
- left: ($(this).offset().left - 13) + 'px'
- });
-
- thisMenu.slideToggle('fast');
-
- // handle click-out autoclosing
- var fn = function(){
- thisMenu.hide();
- $(window).off('click', fn);
- };
- $(window).on('click', fn);
- });
- },
-
- closeMenus: function(exclude){
- var menuId = exclude.attr("id");
- if(menuId != 'split-options-menu') $('#split-options-menu').hide();
- if(menuId != 'changemode-menu') $('#changemode-menu').hide();
- },
-
- setModeDisplay: function(session){
- var currMode = session.getMode().$id;
- if(currMode){
- currMode = currMode.substring(currMode.lastIndexOf('/') + 1);
- $('#current-mode').html(currMode);
- } else {
- $('#current-mode').html('text');
- }
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Remove all Editor instances and clean up the DOM
- //
- //////////////////////////////////////////////////////////////////
-
- exterminate: function() {
- $('.editor').remove();
- $('.editor-wrapper').remove();
- $('#editor-region').append($('
').attr('id', 'editor'));
- $('#current-file').html('');
- $('#current-mode').html('');
- this.instances = [];
- this.activeInstance = null;
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Detach EditSession session from all Editor instances replacing
- // them with replacementSession
- //
- //////////////////////////////////////////////////////////////////
-
- removeSession: function(session, replacementSession) {
- for (var k = 0; k < this.instances.length; k++) {
- if (this.instances[k].getSession().path === session.path) {
- this.instances[k].setSession(replacementSession);
- }
- }
- if ($('#current-file').text() === session.path) {
- $('#current-file').text(replacementSession.path);
- }
-
- this.setModeDisplay(replacementSession);
- },
-
- isOpen: function(session){
- for (var k = 0; k < this.instances.length; k++) {
- if (this.instances[k].getSession().path === session.path) {
- return true;
- }
- }
- return false;
- },
-
- /////////////////////////////////////////////////////////////////
- //
- // Convenience function to iterate over Editor instances
- //
- // Parameters:
- // fn - {Function} callback called with each member as an argument
- //
- /////////////////////////////////////////////////////////////////
-
- forEach: function(fn) {
- for (var k = 0; k < this.instances.length; k++) {
- fn.call(this, this.instances[k]);
- }
- },
-
- /////////////////////////////////////////////////////////////////
- //
- // Get the currently active Editor instance
- //
- // In a multi-pane setup this would correspond to the
- // editor pane user is currently working on.
- //
- /////////////////////////////////////////////////////////////////
-
- getActive: function() {
- return this.activeInstance;
- },
-
- /////////////////////////////////////////////////////////////////
- //
- // Set an editor instance as active
- //
- // Parameters:
- // i - {Editor}
- //
- /////////////////////////////////////////////////////////////////
-
- setActive: function(i) {
- if (! i) return;
- this.activeInstance = i;
- $('#current-file').text(i.getSession().path);
- this.setModeDisplay(i.getSession());
- },
-
- /////////////////////////////////////////////////////////////////
- //
- // Change the EditSession of Editor instance
- //
- // Parameters:
- // session - {EditSession}
- // i - {Editor}
- //
- /////////////////////////////////////////////////////////////////
-
- setSession: function(session, i) {
- i = i || this.getActive();
- if (! this.isOpen(session)) {
- if (! i) {
- i = this.addInstance(session);
- } else {
- i.setSession(session);
- }
- } else {
- // Proxy session is required because scroll-position and
- // cursor position etc. are shared among sessions.
-
- var proxySession = new EditSession(session.getDocument(),
- session.getMode());
- proxySession.setUndoManager(new UndoManager());
- proxySession.path = session.path;
- proxySession.listThumb = session.listThumb;
- proxySession.tabThumb = session.tabThumb;
- if (! i) {
- i = this.addInstance(proxySession);
- } else {
- i.setSession(proxySession);
- }
- }
- this.applySettings(i);
- this.cursorTracking(i);
- this.setActive(i);
- },
-
- /////////////////////////////////////////////////////////////////
- //
- // Select file mode by extension case insensitive
- //
- // Parameters:
- // e - {String} File extension
- //
- /////////////////////////////////////////////////////////////////
-
- selectMode: function(e) {
- if(typeof(e) != 'string'){
- return 'text';
- }
- e = e.toLowerCase();
- return( ModeList.getModeForPath( e ) );
- },
-
- /////////////////////////////////////////////////////////////////
- //
- // Add an text mode for an extension
- //
- // Parameters:
- // extension - {String} File Extension
- // mode - {String} TextMode for this extension
- //
- /////////////////////////////////////////////////////////////////
-
- addFileExtensionTextMode: function(extension, mode){
- if(typeof(extension) != 'string' || typeof(mode) != 'string'){
- if (console){
- console.warn('wrong usage of addFileExtensionTextMode, both parameters need to be string');
- }
- return;
- }
- mode = mode.toLowerCase();
- this.fileExtensionTextMode[extension] = mode;
- },
-
- /////////////////////////////////////////////////////////////////
- //
- // clear all extension-text mode joins
- //
- /////////////////////////////////////////////////////////////////
-
- clearFileExtensionTextMode: function(){
- this.fileExtensionTextMode = {};
- },
-
- /////////////////////////////////////////////////////////////////
- //
- // Set the editor mode
- //
- // Parameters:
- // m - {TextMode} mode
- // i - {Editor} Editor (Defaults to active editor)
- //
- /////////////////////////////////////////////////////////////////
-
- setMode: function(m, i) {
- i = i || this.getActive();
-
- // Check if mode is already loaded
- if (! editorModes[m]) {
-
- // Load the Mode
- var modeFile = 'components/editor/ace-editor/mode-' + m + '.js';
- $.loadScript(modeFile, function() {
-
- // Mark the mode as loaded
- editorModes[m] = true;
- var EditorMode = ace.require('ace/mode/' + m).Mode;
- i.getSession().setMode(new EditorMode());
- }, true);
- } else {
-
- var EditorMode = ace.require('ace/mode/' + m).Mode;
- i.getSession().setMode(new EditorMode());
-
- }
- },
-
- /////////////////////////////////////////////////////////////////
- //
- // Set the editor theme
- //
- // Parameters:
- // t - {String} theme eg. twilight, cobalt etc.
- // i - {Editor} Editor instance (If omitted, Defaults to all editors)
- //
- // For a list of themes supported by Ace - refer :
- // https://github.com/ajaxorg/ace/tree/master/lib/ace/theme
- //
- // TODO: Provide support for custom themes
- //
- /////////////////////////////////////////////////////////////////
-
- setTheme: function(t, i) {
- if (i) {
- // If a specific instance is specified, change the theme for
- // this instance
- i.setTheme('ace/theme/'+ t);
- } else {
- // Change the theme for the existing editor instances
- // and make it the default for new instances
- this.settings.theme = t;
- for (var k = 0; k < this.instances.length; k++) {
- this.instances[k].setTheme('ace/theme/'+ t);
- }
- }
- //Database
- //codiad.settings.update_option( 'codiad.editor.theme', t );
- },
-
- /////////////////////////////////////////////////////////////////
- //
- // Set contents of the editor
- //
- // Parameters:
- // c - {String} content
- // i - {Editor} (Defaults to active editor)
- //
- /////////////////////////////////////////////////////////////////
-
- setContent: function(c, i) {
- i = i || this.getActive();
- i.getSession().setValue(c);
- },
-
- /////////////////////////////////////////////////////////////////
- //
- // Set Font Size
- //
- // Set the font for all Editor instances and remember
- // the value for Editor instances to be created in
- // future
- //
- // Parameters:
- // s - {Number} font size
- // i - {Editor} Editor instance (If omitted, Defaults to all editors)
- //
- /////////////////////////////////////////////////////////////////
-
- setFontSize: function(s, i) {
- if (i) {
- i.setFontSize(s);
- } else {
- this.settings.fontSize = s;
- this.forEach(function(i) {
- i.setFontSize(s);
- });
- }
- //Database
- //codiad.settings.update_option( 'codiad.editor.fontSize', s );
- },
-
-
- /////////////////////////////////////////////////////////////////
- //
- // Enable/disable Highlighting of active line
- //
- // Parameters:
- // h - {Boolean}
- // i - {Editor} Editor instance ( If left out, setting is
- // applied to all editors )
- //
- /////////////////////////////////////////////////////////////////
-
- setHighlightLine: function(h, i) {
- if (i) {
- i.setHighlightActiveLine(h);
- } else {
- this.settings.highlightLine = h;
- this.forEach(function(i) {
- i.setHighlightActiveLine(h);
- });
- }
- //Database
- //codiad.settings.update_option( 'codiad.editor.highlightLine', h );
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Show/Hide print margin indicator
- //
- // Parameters:
- // p - {Number} print margin column
- // i - {Editor} (If omitted, Defaults to all editors)
- //
- //////////////////////////////////////////////////////////////////
-
- setPrintMargin: function(p, i) {
- if (i) {
- i.setShowPrintMargin(p);
- } else {
- this.settings.printMargin = p;
- this.forEach(function(i) {
- i.setShowPrintMargin(p);
- });
- }
- //Database
- //codiad.settings.update_option( 'codiad.editor.printMargin', p );
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Set print margin column
- //
- // Parameters:
- // p - {Number} print margin column
- // i - {Editor} (If omitted, Defaults to all editors)
- //
- //////////////////////////////////////////////////////////////////
-
- setPrintMarginColumn: function(p, i) {
- if (i) {
- i.setPrintMarginColumn(p);
- } else {
- this.settings.printMarginColumn = p;
- this.forEach(function(i) {
- i.setPrintMarginColumn(p);
- });
- }
- //Database
- //codiad.settings.update_option( 'codiad.editor.printMarginColumn', p );
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Show/Hide indent guides
- //
- // Parameters:
- // g - {Boolean}
- // i - {Editor} (If omitted, Defaults to all editors)
- //
- //////////////////////////////////////////////////////////////////
-
- setIndentGuides: function(g, i) {
- if (i) {
- i.setDisplayIndentGuides(g);
- } else {
- this.settings.indentGuides = g;
- this.forEach(function(i) {
- i.setDisplayIndentGuides(g);
- });
- }
- //Database
- //codiad.settings.update_option( 'codiad.editor.indentGuides', g );
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Enable/Disable Code Folding
- //
- // Parameters:
- // f - {Boolean}
- // i - {Editor} (If omitted, Defaults to all editors)
- //
- //////////////////////////////////////////////////////////////////
-
- setCodeFolding: function(f, i) {
- if (i) {
- i.setFoldStyle(f);
- } else {
- this.forEach(function(i) {
- i.setFoldStyle(f);
- });
- }
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Enable/Disable Line Wrapping
- //
- // Parameters:
- // w - {Boolean}
- // i - {Editor} (If omitted, Defaults to all editors)
- //
- //////////////////////////////////////////////////////////////////
-
- setWrapMode: function(w, i) {
- if (i) {
- i.getSession().setUseWrapMode(w);
- } else {
- this.forEach(function(i) {
- i.getSession().setUseWrapMode(w);
- });
- }
- //Database
- //codiad.settings.update_option( 'codiad.editor.wrapMode', w );
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Set last position of modal to be saved
- //
- // Parameters:
- // t - {Boolean} (false for Automatic Position, true for Last Position)
- // i - {Editor} (If omitted, Defaults to all editors)
- //
- //////////////////////////////////////////////////////////////////
-
- setPersistentModal: function(t, i) {
- this.settings.persistentModal = t;
- //Database
- //codiad.settings.update_option( 'codiad.editor.persistentModal', t );
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Set trigger for opening the right sidebar
- //
- // Parameters:
- // t - {Boolean} (false for Hover, true for Click)
- // i - {Editor} (If omitted, Defaults to all editors)
- //
- //////////////////////////////////////////////////////////////////
-
- setRightSidebarTrigger: function(t, i) {
- this.settings.rightSidebarTrigger = t;
- //Database
- //codiad.settings.update_option( 'codiad.editor.rightSidebarTrigger', t );
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Set trigger for clicking on the filemanager
- //
- // Parameters:
- // t - {Boolean} (false for Hover, true for Click)
- // i - {Editor} (If omitted, Defaults to all editors)
- //
- //////////////////////////////////////////////////////////////////
-
- setFileManagerTrigger: function(t, i) {
- this.settings.fileManagerTrigger = t;
- //Database
- //codiad.settings.update_option( 'codiad.editor.fileManagerTrigger', t );
- codiad.project.loadSide();
- },
-
-
- //////////////////////////////////////////////////////////////////
- //
- // set Tab Size
- //
- // Parameters:
- // s - size
- // i - {Editor} (If omitted, Defaults to all editors)
- //
- //////////////////////////////////////////////////////////////////
-
- setTabSize: function(s, i) {
- if (i) {
- i.getSession().setTabSize(parseInt(s));
- } else {
- this.forEach(function(i) {
- i.getSession().setTabSize(parseInt(s));
- });
- }
- //Database
- //codiad.settings.update_option( 'codiad.editor.tabSize', s );
-
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Enable or disable Soft Tabs
- //
- // Parameters:
- // t - true / false
- // i - {Editor} (If omitted, Defaults to all editors)
- //
- //////////////////////////////////////////////////////////////////
-
- setSoftTabs: function(t, i) {
- if (i) {
- i.getSession().setUseSoftTabs(t);
- } else {
- this.forEach(function(i) {
- i.getSession().setUseSoftTabs(t);
- });
- }
- //Database
- //codiad.settings.update_option( 'codiad.editor.softTabs', t );
-
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Get content from editor
- //
- // Parameters:
- // i - {Editor} (Defaults to active editor)
- //
- //////////////////////////////////////////////////////////////////
-
- getContent: function(i) {
- i = i || this.getActive();
- if (! i) return;
- var content = i.getSession().getValue();
- if (!content) {
- content = ' ';
- } // Pass something through
- return content;
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Resize the editor - Trigger the editor to readjust its layout
- // esp if the container has been resized manually.
- //
- // Parameters:
- // i - {Editor} (Defaults to active editor)
- //
- //////////////////////////////////////////////////////////////////
-
- resize: function(i) {
- i = i || this.getActive();
- if (! i) return;
- i.resize();
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Mark the instance as changed (in the user interface)
- // upon change in the document content.
- //
- // Parameters:
- // i - {Editor}
- //
- //////////////////////////////////////////////////////////////////
-
- changeListener: function(i) {
-
- var _this = this;
- i.on('change', function() {
-
- codiad.active.markChanged(_this.getActive().getSession().path);
- codiad.active.savePosition();
- });
- },
-
- clickListener: function(i) {
-
- var _this = this;
- i.on('click', function() {
-
- codiad.active.savePosition();
- });
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Get Selected Text
- //
- // Parameters:
- // i - {Editor} (Defaults to active editor)
- //
- //////////////////////////////////////////////////////////////////
-
- getSelectedText: function(i) {
- i = i || this.getActive();
- if (! i) return;
- return i.getCopyText();
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Insert text
- //
- // Parameters:
- // val - {String} Text to be inserted
- // i - {Editor} (Defaults to active editor)
- //
- //////////////////////////////////////////////////////////////////
-
- insertText: function(val, i) {
- i = i || this.getActive();
- if (! i) return;
- i.insert(val);
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Move the cursor to a particular line
- //
- // Parameters:
- // line - {Number} Line number
- // i - {Editor} Editor instance
- //
- //////////////////////////////////////////////////////////////////
-
- gotoLine: function(line, i) {
- i = i || this.getActive();
- if (! i) return;
- i.gotoLine(line, 0, true);
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Focus an editor
- //
- // Parameters:
- // i - {Editor} Editor instance (Defaults to current editor)
- //
- //////////////////////////////////////////////////////////////////
-
- focus: function(i) {
- i = i || this.getActive();
- this.setActive(i);
- if (! i) return;
- i.focus();
- codiad.active.focus(i.getSession().path);
- this.cursorTracking(i);
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Setup Cursor Tracking
- //
- // Parameters:
- // i - {Editor} (Defaults to active editor)
- //
- //////////////////////////////////////////////////////////////////
-
- cursorTracking: function(i) {
-
- i = i || this.getActive();
- if (! i) return;
-
- /**
- * Update the cursor position now so that when a new file opens,
- * we do not have the old cursor data.
- */
-
- $('#cursor-position')
- .html(i18n('Ln') + ': '
- + (i.getCursorPosition().row + 1)
- + ' · ' + i18n('Col') + ': '
- + i.getCursorPosition().column
- );
-
- //Register the changecursor function so updates continue
- i.selection.on( "changeCursor", function( e ) {
-
- codiad.active.savePosition();
- $('#cursor-position')
- .html(i18n('Ln') + ': '
- + (i.getCursorPosition().row + 1)
- + ' · ' + i18n('Col') + ': '
- + i.getCursorPosition().column
- );
- });
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Setup Key bindings
- //
- // Parameters:
- // i - {Editor}
- //
- //////////////////////////////////////////////////////////////////
-
- bindKeys: function(i) {
-
- var _this = this;
-
- // Find
- i.commands.addCommand({
- name: 'Find',
- bindKey: {
- win: 'Ctrl-F',
- mac: 'Command-F'
- },
- exec: function(e) {
- _this.openSearch('find');
- }
- });
-
- // Find + Replace
- i.commands.addCommand({
- name: 'Replace',
- bindKey: {
- win: 'Ctrl-R',
- mac: 'Command-R'
- },
- exec: function(e) {
- _this.openSearch('replace');
- }
- });
-
- i.commands.addCommand({
- name: 'Move Up',
- bindKey: {
- win: 'Ctrl-up',
- mac: 'Command-up'
- },
- exec: function(e) {
- codiad.active.move('up');
- }
- });
-
- i.commands.addCommand({
- name: 'Move Down',
- bindKey: {
- win: 'Ctrl-down',
- mac: 'Command-up'
- },
- exec: function(e) {
- codiad.active.move('down');
- }
- });
-
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Present the Search (Find + Replace) dialog box
- //
- // Parameters:
- // type - {String} Optional, defaults to find. Provide 'replace' for replace dialog.
- //
- //////////////////////////////////////////////////////////////////
-
- openSearch: function(type) {
- if (this.getActive()) {
- codiad.modal.load(400,
- 'components/editor/dialog.php?action=search&type=' +
- type);
- codiad.modal.hideOverlay();
- } else {
- codiad.message.error('No Open Files');
- }
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Perform Search (Find + Replace) operation
- //
- // Parameters:
- // action - {String} find | replace | replaceAll
- // i - {Editor} Defaults to active Editor instance
- //
- //////////////////////////////////////////////////////////////////
-
- search: function(action, i) {
- i = i || this.getActive();
- if (! i) return;
- if( this.multi_line ) {
-
- var find = $('#modal textarea[name="find"]')
- .val();
- var replace = $('#modal textarea[name="replace"]')
- .val();
- } else {
-
- var find = $('#modal input[name="find"]')
- .val();
- var replace = $('#modal input[name="replace"]')
- .val();
- }
- switch (action) {
- case 'find':
-
- i.find(find, {
- backwards: false,
- wrap: true,
- caseSensitive: false,
- wholeWord: false,
- regExp: false
- });
-
- break;
-
- case 'replace':
-
- i.find(find, {
- backwards: false,
- wrap: true,
- caseSensitive: false,
- wholeWord: false,
- regExp: false
- });
- i.replace(replace);
-
- break;
-
- case 'replaceAll':
-
- i.find(find, {
- backwards: false,
- wrap: true,
- caseSensitive: false,
- wholeWord: false,
- regExp: false
- });
- i.replaceAll(replace);
-
- break;
- }
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Enable editor
- //
- // Parameters:
- // i - {Editor} (Defaults to active editor)
- //
- //////////////////////////////////////////////////////////////////
-
- enableEditing: function(i) {
- i = i || this.getActive();
- if (! i) return;
- i.textInput.setReadOnly( false );
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Disable editor
- //
- // Parameters:
- // i - {Editor} (Defaults to active editor)
- //
- //////////////////////////////////////////////////////////////////
-
- disableEditing: function(i) {
- i = i || this.getActive();
- if (! i) return;
- i.textInput.setReadOnly( true );
- },
-
- //////////////////////////////////////////////////////////////////
- //
- // Set Overscroll
- //
- // Parameters:
- // i - {Editor} (Defaults to active editor)
- //
- //////////////////////////////////////////////////////////////////
-
- setOverScroll: function( s, i ) {
-
- if (i) {
- i.setOption( "scrollPastEnd", s );
- } else {
- this.settings.overScroll = s;
- this.forEach(function(i) {
- i.setOption( "scrollPastEnd", s );
- });
- }
- //Database
- //codiad.settings.update_option( 'codiad.editor.overScroll', s );
- },
-
- setLiveAutocomplete: function( s, i ) {
-
- if (i) {
- i.setOptions({
- enableLiveAutocompletion: s
- });
- } else {
- this.settings.autocomplete = s;
- this.forEach(function(i) {
- i.setOptions({
- enableLiveAutocompletion: s
- });
- });
- }
- //Database
- //codiad.settings.update_option( 'codiad.editor.autocomplete', s );
- },
-
- toggleMultiLine: function( e ) {
-
- if( e.innerText === "Multi Line" ) {
-
- this.multi_line = true;
- e.innerText = "Single Line";
- $('input[name="find"]').hide();
- $('textarea[name="find"]').show();
- $('textarea[name="find"]').val( $('input[name="find"]').val() );
-
- $('input[name="replace"]').hide();
- $('textarea[name="replace"]').show();
- $('textarea[name="replace"]').val( $('input[name="replace"]').val() );
- } else {
-
- this.multi_line = false;
- e.innerText = "Multi Line";
- $('input[name="find"]').show();
- $('textarea[name="find"]').hide();
- $('input[name="find"]').val( $('textarea[name="find"]').val() );
-
- $('input[name="replace"]').show();
- $('textarea[name="replace"]').hide();
- $('input[name="replace"]').val( $('textarea[name="replace"]').val() );
- }
- },
-
- paste: function( ) {
-
- navigator.clipboard.readText().then(text => {codiad.editor.getActive().insert( text )});
- },
-
- openSort: function() {
-
- if ( this.getActive() && codiad.active.getSelectedText() != "" ) {
-
- codiad.modal.load( 400, 'components/editor/dialog.php?action=sort' );
- codiad.modal.hideOverlay();
- } else {
-
- codiad.message.error('No text selected');
- }
- },
-
- sort: function( eol ) {
-
- let text = $('#modal textarea[name="sort"]').val();
- let array = text.split( eol );
- array = array.sort( codiad.editor.sort_a );
- let sorted = array.join( eol );
-
- console.log( text, eol, array, sorted );
- codiad.modal.unload();
- codiad.editor.getActive().insert( sorted );
- codiad.editor.getActive().focus();
- },
-
- sort_a: function( a, b ) {
-
- let pos = 0;
- let case_sensitive = $( '#modal input[name="case_sensitive"]' ).prop( 'checked' )
-
- if( ! case_sensitive ) {
-
- a = a.toLowerCase();
- b = b.toLowerCase();
- }
-
- if( a < b ) {
-
- pos = -1;
- } else if( a > b ) {
-
- pos = 1;
- }
-
- return pos;
- }
- };
-
-})(this, jQuery);
\ No newline at end of file
+/*
+ * Copyright (c) Codiad & Kent Safranski (codiad.com), distributed
+ * as-is and without warranty under the MIT License. See
+ * [root]/license.txt for more. This information must remain intact.
+ */
+( function( global, $ ) {
+
+ // Classes from Ace
+ var VirtualRenderer = ace.require( 'ace/virtual_renderer' ).VirtualRenderer;
+ var Editor = ace.require( 'ace/editor' ).Editor;
+ var EditSession = ace.require( 'ace/edit_session' ).EditSession;
+ var ModeList = ace.require( "ace/ext/modelist" );
+ var UndoManager = ace.require( "ace/undomanager" ).UndoManager;
+
+ // Editor modes that have been loaded
+ var editorModes = {};
+
+ var codiad = global.codiad;
+ codiad._cursorPoll = null;
+
+ var separatorWidth = 3;
+
+ $( function() {
+ codiad.editor.init();
+ });
+
+ function SplitContainer( root, children, splitType ) {
+ var _this = this;
+
+ this.root = root;
+ this.splitType = splitType;
+ this.childContainers = {};
+ this.childElements = {};
+ this.splitProp = 0.5;
+
+ this.setChild( 0, children[0 ] );
+ this.setChild( 1, children[1 ] );
+
+ this.splitter = $( '
' )
+ .addClass( 'splitter' )
+ .appendTo( root )
+ .draggable( {
+ axis: ( splitType === 'horizontal' ? 'x' : 'y' ),
+ drag: function( e, ui ) {
+ if( _this.splitType === 'horizontal' ) {
+ var w1, w2;
+ w1 = ui.position.left - separatorWidth / 2;
+ w2 = _this.root.width() - ui.position.left -
+ separatorWidth / 2;
+ _this.splitProp = w1 / _this.root.width();
+ _this.childElements[0
+ .width( w1 )
+ .trigger( 'h-resize', [true, true] );
+ _this.childElements[1]
+ .width( w2 )
+ .css( 'left', w1 + separatorWidth + 'px' )
+ .trigger( 'h-resize', [true, true] );
+ _this.splitProp = ui.position.left / _this.root.width();
+ } else {
+ var h1, h2;
+ h1 = ui.position.top - separatorWidth / 2;
+ h2 = _this.root.width() - ui.position.top -
+ separatorWidth / 2;
+ _this.splitProp = h1 / _this.root.height();
+ _this.childElements[0]
+ .height( h1 )
+ .trigger( 'v-resize', [true, true] );
+ _this.childElements[1]
+ .height( h2 )
+ .css( 'top', h1 + separatorWidth + 'px' )
+ .trigger( 'v-resize', [true, true] );
+ }
+ }
+ });
+
+ if( splitType === 'horizontal' ) {
+ this.splitter
+ .addClass( 'h-splitter' )
+ .width( separatorWidth )
+ .height( root.height() );
+ } else if( splitType === 'vertical' ) {
+ this.splitter
+ .addClass( 'v-splitter' )
+ .height( separatorWidth )
+ .width( root.width() );
+ }
+
+ this.root.on( 'h-resize', function( e, percolateUp, percolateDown ) {
+ e.stopPropagation();
+ if( _this.splitType === 'horizontal' ) {
+ var w1, w2;
+ w1 = _this.root.width() * _this.splitProp -
+ separatorWidth / 2;
+ w2 = _this.root.width() * ( 1 - _this.splitProp ) -
+ separatorWidth / 2;
+ _this.childElements[0]
+ .width( w1 );
+ _this.childElements[1]
+ .width( w2 )
+ .css( 'left', w1 + separatorWidth );
+ _this.splitter.css( 'left', w1 );
+ } else if( _this.splitType === 'vertical' ) {
+ var w = _this.root.width();
+ _this.childElements[0]
+ .width( w );
+ _this.childElements[1]
+ .width( w );
+ _this.splitter.width( w );
+ }
+ if( percolateUp ) {
+ _this.root.parent( '.editor-wrapper' )
+ .trigger( 'h-resize', [true, false] );
+ }
+ if( !percolateDown ) return;
+ if( _this.childContainers[0] ) {
+ _this.childContainers[0].root
+ .trigger( 'h-resize', [false, true] );
+ } else if( _this.childContainers[1] ) {
+ _this.childContainers[1].root
+ .trigger( 'h-resize', [false, true] );
+ }
+ });
+
+ this.root.on( 'v-resize', function( e, percolateUp, percolateDown ) {
+ e.stopPropagation();
+ if( _this.splitType === 'horizontal' ) {
+ var h = _this.root.height();
+ _this.childElements[0]
+ .height( h );
+ _this.childElements[1]
+ .height( h );
+ _this.splitter.height( h );
+ } else if( _this.splitType === 'vertical' ) {
+ var h1 = _this.root.height() * _this.splitProp -
+ separatorWidth / 2;
+ var h2 = _this.root.height() * ( 1 - _this.splitProp ) -
+ separatorWidth / 2;
+ _this.childElements[0]
+ .height( h1 );
+ _this.childElements[1]
+ .height( h2 )
+ .css( 'top', h1 + separatorWidth );
+ _this.splitter.css( 'top', h1 );
+ }
+ if( percolateUp ) {
+ _this.root.parent( '.editor-wrapper' )
+ .trigger( 'v-resize', [true, false] );
+ }
+ if( !percolateDown ) return;
+ if( _this.childContainers[0] ) {
+ _this.childContainers[0].root
+ .trigger( 'v-resize', [false, true] );
+ } else if( _this.childContainers[1] ) {
+ _this.childContainers[1].root
+ .trigger( 'v-resize', [false, true] );
+ }
+ });
+
+ this.root
+ .trigger( 'h-resize', [false, false] )
+ .trigger( 'v-resize', [false, false] );
+ }
+
+ SplitContainer.prototype = {
+ setChild: function( idx, el ) {
+
+ if( el instanceof SplitContainer ) {
+ this.childElements[idx] = el.root;
+ this.childContainers[idx] = el;
+ el.idx = idx;
+ } else {
+ this.childElements[idx] = el;
+ }
+
+ this.childElements[idx].appendTo( this.root );
+ this.cssInit( this.childElements[idx], idx );
+ },
+ cssInit: function( el, idx ) {
+ var props = {};
+ var h1, h2, w1, w2, rh, rw;
+
+ rh = this.root.height();
+ rw = this.root.width();
+
+ if( this.splitType === 'horizontal' ) {
+
+ w1 = rw * this.splitProp - separatorWidth / 2;
+ w2 = rw * ( 1 - this.splitProp ) - separatorWidth / 2;
+
+ if( idx === 0 ) {
+ props = {
+ left: 0,
+ width: w1,
+ height: rh,
+ top: 0
+ };
+ } else {
+ props = {
+ left: w1 + separatorWidth,
+ width: w2,
+ height: rh,
+ top: 0
+ };
+ }
+
+ } else if( this.splitType === 'vertical' ) {
+
+ h1 = rh * this.splitProp - separatorWidth / 2;
+ h2 = rh * ( 1 - this.splitProp ) - separatorWidth / 2;
+
+ if( idx === 0 ) {
+ props = {
+ top: 0,
+ height: h1,
+ width: rw,
+ left: 0
+ };
+ } else {
+ props = {
+ top: h1 + separatorWidth,
+ height: h2,
+ width: rw,
+ left: 0
+ };
+ }
+
+ }
+
+ el.css( props );
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Editor Component for Codiad
+ // ---------------------------
+ // Manage the lifecycle of Editor instances
+ //
+ //////////////////////////////////////////////////////////////////
+
+ codiad.editor = {
+
+ /// Editor instances - One instance corresponds to an editor
+ /// pane in the user interface. Different EditSessions
+ /// (ace/edit_session)
+ instances: [],
+
+ /// Currently focussed editor
+ activeInstance: null,
+
+ // Settings for Editor instances
+ settings: {
+ autocomplete: false,
+ theme: 'twilight',
+ fontSize: '13px',
+ printMargin: false,
+ printMarginColumn: 80,
+ highlightLine: true,
+ indentGuides: true,
+ wrapMode: false,
+ softTabs: false,
+ persistentModal: true,
+ rightSidebarTrigger: false,
+ fileManagerTrigger: false,
+ tabSize: 4
+ },
+
+ multi_line: false,
+
+ rootContainer: null,
+
+ fileExtensionTextMode: {},
+
+ init: function() {
+ this.createSplitMenu();
+ this.createModeMenu();
+
+ var er = $( '#editor-region' );
+
+ er.on( 'h-resize-init', function() {
+ $( '#editor-region > .editor-wrapper' )
+ .width( $( this ).width() )
+ .trigger( 'h-resize' );
+
+ }).on( 'v-resize-init', function() {
+ $( '#editor-region > .editor-wrapper' )
+ .height( $( this ).height() )
+ .trigger( 'v-resize' );
+ });
+
+ $( "#root-editor-wrapper" ).live( "contextmenu", function( e ) {
+
+ // Context Menu
+ e.preventDefault();
+ _this = codiad.editor
+
+ if( _this.getActive() ) {
+
+ let path = codiad.active.getPath();
+ $( e.target ).attr( 'data-path', path );
+ codiad.filemanager.contextMenuShow( e, path, 'editor', 'editor' );
+ $( this ).addClass( 'context-menu-active' );
+ }
+ });
+
+ $( window ).resize( function() {
+ $( '#editor-region' )
+ .trigger( 'h-resize-init' )
+ .trigger( 'v-resize-init' );
+ });
+
+ //Load settings when initially starting up that way the first editor
+ //we open doesn't have the default settings.
+ this.getSettings();
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Retrieve editor settings from database
+ //
+ //////////////////////////////////////////////////////////////////
+
+ getSettings: async function() {
+
+ let boolVal = null;
+ let _this = this;
+ let options = [
+ 'editor.fontSize',
+ 'editor.overScroll',
+ 'editor.printMarginColumn',
+ 'editor.tabSize',
+ 'editor.theme',
+ ];
+ let bool_options = [
+ 'editor.autocomplete',
+ 'settings.autosave',
+ 'editor.printMargin',
+ 'editor.highlightLine',
+ 'editor.indentGuides',
+ 'editor.wrapMode',
+ 'editor.rightSidebarTrigger',
+ 'editor.fileManagerTrigger',
+ 'editor.softTabs',
+ 'editor.persistentModal',
+ ];
+
+ let user_settings = await codiad.settings.get_options();
+
+ //console.log( user_settings );
+
+ $.each( options, function( idx, key ) {
+
+ let localValue = user_settings['codiad.' + key];
+ if( localValue != null ) {
+
+ _this.settings[key.split( '.' ).pop()] = localValue;
+ }
+ });
+
+ $.each( bool_options, async function( idx, key ) {
+
+ let localValue = user_settings['codiad.' + key];
+ if( localValue != null ) {
+
+ _this.settings[key.split( '.' ).pop()] = ( localValue == 'true' );
+ }
+ });
+ },
+
+ /////////////////////////////////////////////////////////////////
+ //
+ // Apply configuration settings
+ //
+ // Parameters:
+ // i - {Editor}
+ //
+ /////////////////////////////////////////////////////////////////
+
+ applySettings: function( i ) {
+ // Check user-specified settings
+ this.getSettings();
+
+ // Apply the current configuration settings:
+ i.setTheme( 'ace/theme/' + this.settings.theme );
+ i.setFontSize( this.settings.fontSize );
+ i.setPrintMarginColumn( this.settings.printMarginColumn );
+ i.setShowPrintMargin( this.settings.printMargin );
+ i.setHighlightActiveLine( this.settings.highlightLine );
+ i.setDisplayIndentGuides( this.settings.indentGuides );
+ i.getSession().setUseWrapMode( this.settings.wrapMode );
+ this.setTabSize( this.settings.tabSize, i );
+ this.setSoftTabs( this.settings.softTabs, i );
+ this.setOverScroll( this.settings.overScroll, i );
+ i.setOptions( {
+ enableBasicAutocompletion: true,
+ enableSnippets: true,
+ enableLiveAutocompletion: this.settings.autocomplete
+ });
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Create a new editor instance attached to given session
+ //
+ // Parameters:
+ // session - {EditSession} Session to be used for new Editor instance
+ //
+ //////////////////////////////////////////////////////////////////
+
+ addInstance: function( session, where ) {
+ var el = $( '
' );
+ var chType, chArr = [],
+ sc = null,
+ chIdx = null;
+ var _this = this;
+
+ if( this.instances.length == 0 ) {
+ // el.appendTo($('#editor-region'));
+ el.appendTo( $( '#root-editor-wrapper' ) );
+ } else {
+
+ var ch = this.activeInstance.el;
+ var root;
+
+ chIdx = ( where === 'top' || where === 'left' ) ? 0 : 1;
+ chType = ( where === 'top' || where === 'bottom' ) ?
+ 'vertical' : 'horizontal';
+
+ chArr[chIdx] = el;
+ chArr[1 - chIdx] = ch;
+
+ root = $( '
' )
+ .height( ch.height() )
+ .width( ch.width() )
+ .addClass( 'editor-wrapper-' + chType )
+ .appendTo( ch.parent() );
+
+ sc = new SplitContainer( root, chArr, chType );
+
+ if( this.instances.length > 1 ) {
+ var pContainer = this.activeInstance.splitContainer;
+ var idx = this.activeInstance.splitIdx;
+ pContainer.setChild( idx, sc );
+ }
+ }
+
+ ace.require( "ace/ext/language_tools" );
+ var i = ace.edit( el[0] );
+ var resizeEditor = function() {
+ i.resize();
+ };
+
+ if( sc ) {
+ i.splitContainer = sc;
+ i.splitIdx = chIdx;
+
+ this.activeInstance.splitContainer = sc;
+ this.activeInstance.splitIdx = 1 - chIdx;
+
+ sc.root
+ .on( 'h-resize', resizeEditor )
+ .on( 'v-resize', resizeEditor );
+
+ if( this.instances.length === 1 ) {
+ var re = function() {
+ _this.instances[0].resize();
+ };
+ sc.root
+ .on( 'h-resize', re )
+ .on( 'v-resize', re );
+ }
+ }
+
+ i.el = el;
+ this.setSession( session, i );
+
+ this.changeListener( i );
+ this.cursorTracking( i );
+ this.clickListener( i );
+ this.bindKeys( i );
+
+ this.instances.push( i );
+
+ i.on( 'focus', function() {
+ _this.focus( i );
+ });
+
+ return i;
+ },
+
+ createSplitMenu: function() {
+ var _this = this;
+ var _splitOptionsMenu = $( '#split-options-menu' );
+
+ this.initMenuHandler( $( '#split' ), _splitOptionsMenu );
+
+ $( '#split-horizontally a' ).click( function( e ) {
+ e.stopPropagation();
+ _this.addInstance( _this.activeInstance.getSession(), 'bottom' );
+ _splitOptionsMenu.hide();
+ });
+
+ $( '#split-vertically a' ).click( function( e ) {
+ e.stopPropagation();
+ _this.addInstance( _this.activeInstance.getSession(), 'right' );
+ _splitOptionsMenu.hide();
+ });
+
+ $( '#merge-all a' ).click( function( e ) {
+ e.stopPropagation();
+ var s = _this.activeInstance.getSession();
+ _this.exterminate();
+ _this.addInstance( s );
+ _splitOptionsMenu.hide();
+ });
+ },
+
+ createModeMenu: function() {
+ var _this = this;
+ var _thisMenu = $( '#changemode-menu' );
+ var modeColumns = new Array();
+ var modeOptions = new Array();
+ var maxOptionsColumn = 15;
+ var firstOption = 0;
+
+ this.initMenuHandler( $( '#current-mode' ), _thisMenu );
+
+ var modes = Object.keys( ModeList.modesByName ).sort();
+
+ $.each( modes, function( i ) {
+ modeOptions.push( '
' + modes[i] + '' );
+ });
+
+ var html = '
';
+ while( true ) {
+ html += '';
+ if( ( modeOptions.length - firstOption ) < maxOptionsColumn ) {
+ max = modeOptions.length;
+ } else {
+ max = firstOption + maxOptionsColumn;
+ }
+ var currentcolumn = modeOptions.slice( firstOption, max );
+ for( var option in currentcolumn ) {
+ html += currentcolumn[option];
+ }
+ html += ' | ';
+ firstOption = firstOption + maxOptionsColumn;
+ if( firstOption >= modeOptions.length ) {
+ break;
+ }
+ }
+
+ html += '
';
+ _thisMenu.html( html );
+
+ $( '#changemode-menu a' ).click( function( e ) {
+ e.stopPropagation();
+ var newMode = "ace/mode/" + $( e.currentTarget ).text();
+ var actSession = _this.activeInstance.getSession();
+
+ // handle async mode change
+ var fn = function() {
+ _this.setModeDisplay( actSession );
+ actSession.removeListener( 'changeMode', fn );
+ };
+ actSession.on( "changeMode", fn );
+
+ actSession.setMode( newMode );
+ _thisMenu.hide();
+
+ });
+ },
+
+ initMenuHandler: function( button, menu ) {
+ var _this = this;
+ var thisButton = button;
+ var thisMenu = menu;
+
+ thisMenu.appendTo( $( 'body' ) );
+
+ thisButton.click( function( e ) {
+ var wh = $( window ).height();
+
+ e.stopPropagation();
+
+ // close other menus
+ _this.closeMenus( thisMenu );
+
+ thisMenu.css( {
+ // display: 'block',
+ bottom: ( ( wh - $( this ).offset().top ) + 8 ) + 'px',
+ left: ( $( this ).offset().left - 13 ) + 'px'
+ });
+
+ thisMenu.slideToggle( 'fast' );
+
+ // handle click-out autoclosing
+ var fn = function() {
+ thisMenu.hide();
+ $( window ).off( 'click', fn );
+ };
+ $( window ).on( 'click', fn );
+ });
+ },
+
+ closeMenus: function( exclude ) {
+ var menuId = exclude.attr( "id" );
+ if( menuId != 'split-options-menu' ) $( '#split-options-menu' ).hide();
+ if( menuId != 'changemode-menu' ) $( '#changemode-menu' ).hide();
+ },
+
+ setModeDisplay: function( session ) {
+ var currMode = session.getMode().$id;
+ if( currMode ) {
+ currMode = currMode.substring( currMode.lastIndexOf( '/' ) + 1 );
+ $( '#current-mode' ).html( currMode );
+ } else {
+ $( '#current-mode' ).html( 'text' );
+ }
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Remove all Editor instances and clean up the DOM
+ //
+ //////////////////////////////////////////////////////////////////
+
+ exterminate: function() {
+ $( '.editor' ).remove();
+ $( '.editor-wrapper' ).remove();
+ $( '#editor-region' ).append( $( '
' ).attr( 'id', 'editor' ) );
+ $( '#current-file' ).html( '' );
+ $( '#current-mode' ).html( '' );
+ this.instances = [];
+ this.activeInstance = null;
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Detach EditSession session from all Editor instances replacing
+ // them with replacementSession
+ //
+ //////////////////////////////////////////////////////////////////
+
+ removeSession: function( session, replacementSession ) {
+ for( var k = 0; k < this.instances.length; k++ ) {
+ if( this.instances[k].getSession().path === session.path ) {
+ this.instances[k].setSession( replacementSession );
+ }
+ }
+ if( $( '#current-file' ).text() === session.path ) {
+ $( '#current-file' ).text( replacementSession.path );
+ }
+
+ this.setModeDisplay( replacementSession );
+ },
+
+ isOpen: function( session ) {
+ for( var k = 0; k < this.instances.length; k++ ) {
+ if( this.instances[k].getSession().path === session.path ) {
+ return true;
+ }
+ }
+ return false;
+ },
+
+ /////////////////////////////////////////////////////////////////
+ //
+ // Convenience function to iterate over Editor instances
+ //
+ // Parameters:
+ // fn - {Function} callback called with each member as an argument
+ //
+ /////////////////////////////////////////////////////////////////
+
+ forEach: function( fn ) {
+ for( var k = 0; k < this.instances.length; k++ ) {
+ fn.call( this, this.instances[k] );
+ }
+ },
+
+ /////////////////////////////////////////////////////////////////
+ //
+ // Get the currently active Editor instance
+ //
+ // In a multi-pane setup this would correspond to the
+ // editor pane user is currently working on.
+ //
+ /////////////////////////////////////////////////////////////////
+
+ getActive: function() {
+ return this.activeInstance;
+ },
+
+ /////////////////////////////////////////////////////////////////
+ //
+ // Set an editor instance as active
+ //
+ // Parameters:
+ // i - {Editor}
+ //
+ /////////////////////////////////////////////////////////////////
+
+ setActive: function( i ) {
+ if( !i ) return;
+ this.activeInstance = i;
+ $( '#current-file' ).text( i.getSession().path );
+ this.setModeDisplay( i.getSession() );
+ },
+
+ /////////////////////////////////////////////////////////////////
+ //
+ // Change the EditSession of Editor instance
+ //
+ // Parameters:
+ // session - {EditSession}
+ // i - {Editor}
+ //
+ /////////////////////////////////////////////////////////////////
+
+ setSession: function( session, i ) {
+ i = i || this.getActive();
+ if( !this.isOpen( session ) ) {
+ if( !i ) {
+ i = this.addInstance( session );
+ } else {
+ i.setSession( session );
+ }
+ } else {
+ // Proxy session is required because scroll-position and
+ // cursor position etc. are shared among sessions.
+
+ var proxySession = new EditSession( session.getDocument(),
+ session.getMode() );
+ proxySession.setUndoManager( new UndoManager() );
+ proxySession.path = session.path;
+ proxySession.listThumb = session.listThumb;
+ proxySession.tabThumb = session.tabThumb;
+ if( !i ) {
+ i = this.addInstance( proxySession );
+ } else {
+ i.setSession( proxySession );
+ }
+ }
+ this.applySettings( i );
+ this.cursorTracking( i );
+ this.setActive( i );
+ },
+
+ /////////////////////////////////////////////////////////////////
+ //
+ // Select file mode by extension case insensitive
+ //
+ // Parameters:
+ // e - {String} File extension
+ //
+ /////////////////////////////////////////////////////////////////
+
+ selectMode: function( e ) {
+ if( typeof( e ) != 'string' ) {
+ return 'text';
+ }
+ e = e.toLowerCase();
+ return ( ModeList.getModeForPath( e ) );
+ },
+
+ /////////////////////////////////////////////////////////////////
+ //
+ // Add an text mode for an extension
+ //
+ // Parameters:
+ // extension - {String} File Extension
+ // mode - {String} TextMode for this extension
+ //
+ /////////////////////////////////////////////////////////////////
+
+ addFileExtensionTextMode: function( extension, mode ) {
+ if( typeof( extension ) != 'string' || typeof( mode ) != 'string' ) {
+ if( console ) {
+ console.warn( 'wrong usage of addFileExtensionTextMode, both parameters need to be string' );
+ }
+ return;
+ }
+ mode = mode.toLowerCase();
+ this.fileExtensionTextMode[extension] = mode;
+ },
+
+ /////////////////////////////////////////////////////////////////
+ //
+ // clear all extension-text mode joins
+ //
+ /////////////////////////////////////////////////////////////////
+
+ clearFileExtensionTextMode: function() {
+ this.fileExtensionTextMode = {};
+ },
+
+ /////////////////////////////////////////////////////////////////
+ //
+ // Set the editor mode
+ //
+ // Parameters:
+ // m - {TextMode} mode
+ // i - {Editor} Editor (Defaults to active editor)
+ //
+ /////////////////////////////////////////////////////////////////
+
+ setMode: function( m, i ) {
+ i = i || this.getActive();
+
+ // Check if mode is already loaded
+ if( !editorModes[m] ) {
+
+ // Load the Mode
+ var modeFile = 'components/editor/ace-editor/mode-' + m + '.js';
+ $.loadScript( modeFile, function() {
+
+ // Mark the mode as loaded
+ editorModes[m] = true;
+ var EditorMode = ace.require( 'ace/mode/' + m ).Mode;
+ i.getSession().setMode( new EditorMode() );
+ }, true );
+ } else {
+
+ var EditorMode = ace.require( 'ace/mode/' + m ).Mode;
+ i.getSession().setMode( new EditorMode() );
+
+ }
+ },
+
+ /////////////////////////////////////////////////////////////////
+ //
+ // Set the editor theme
+ //
+ // Parameters:
+ // t - {String} theme eg. twilight, cobalt etc.
+ // i - {Editor} Editor instance (If omitted, Defaults to all editors)
+ //
+ // For a list of themes supported by Ace - refer :
+ // https://github.com/ajaxorg/ace/tree/master/lib/ace/theme
+ //
+ // TODO: Provide support for custom themes
+ //
+ /////////////////////////////////////////////////////////////////
+
+ setTheme: function( t, i ) {
+ if( i ) {
+ // If a specific instance is specified, change the theme for
+ // this instance
+ i.setTheme( 'ace/theme/' + t );
+ } else {
+ // Change the theme for the existing editor instances
+ // and make it the default for new instances
+ this.settings.theme = t;
+ for( var k = 0; k < this.instances.length; k++ ) {
+ this.instances[k].setTheme( 'ace/theme/' + t );
+ }
+ }
+ //Database
+ //codiad.settings.update_option( 'codiad.editor.theme', t );
+ },
+
+ /////////////////////////////////////////////////////////////////
+ //
+ // Set contents of the editor
+ //
+ // Parameters:
+ // c - {String} content
+ // i - {Editor} (Defaults to active editor)
+ //
+ /////////////////////////////////////////////////////////////////
+
+ setContent: function( c, i ) {
+ i = i || this.getActive();
+ i.getSession().setValue( c );
+ },
+
+ /////////////////////////////////////////////////////////////////
+ //
+ // Set Font Size
+ //
+ // Set the font for all Editor instances and remember
+ // the value for Editor instances to be created in
+ // future
+ //
+ // Parameters:
+ // s - {Number} font size
+ // i - {Editor} Editor instance (If omitted, Defaults to all editors)
+ //
+ /////////////////////////////////////////////////////////////////
+
+ setFontSize: function( s, i ) {
+ if( i ) {
+ i.setFontSize( s );
+ } else {
+ this.settings.fontSize = s;
+ this.forEach( function( i ) {
+ i.setFontSize( s );
+ });
+ }
+ //Database
+ //codiad.settings.update_option( 'codiad.editor.fontSize', s );
+ },
+
+
+ /////////////////////////////////////////////////////////////////
+ //
+ // Enable/disable Highlighting of active line
+ //
+ // Parameters:
+ // h - {Boolean}
+ // i - {Editor} Editor instance ( If left out, setting is
+ // applied to all editors )
+ //
+ /////////////////////////////////////////////////////////////////
+
+ setHighlightLine: function( h, i ) {
+ if( i ) {
+ i.setHighlightActiveLine( h );
+ } else {
+ this.settings.highlightLine = h;
+ this.forEach( function( i ) {
+ i.setHighlightActiveLine( h );
+ });
+ }
+ //Database
+ //codiad.settings.update_option( 'codiad.editor.highlightLine', h );
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Show/Hide print margin indicator
+ //
+ // Parameters:
+ // p - {Number} print margin column
+ // i - {Editor} (If omitted, Defaults to all editors)
+ //
+ //////////////////////////////////////////////////////////////////
+
+ setPrintMargin: function( p, i ) {
+ if( i ) {
+ i.setShowPrintMargin( p );
+ } else {
+ this.settings.printMargin = p;
+ this.forEach( function( i ) {
+ i.setShowPrintMargin( p );
+ });
+ }
+ //Database
+ //codiad.settings.update_option( 'codiad.editor.printMargin', p );
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Set print margin column
+ //
+ // Parameters:
+ // p - {Number} print margin column
+ // i - {Editor} (If omitted, Defaults to all editors)
+ //
+ //////////////////////////////////////////////////////////////////
+
+ setPrintMarginColumn: function( p, i ) {
+ if( i ) {
+ i.setPrintMarginColumn( p );
+ } else {
+ this.settings.printMarginColumn = p;
+ this.forEach( function( i ) {
+ i.setPrintMarginColumn( p );
+ });
+ }
+ //Database
+ //codiad.settings.update_option( 'codiad.editor.printMarginColumn', p );
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Show/Hide indent guides
+ //
+ // Parameters:
+ // g - {Boolean}
+ // i - {Editor} (If omitted, Defaults to all editors)
+ //
+ //////////////////////////////////////////////////////////////////
+
+ setIndentGuides: function( g, i ) {
+ if( i ) {
+ i.setDisplayIndentGuides( g );
+ } else {
+ this.settings.indentGuides = g;
+ this.forEach( function( i ) {
+ i.setDisplayIndentGuides( g );
+ });
+ }
+ //Database
+ //codiad.settings.update_option( 'codiad.editor.indentGuides', g );
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Enable/Disable Code Folding
+ //
+ // Parameters:
+ // f - {Boolean}
+ // i - {Editor} (If omitted, Defaults to all editors)
+ //
+ //////////////////////////////////////////////////////////////////
+
+ setCodeFolding: function( f, i ) {
+ if( i ) {
+ i.setFoldStyle( f );
+ } else {
+ this.forEach( function( i ) {
+ i.setFoldStyle( f );
+ });
+ }
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Enable/Disable Line Wrapping
+ //
+ // Parameters:
+ // w - {Boolean}
+ // i - {Editor} (If omitted, Defaults to all editors)
+ //
+ //////////////////////////////////////////////////////////////////
+
+ setWrapMode: function( w, i ) {
+ if( i ) {
+ i.getSession().setUseWrapMode( w );
+ } else {
+ this.forEach( function( i ) {
+ i.getSession().setUseWrapMode( w );
+ });
+ }
+ //Database
+ //codiad.settings.update_option( 'codiad.editor.wrapMode', w );
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Set last position of modal to be saved
+ //
+ // Parameters:
+ // t - {Boolean} (false for Automatic Position, true for Last Position)
+ // i - {Editor} (If omitted, Defaults to all editors)
+ //
+ //////////////////////////////////////////////////////////////////
+
+ setPersistentModal: function( t, i ) {
+ this.settings.persistentModal = t;
+ //Database
+ //codiad.settings.update_option( 'codiad.editor.persistentModal', t );
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Set trigger for opening the right sidebar
+ //
+ // Parameters:
+ // t - {Boolean} (false for Hover, true for Click)
+ // i - {Editor} (If omitted, Defaults to all editors)
+ //
+ //////////////////////////////////////////////////////////////////
+
+ setRightSidebarTrigger: function( t, i ) {
+ this.settings.rightSidebarTrigger = t;
+ //Database
+ //codiad.settings.update_option( 'codiad.editor.rightSidebarTrigger', t );
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Set trigger for clicking on the filemanager
+ //
+ // Parameters:
+ // t - {Boolean} (false for Hover, true for Click)
+ // i - {Editor} (If omitted, Defaults to all editors)
+ //
+ //////////////////////////////////////////////////////////////////
+
+ setFileManagerTrigger: function( t, i ) {
+ this.settings.fileManagerTrigger = t;
+ //Database
+ //codiad.settings.update_option( 'codiad.editor.fileManagerTrigger', t );
+ codiad.project.loadSide();
+ },
+
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // set Tab Size
+ //
+ // Parameters:
+ // s - size
+ // i - {Editor} (If omitted, Defaults to all editors)
+ //
+ //////////////////////////////////////////////////////////////////
+
+ setTabSize: function( s, i ) {
+ if( i ) {
+ i.getSession().setTabSize( parseInt( s ) );
+ } else {
+ this.forEach( function( i ) {
+ i.getSession().setTabSize( parseInt( s ) );
+ });
+ }
+ //Database
+ //codiad.settings.update_option( 'codiad.editor.tabSize', s );
+
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Enable or disable Soft Tabs
+ //
+ // Parameters:
+ // t - true / false
+ // i - {Editor} (If omitted, Defaults to all editors)
+ //
+ //////////////////////////////////////////////////////////////////
+
+ setSoftTabs: function( t, i ) {
+ if( i ) {
+ i.getSession().setUseSoftTabs( t );
+ } else {
+ this.forEach( function( i ) {
+ i.getSession().setUseSoftTabs( t );
+ });
+ }
+ //Database
+ //codiad.settings.update_option( 'codiad.editor.softTabs', t );
+
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Get content from editor
+ //
+ // Parameters:
+ // i - {Editor} (Defaults to active editor)
+ //
+ //////////////////////////////////////////////////////////////////
+
+ getContent: function( i ) {
+ i = i || this.getActive();
+ if( !i ) return;
+ var content = i.getSession().getValue();
+ if( !content ) {
+ content = ' ';
+ } // Pass something through
+ return content;
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Resize the editor - Trigger the editor to readjust its layout
+ // esp if the container has been resized manually.
+ //
+ // Parameters:
+ // i - {Editor} (Defaults to active editor)
+ //
+ //////////////////////////////////////////////////////////////////
+
+ resize: function( i ) {
+ i = i || this.getActive();
+ if( !i ) return;
+ i.resize();
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Mark the instance as changed (in the user interface)
+ // upon change in the document content.
+ //
+ // Parameters:
+ // i - {Editor}
+ //
+ //////////////////////////////////////////////////////////////////
+
+ changeListener: function( i ) {
+
+ var _this = this;
+ i.on( 'change', function() {
+
+ codiad.active.markChanged( _this.getActive().getSession().path );
+ codiad.active.savePosition();
+ });
+ },
+
+ clickListener: function( i ) {
+
+ var _this = this;
+ i.on( 'click', function() {
+
+ codiad.active.savePosition();
+ });
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Get Selected Text
+ //
+ // Parameters:
+ // i - {Editor} (Defaults to active editor)
+ //
+ //////////////////////////////////////////////////////////////////
+
+ getSelectedText: function( i ) {
+ i = i || this.getActive();
+ if( !i ) return;
+ return i.getCopyText();
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Insert text
+ //
+ // Parameters:
+ // val - {String} Text to be inserted
+ // i - {Editor} (Defaults to active editor)
+ //
+ //////////////////////////////////////////////////////////////////
+
+ insertText: function( val, i ) {
+ i = i || this.getActive();
+ if( !i ) return;
+ i.insert( val );
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Move the cursor to a particular line
+ //
+ // Parameters:
+ // line - {Number} Line number
+ // i - {Editor} Editor instance
+ //
+ //////////////////////////////////////////////////////////////////
+
+ gotoLine: function( line, i ) {
+ i = i || this.getActive();
+ if( !i ) return;
+ i.gotoLine( line, 0, true );
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Focus an editor
+ //
+ // Parameters:
+ // i - {Editor} Editor instance (Defaults to current editor)
+ //
+ //////////////////////////////////////////////////////////////////
+
+ focus: function( i ) {
+ i = i || this.getActive();
+ this.setActive( i );
+ if( !i ) return;
+ i.focus();
+ codiad.active.focus( i.getSession().path );
+ this.cursorTracking( i );
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Setup Cursor Tracking
+ //
+ // Parameters:
+ // i - {Editor} (Defaults to active editor)
+ //
+ //////////////////////////////////////////////////////////////////
+
+ cursorTracking: function( i ) {
+
+ i = i || this.getActive();
+ if( !i ) return;
+
+ /**
+ * Update the cursor position now so that when a new file opens,
+ * we do not have the old cursor data.
+ */
+
+ $( '#cursor-position' )
+ .html( i18n( 'Ln' ) + ': ' +
+ ( i.getCursorPosition().row + 1 ) +
+ ' · ' + i18n( 'Col' ) + ': ' +
+ i.getCursorPosition().column
+ );
+
+ //Register the changecursor function so updates continue
+ i.selection.on( "changeCursor", function( e ) {
+
+ codiad.active.savePosition();
+ $( '#cursor-position' )
+ .html( i18n( 'Ln' ) + ': ' +
+ ( i.getCursorPosition().row + 1 ) +
+ ' · ' + i18n( 'Col' ) + ': ' +
+ i.getCursorPosition().column
+ );
+ });
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Setup Key bindings
+ //
+ // Parameters:
+ // i - {Editor}
+ //
+ //////////////////////////////////////////////////////////////////
+
+ bindKeys: function( i ) {
+
+ var _this = this;
+
+ // Find
+ i.commands.addCommand( {
+ name: 'Find',
+ bindKey: {
+ win: 'Ctrl-F',
+ mac: 'Command-F'
+ },
+ exec: function( e ) {
+ _this.openSearch( 'find' );
+ }
+ });
+
+ // Find + Replace
+ i.commands.addCommand( {
+ name: 'Replace',
+ bindKey: {
+ win: 'Ctrl-R',
+ mac: 'Command-R'
+ },
+ exec: function( e ) {
+ _this.openSearch( 'replace' );
+ }
+ });
+
+ i.commands.addCommand( {
+ name: 'Move Up',
+ bindKey: {
+ win: 'Ctrl-up',
+ mac: 'Command-up'
+ },
+ exec: function( e ) {
+ codiad.active.move( 'up' );
+ }
+ });
+
+ i.commands.addCommand( {
+ name: 'Move Down',
+ bindKey: {
+ win: 'Ctrl-down',
+ mac: 'Command-up'
+ },
+ exec: function( e ) {
+ codiad.active.move( 'down' );
+ }
+ });
+
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Present the Search (Find + Replace) dialog box
+ //
+ // Parameters:
+ // type - {String} Optional, defaults to find. Provide 'replace' for replace dialog.
+ //
+ //////////////////////////////////////////////////////////////////
+
+ openSearch: function( type ) {
+ if( this.getActive() ) {
+ codiad.modal.load( 400,
+ 'components/editor/dialog.php?action=search&type=' +
+ type );
+ codiad.modal.hideOverlay();
+ } else {
+ codiad.message.error( 'No Open Files' );
+ }
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Perform Search (Find + Replace) operation
+ //
+ // Parameters:
+ // action - {String} find | replace | replaceAll
+ // i - {Editor} Defaults to active Editor instance
+ //
+ //////////////////////////////////////////////////////////////////
+
+ search: function( action, i ) {
+ i = i || this.getActive();
+ if( !i ) return;
+ if( this.multi_line ) {
+
+ var find = $( '#modal textarea[name="find"]' )
+ .val();
+ var replace = $( '#modal textarea[name="replace"]' )
+ .val();
+ } else {
+
+ var find = $( '#modal input[name="find"]' )
+ .val();
+ var replace = $( '#modal input[name="replace"]' )
+ .val();
+ }
+ switch ( action ) {
+ case 'find':
+
+ i.find( find, {
+ backwards: false,
+ wrap: true,
+ caseSensitive: false,
+ wholeWord: false,
+ regExp: false
+ });
+
+ break;
+
+ case 'replace':
+
+ i.find( find, {
+ backwards: false,
+ wrap: true,
+ caseSensitive: false,
+ wholeWord: false,
+ regExp: false
+ });
+ i.replace( replace );
+
+ break;
+
+ case 'replaceAll':
+
+ i.find( find, {
+ backwards: false,
+ wrap: true,
+ caseSensitive: false,
+ wholeWord: false,
+ regExp: false
+ });
+ i.replaceAll( replace );
+
+ break;
+ }
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Enable editor
+ //
+ // Parameters:
+ // i - {Editor} (Defaults to active editor)
+ //
+ //////////////////////////////////////////////////////////////////
+
+ enableEditing: function( i ) {
+ i = i || this.getActive();
+ if( !i ) return;
+ i.textInput.setReadOnly( false );
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Disable editor
+ //
+ // Parameters:
+ // i - {Editor} (Defaults to active editor)
+ //
+ //////////////////////////////////////////////////////////////////
+
+ disableEditing: function( i ) {
+ i = i || this.getActive();
+ if( !i ) return;
+ i.textInput.setReadOnly( true );
+ },
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // Set Overscroll
+ //
+ // Parameters:
+ // i - {Editor} (Defaults to active editor)
+ //
+ //////////////////////////////////////////////////////////////////
+
+ setOverScroll: function( s, i ) {
+
+ if( i ) {
+ i.setOption( "scrollPastEnd", s );
+ } else {
+ this.settings.overScroll = s;
+ this.forEach( function( i ) {
+ i.setOption( "scrollPastEnd", s );
+ });
+ }
+ //Database
+ //codiad.settings.update_option( 'codiad.editor.overScroll', s );
+ },
+
+ setLiveAutocomplete: function( s, i ) {
+
+ if( i ) {
+ i.setOptions( {
+ enableLiveAutocompletion: s
+ });
+ } else {
+ this.settings.autocomplete = s;
+ this.forEach( function( i ) {
+ i.setOptions( {
+ enableLiveAutocompletion: s
+ });
+ });
+ }
+ //Database
+ //codiad.settings.update_option( 'codiad.editor.autocomplete', s );
+ },
+
+ toggleMultiLine: function( e ) {
+
+ if( e.innerText === "Multi Line" ) {
+
+ this.multi_line = true;
+ e.innerText = "Single Line";
+ $( 'input[name="find"]' ).hide();
+ $( 'textarea[name="find"]' ).show();
+ $( 'textarea[name="find"]' ).val( $( 'input[name="find"]' ).val() );
+
+ $( 'input[name="replace"]' ).hide();
+ $( 'textarea[name="replace"]' ).show();
+ $( 'textarea[name="replace"]' ).val( $( 'input[name="replace"]' ).val() );
+ } else {
+
+ this.multi_line = false;
+ e.innerText = "Multi Line";
+ $( 'input[name="find"]' ).show();
+ $( 'textarea[name="find"]' ).hide();
+ $( 'input[name="find"]' ).val( $( 'textarea[name="find"]' ).val() );
+
+ $( 'input[name="replace"]' ).show();
+ $( 'textarea[name="replace"]' ).hide();
+ $( 'input[name="replace"]' ).val( $( 'textarea[name="replace"]' ).val() );
+ }
+ },
+
+ paste: function() {
+
+ navigator.clipboard.readText().then( text => {
+ codiad.editor.getActive().insert( text )
+ });
+ },
+
+ openSort: function() {
+
+ if( this.getActive() && codiad.active.getSelectedText() != "" ) {
+
+ codiad.modal.load( 400, 'components/editor/dialog.php?action=sort' );
+ codiad.modal.hideOverlay();
+ } else {
+
+ codiad.message.error( 'No text selected' );
+ }
+ },
+
+ sort: function( eol ) {
+
+ let text = $( '#modal textarea[name="sort"]' ).val();
+ let array = text.split( eol );
+ array = array.sort( codiad.editor.sort_a );
+ let sorted = array.join( eol );
+
+ console.log( text, eol, array, sorted );
+ codiad.modal.unload();
+ codiad.editor.getActive().insert( sorted );
+ codiad.editor.getActive().focus();
+ },
+
+ sort_a: function( a, b ) {
+
+ let pos = 0;
+ let case_sensitive = $( '#modal input[name="case_sensitive"]' ).prop( 'checked' )
+
+ if( !case_sensitive ) {
+
+ a = a.toLowerCase();
+ b = b.toLowerCase();
+ }
+
+ if( a < b ) {
+
+ pos = -1;
+ } else if( a > b ) {
+
+ pos = 1;
+ }
+
+ return pos;
+ }
+ };
+
+})( this, jQuery );
diff --git a/components/filemanager/init.js b/components/filemanager/init.js
index 5355a7b..42471b6 100755
--- a/components/filemanager/init.js
+++ b/components/filemanager/init.js
@@ -387,18 +387,18 @@
var appendage = '
';
$.each( files, function( index ) {
var ext = '';
- var name = files[ index ].name.replace( path, '' );
+ var name = files[index].name.replace( path, '' );
var nodeClass = 'none';
name = name.split( '/' )
.join( ' ' );
- if( files[ index ].type == 'file' ) {
+ if( files[index].type == 'file' ) {
var ext = ' ext-' + name.split( '.' )
.pop();
}
- if( files[ index ].type == 'directory' && files[ index ].size > 0 ) {
+ if( files[index].type == 'directory' && files[index].size > 0 ) {
nodeClass = 'plus';
}
- appendage += '- ' + name + '
';
+ appendage += '- ' + name + '
';
});
appendage += '
';
if( rescan ) {
@@ -416,7 +416,7 @@
}
node.removeClass( 'loading' );
if( rescan && _this.rescanChildren.length > _this.rescanCounter ) {
- _this.rescan( _this.rescanChildren[ _this.rescanCounter++ ] );
+ _this.rescan( _this.rescanChildren[_this.rescanCounter++] );
} else {
_this.rescanChildren = [];
_this.rescanCounter = 0;
@@ -578,7 +578,7 @@
codiad.message.error( i18n( 'File could not be saved' ) );
if( typeof callbacks.error === 'function' ) {
var context = callbacks.context || _this;
- callbacks.error.apply( context, [ data ] );
+ callbacks.error.apply( context, [data] );
}
}
$.post( this.controller + '?action=modify&path=' + encodeURIComponent( path ), data, function( resp ) {
@@ -611,7 +611,7 @@
} 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 ] );
+ callbacks.error.apply( context, [resp.data] );
}
}
}).error( notifySaveErr );
@@ -778,7 +778,7 @@
var arr = path.split( '/' );
var temp = new Array();
for( i = 0; i < arr.length - 1; i++ ) {
- temp.push( arr[ i ] )
+ temp.push( arr[i] )
}
var newPath = temp.join( '/' ) + '/' + newName;
$.get( _this.controller, {
@@ -969,12 +969,12 @@
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 );
+ if( val['file'].substr( -1 ) == '/' ) {
+ val['file'] = val['file'].substr( 0, str.length - 1 );
}
- val[ 'file' ] = val[ 'file' ].replace( '//', '/' );
+ val['file'] = val['file'].replace( '//', '/' );
// Add result
- results += '
';
+ results += '
';
});
$( '#filemanager-search-results' )
.slideDown()