editor.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. function setEditorSize(){
  2. // Sets the size of the text editor window.
  3. fillWindow($('#editor'));
  4. }
  5. function getFileExtension(file){
  6. var parts=file.split('.');
  7. return parts[parts.length-1];
  8. }
  9. function setSyntaxMode(ext){
  10. // Loads the syntax mode files and tells the editor
  11. var filetype = new Array();
  12. // Todo finish these
  13. filetype["h"] = "c_cpp";
  14. filetype["c"] = "c_cpp";
  15. filetype["clj"] = "clojure";
  16. filetype["coffee"] = "coffee"; // coffescript can be compiled to javascript
  17. filetype["coldfusion"] = "cfc";
  18. filetype["cpp"] = "c_cpp";
  19. filetype["cs"] = "csharp";
  20. filetype["css"] = "css";
  21. filetype["groovy"] = "groovy";
  22. filetype["haxe"] = "hx";
  23. filetype["html"] = "html";
  24. filetype["java"] = "java";
  25. filetype["js"] = "javascript";
  26. filetype["json"] = "json";
  27. filetype["latex"] = "latex";
  28. filetype["lua"] = "lua";
  29. filetype["markdown"] = "markdown"; // also: .md .markdown .mdown .mdwn
  30. filetype["ml"] = "ocaml";
  31. filetype["mli"] = "ocaml";
  32. filetype["pl"] = "perl";
  33. filetype["php"] = "php";
  34. filetype["powershell"] = "ps1";
  35. filetype["py"] = "python";
  36. filetype["rb"] = "ruby";
  37. filetype["scad"] = "scad"; // seems to be something like 3d model files printed with e.g. reprap
  38. filetype["scala"] = "scala";
  39. filetype["scss"] = "scss"; // "sassy css"
  40. filetype["sql"] = "sql";
  41. filetype["svg"] = "svg";
  42. filetype["textile"] = "textile"; // related to markdown
  43. filetype["xml"] = "xml";
  44. if(filetype[ext]!=null){
  45. // Then it must be in the array, so load the custom syntax mode
  46. // Set the syntax mode
  47. OC.addScript('files_texteditor','aceeditor/mode-'+filetype[ext], function(){
  48. var SyntaxMode = require("ace/mode/"+filetype[ext]).Mode;
  49. window.aceEditor.getSession().setMode(new SyntaxMode());
  50. });
  51. }
  52. }
  53. function showControls(filename,writeperms){
  54. // Loads the control bar at the top.
  55. $('.actions,#file_action_panel').fadeOut('slow').promise().done(function() {
  56. // Load the new toolbar.
  57. var editorcontrols;
  58. if(writeperms=="true"){
  59. var editorcontrols = '<button id="editor_save">'+t('files_texteditor','Save')+'</button><div class="separator"></div><label for="gotolineval">Go to line:</label><input type="text" id="gotolineval"><div class="separator"></div>';
  60. }
  61. var html = '<label for="editorseachval">Search:</label><input type="text" name="editorsearchval" id="editorsearchval"><div class="separator"></div><button id="editor_close">'+t('files_texteditor','Close')+'</button>';
  62. $('#controls').append(html);
  63. $('#editorbar').fadeIn('slow');
  64. var breadcrumbhtml = '<div class="crumb svg" id="breadcrumb_file" style="background-image:url(&quot;../core/img/breadcrumb.png&quot;)"><p>'+filename+'</p></div>';
  65. $('.actions').before(breadcrumbhtml).before(editorcontrols);
  66. });
  67. }
  68. function bindControlEvents(){
  69. $("#editor_save").die('click',doFileSave).live('click',doFileSave);
  70. $('#editor_close').die('click',hideFileEditor).live('click',hideFileEditor);
  71. $('#gotolineval').die('keyup', goToLine).live('keyup', goToLine);
  72. $('#editorsearchval').die('keyup', doSearch).live('keyup', doSearch);
  73. $('#clearsearchbtn').die('click', resetSearch).live('click', resetSearch);
  74. $('#nextsearchbtn').die('click', nextSearchResult).live('click', nextSearchResult);
  75. }
  76. // returns true or false if the editor is in view or not
  77. function editorIsShown(){
  78. // Not working as intended. Always returns true.
  79. return is_editor_shown;
  80. }
  81. // Moves the editor view to the line number speificed in #gotolineval
  82. function goToLine(){
  83. // Go to the line specified
  84. window.aceEditor.gotoLine($('#gotolineval').val());
  85. }
  86. //resets the search
  87. function resetSearch(){
  88. $('#editorsearchval').val('');
  89. $('#nextsearchbtn').remove();
  90. $('#clearsearchbtn').remove();
  91. window.aceEditor.gotoLine(0);
  92. }
  93. // moves the cursor to the next search resukt
  94. function nextSearchResult(){
  95. window.aceEditor.findNext();
  96. }
  97. // Performs the initial search
  98. function doSearch(){
  99. // check if search box empty?
  100. if($('#editorsearchval').val()==''){
  101. // Hide clear button
  102. window.aceEditor.gotoLine(0);
  103. $('#nextsearchbtn').remove();
  104. $('#clearsearchbtn').remove();
  105. } else {
  106. // New search
  107. // Reset cursor
  108. window.aceEditor.gotoLine(0);
  109. // Do search
  110. window.aceEditor.find($('#editorsearchval').val(),{
  111. backwards: false,
  112. wrap: false,
  113. caseSensitive: false,
  114. wholeWord: false,
  115. regExp: false
  116. });
  117. // Show next and clear buttons
  118. // check if already there
  119. if($('#nextsearchbtn').length==0){
  120. var nextbtnhtml = '<button id="nextsearchbtn">Next</button>';
  121. var clearbtnhtml = '<button id="clearsearchbtn">Clear</button>';
  122. $('#editorsearchval').after(nextbtnhtml).after(clearbtnhtml);
  123. }
  124. }
  125. }
  126. // Tries to save the file.
  127. function doFileSave(){
  128. if(editorIsShown()){
  129. // Get file path
  130. var path = $('#editor').attr('data-dir')+'/'+$('#editor').attr('data-filename');
  131. // Get original mtime
  132. var mtime = $('#editor').attr('data-mtime');
  133. // Show saving spinner
  134. $("#editor_save").die('click',doFileSave);
  135. $('#save_result').remove();
  136. $('#editor_save').text(t('files_texteditor','Saving...'));//after('<img id="saving_icon" src="'+OC.filePath('core','img','loading.gif')+'"></img>');
  137. // Get the data
  138. var filecontents = window.aceEditor.getSession().getValue();
  139. // Send the data
  140. $.post(OC.filePath('files_texteditor','ajax','savefile.php'), { filecontents: filecontents, path: path, mtime: mtime },function(jsondata){
  141. if(jsondata.status!='success'){
  142. // Save failed
  143. $('#editor_save').text(t('files_texteditor','Save'));
  144. $('#editor_save').after('<p id="save_result" style="float: left">Failed to save file</p>');
  145. $("#editor_save").live('click',doFileSave);
  146. } else {
  147. // Save OK
  148. // Update mtime
  149. $('#editor').attr('data-mtime',jsondata.data.mtime);
  150. $('#editor_save').text(t('files_texteditor','Save'));
  151. $("#editor_save").live('click',doFileSave);
  152. }
  153. },'json');
  154. }
  155. };
  156. // Gives the editor focus
  157. function giveEditorFocus(){
  158. window.aceEditor.focus();
  159. };
  160. // Loads the file editor. Accepts two parameters, dir and filename.
  161. function showFileEditor(dir,filename){
  162. if(!editorIsShown()){
  163. // Loads the file editor and display it.
  164. var data = $.getJSON(
  165. OC.filePath('files_texteditor','ajax','loadfile.php'),
  166. {file:filename,dir:dir},
  167. function(result){
  168. if(result.status == 'success'){
  169. // Save mtime
  170. $('#editor').attr('data-mtime', result.data.mtime);
  171. // Initialise the editor
  172. showControls(filename,result.data.write);
  173. $('table').fadeOut('slow', function() {
  174. // Update document title
  175. document.title = filename;
  176. $('#editor').text(result.data.filecontents);
  177. $('#editor').attr('data-dir', dir);
  178. $('#editor').attr('data-filename', filename);
  179. window.aceEditor = ace.edit("editor");
  180. aceEditor.setShowPrintMargin(false);
  181. if(result.data.write=='false'){
  182. aceEditor.setReadOnly(true);
  183. }
  184. setEditorSize();
  185. setSyntaxMode(getFileExtension(filename));
  186. OC.addScript('files_texteditor','aceeditor/theme-clouds', function(){
  187. window.aceEditor.setTheme("ace/theme/clouds");
  188. });
  189. });
  190. } else {
  191. // Failed to get the file.
  192. alert(result.data.message);
  193. }
  194. // End success
  195. }
  196. // End ajax
  197. );
  198. is_editor_shown = true;
  199. }
  200. }
  201. // Fades out the editor.
  202. function hideFileEditor(){
  203. // Fades out editor controls
  204. $('#controls > :not(.actions,#file_access_panel,.crumb),#breadcrumb_file').fadeOut('slow',function(){
  205. $(this).remove();
  206. });
  207. // Fade out editor
  208. $('#editor').fadeOut('slow', function(){
  209. $(this).remove();
  210. // Reset document title
  211. document.title = "ownCloud";
  212. var editorhtml = '<div id="editor"></div>';
  213. $('table').after(editorhtml);
  214. $('.actions,#file_access_panel').fadeIn('slow');
  215. $('table').fadeIn('slow');
  216. });
  217. is_editor_shown = false;
  218. }
  219. // Keyboard Shortcuts
  220. var ctrlBtn = false;
  221. // TODO fix detection of ctrl keyup
  222. // returns true if ctrl+s or cmd+s is being pressed
  223. function checkForSaveKeyPress(e){
  224. if(e.which == 17 || e.which == 91) ctrlBtn=true;
  225. if(e.which == 83 && ctrlBtn == true) {
  226. e.preventDefault();
  227. $('#editor_save').trigger('click');
  228. return false;
  229. }
  230. }
  231. // resizes the editor window
  232. $(window).resize(function() {
  233. setEditorSize();
  234. });
  235. var is_editor_shown = false;
  236. $(document).ready(function(){
  237. if(typeof FileActions!=='undefined'){
  238. FileActions.register('text','Edit','',function(filename){
  239. showFileEditor($('#dir').val(),filename);
  240. });
  241. FileActions.setDefault('text','Edit');
  242. FileActions.register('application/xml','Edit','',function(filename){
  243. showFileEditor($('#dir').val(),filename);
  244. });
  245. FileActions.setDefault('application/xml','Edit');
  246. }
  247. OC.search.customResults.Text=function(row,item){
  248. var text=item.link.substr(item.link.indexOf('file=')+5);
  249. var a=row.find('a');
  250. a.data('file',text);
  251. a.attr('href','#');
  252. a.click(function(){
  253. var file=text.split('/').pop();
  254. var dir=text.substr(0,text.length-file.length-1);
  255. showFileEditor(dir,file);
  256. });
  257. }
  258. // Binds the file save and close editor events, and gotoline button
  259. bindControlEvents();
  260. // Binds the save keyboard shortcut events
  261. //$(document).unbind('keydown').bind('keydown',checkForSaveKeyPress);
  262. });