ws-editor.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /* global window,$,ace,setTimeout,rp,_ws */
  2. "use strict";
  3. $(document).ready(function() {
  4. // console.log('ws: init editor');
  5. var $editorWrapper = $('#editor-wrapper');
  6. var $editor = $('#editor');
  7. var $saveChanges = $('#save-changes');
  8. var $revertEditor = $('#revert-editor');
  9. var $panelLeft = $('.panel-left');
  10. // var $panelRight = $('.panel-right');
  11. // var $panelWrap = $('.panel-container');
  12. var $tabItems = $('#tabs li');
  13. var $detailsRepo = $('#details-repo');
  14. var $detailsExmp = $('#details-example');
  15. var $window = $(window);
  16. var activeMode = 'html';
  17. var currentFileIdx;
  18. var editor;
  19. var editorSession;
  20. var editorStorage = new LocalStorageDraft();
  21. // var saveTimeout1;
  22. // var saveTimeout2;
  23. var mapTypes = {
  24. html: 'html', js: 'javascript', css: 'css'
  25. }
  26. _ws.events.on('navToRoot', function() {
  27. $editorWrapper.hide();
  28. $detailsRepo.hide();
  29. $detailsExmp.hide();
  30. });
  31. _ws.events.on('navToRepo', function(repoSlug) {
  32. $editorWrapper.hide();
  33. $detailsRepo.show();
  34. $detailsExmp.hide();
  35. });
  36. // https://stackoverflow.com/questions/93695/best-cross-browser-method-to-capture-ctrls-with-jquery#answer-14180949
  37. $(window).bind('keydown', function(event) {
  38. if (event.ctrlKey || event.metaKey) {
  39. switch (String.fromCharCode(event.which).toLowerCase()) {
  40. case 's':
  41. event.preventDefault();
  42. (onSaveChanges.bind(_ws.ui.tabs))();
  43. break;
  44. }
  45. }
  46. });
  47. // /**
  48. // * Make the left panel resizable
  49. // */
  50. $panelLeft.resizable({
  51. handleSelector: ".splitter",
  52. resizeHeight: false,
  53. onDrag: function(e) {
  54. $editor.width($panelLeft.width());
  55. }
  56. });
  57. function setDefaultEditorContent() {
  58. if(_ws.files.length > 0) {
  59. editorSession.setMode("ace/mode/html");
  60. var firstHtml = _ws.files.find(f => (f.type === 'html'));
  61. _ws.ui.tabs.setActiveTab(firstHtml);
  62. editorSession.setValue(firstHtml.content);
  63. }
  64. }
  65. function initEditor() {
  66. editor = ace.edit("editor");
  67. editorSession = editor.getSession();
  68. editor.setTheme("ace/theme/eclipse");
  69. editor.$blockScrolling = Infinity;
  70. editorSession.setUseWrapMode(true);
  71. editorSession.setOptions({
  72. tabSize: 2,
  73. useSoftTabs: true
  74. });
  75. setDefaultEditorContent();
  76. }
  77. function onTabClicked(e) {
  78. var clickedItem = $(e.target);
  79. var activeTab = _ws.ui.tabs.getActiveTab();
  80. if(activeTab[0] === clickedItem[0] || clickedItem[0].tagName === 'SPAN') {
  81. return true;
  82. }
  83. if(activeTab.hasClass('dirty')) {
  84. var proceed = window.confirm("Vos changements sur " + activeTab.data('name') +
  85. " seront perdus si vous changez de fichier. Continuer tout de même ?");
  86. if(! proceed) {
  87. return;
  88. }
  89. activeTab.removeClass('dirty');
  90. }
  91. var type = clickedItem.data('type');
  92. editorSession.setMode("ace/mode/" + mapTypes[type]);
  93. var name = clickedItem.data('name');
  94. var file = _ws.files.find(f => (f.name === name));
  95. _ws.ui.tabs.setActiveTab(file);
  96. editor.getSession().off('change', _ws.ui.editor.contentChanged);
  97. editorSession.setValue(file.content);
  98. editor.getSession().on('change', _ws.ui.editor.contentChanged);
  99. // saveToLocalStorage();
  100. // var mode = $(this).prop('id').substr(5);
  101. // console.log( .html() );
  102. // setActiveTab(mode);
  103. }
  104. function setFirstActiveTab() {
  105. var firstHtml = _ws.files.find(f => (f.type === 'html'));
  106. this.setActiveTab(firstHtml);
  107. }
  108. _ws.makeView('tabs', {
  109. setActiveTab: function(file) {
  110. this.file = _ws.files.find(f => (f.name === file.name));
  111. if(this.activeTab) {
  112. this.activeTab.removeClass('bold');
  113. }
  114. var idx = this.fileIdx = _ws.files.indexOf(this.file);
  115. this.activeTab = this.$elem.find('li:eq(' + idx + ')');
  116. this.activeTab.addClass('bold');
  117. },
  118. setFirstActiveTab: setFirstActiveTab,
  119. afterRender: setFirstActiveTab,
  120. getActiveTab: function() {
  121. return this.activeTab;
  122. },
  123. events: {
  124. 'click li[data-type]': onTabClicked,
  125. 'click li[data-type] span': onSaveChanges
  126. }
  127. })
  128. initEditor();
  129. _ws.makeView('editor', {
  130. aceEditor: editor,
  131. aceSession: editor.getSession(),
  132. init: function() {
  133. this.aceSession.on('change', this.contentChanged);
  134. },
  135. /**
  136. * React to changes in editor by saving a copy
  137. */
  138. contentChanged: function() {
  139. // console.log('content changed handler', editorSession.getValue());
  140. _ws.ui.tabs.getActiveTab()
  141. .addClass('dirty');
  142. // if(saveTimeout1 || saveTimeout2) {
  143. // clearTimeout(saveTimeout1);
  144. // clearTimeout(saveTimeout2);
  145. // }
  146. // saveTimeout1 = setTimeout(saveToLocalStorage, 500);
  147. // // saveTimeout2 = setTimeout(saveChanges, 1000);
  148. },
  149. render: function() {
  150. // console.log('render editor', this);
  151. setDefaultEditorContent();
  152. $editorWrapper.show();
  153. this.$elem.removeClass('hidden');
  154. }
  155. });
  156. _ws.makeView('sandbox-iframe', {
  157. reload: function() {
  158. var src = this.$elem.prop('src');
  159. this.$elem.prop('src', '/empty.html');
  160. this.$elem.prop('src', src);
  161. },
  162. render: function(src) {
  163. this.$elem.prop('src', src);
  164. }
  165. });
  166. // /**
  167. // * Set editor mode (html, javascript, css)
  168. // */
  169. // function setEditorMode(mode) {
  170. // editor.getSession().setMode("ace/mode/" + mode);
  171. // }
  172. // /**
  173. // * Save a copy in localStorage
  174. // */
  175. // function saveToLocalStorage() {
  176. // var editorContent = editor.getSession().getValue();
  177. // editorStorage.saveSource(activeMode, editorContent);
  178. // saveTimeout1 = undefined;
  179. // }
  180. // function revertEditor() {
  181. // editorStorage.reset();
  182. // location.reload();
  183. // }
  184. function onSaveChanges() {
  185. // console.log('Saving', this.file, editorSession.getValue())
  186. var filename = this.file.name;
  187. // var payload = editorStorage.getSources();
  188. var payload = {
  189. content: editorSession.getValue()
  190. };
  191. // Submit the new file content to server
  192. rp.put('/' + _ws.repo.path + '/examples/' + _ws.example.slug + '/files/' + filename, payload)
  193. .then(function(updatedFile) {
  194. // notify
  195. _ws.notify('success', "Fichier " + filename + " sauvegardé !");
  196. // remove the dirty state on current editor tab
  197. _ws.ui.tabs.getActiveTab().removeClass('dirty');
  198. // replace content with the updated one in _ws.files
  199. var originalFile = _ws.files.find(f => (f.name === updatedFile.name));
  200. var index = _ws.files.indexOf(originalFile);
  201. _ws.files[index].content = updatedFile.content;
  202. // reload sandbox iframe
  203. _ws.ui.sandboxIframe.reload();
  204. })
  205. .catch(function(err) {
  206. // console.error(err);
  207. _ws.notify('error', 'Erreur: ' + err.message);
  208. });
  209. }
  210. // $fileSelect.change(function() {
  211. // loadExample($(this).val());
  212. // });
  213. // $saveChanges.click(saveChanges);
  214. // $revertEditor.click(revertEditor);
  215. // $.get('/menu', menu => $('#site-menu').html(menu), 'html');
  216. // loadExampleList();
  217. });