editor.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. $(document).ready(function() {
  2. var $editor = $('#editor');
  3. var $editorJs = $('#editor-javascript');
  4. var $editorHtml = $('#editor-html');
  5. var $htmlContent = $('#html-content');
  6. var $selectorNav = $('#selector');
  7. var $fileSelect = $('#file-select');
  8. var $addExampleBtn = $('#add-example-btn');
  9. var $exampleForm = $('#add-example-form');
  10. var $exampleSave = $('#add-example-save');
  11. var $exampleCancel = $('#add-example-cancel');
  12. var $saveChanges = $('#save-changes');
  13. var $notification = $('#notification');
  14. var $leftPanel = $(".panel-left");
  15. var $window = $(window);
  16. var activeMode = 'html';
  17. var currentHash;
  18. var editor;
  19. var editorStorage = new LocalStorageDraft();
  20. var saveTimeout1;
  21. var saveTimeout2;
  22. var exampleList;
  23. $leftPanel.resizable({
  24. handleSelector: ".splitter",
  25. resizeHeight: false,
  26. onDrag: function(e) {
  27. $editor.width($leftPanel.width());
  28. }
  29. });
  30. $window.resize(function() {
  31. $editor.width($leftPanel.width());
  32. $(".panel-container").height($(window).height());
  33. });
  34. $(".panel-container").height($(window).height());
  35. $editor.width($leftPanel.width());
  36. editor = ace.edit("editor");
  37. editor.setTheme("ace/theme/eclipse");
  38. editor.$blockScrolling = Infinity;
  39. editor.getSession().setUseWrapMode(true);
  40. function setCurrentHash(slug) {
  41. // console.log('setCurrentHash', slug)
  42. if(slug) {
  43. // console.log('save current hash', slug);
  44. window.location.hash = currentHash = slug;
  45. }
  46. else {
  47. currentHash = window.location.hash ?
  48. window.location.hash.substr(1) : undefined;
  49. // if(currentHash) console.log('restored current hash', currentHash);
  50. }
  51. }
  52. function setEditorMode(mode) {
  53. editor.getSession().setMode("ace/mode/" + mode);
  54. }
  55. function saveToLocalStorage() {
  56. var editorContent = editor.getSession().getValue();
  57. // console.log('saveToLocalStorage', activeMode, editorContent.substr(0, 10) + '[...]');
  58. editorStorage.saveSource(activeMode, editorContent);
  59. saveTimeout = undefined;
  60. }
  61. function editorContentChanged() {
  62. // console.log('editorContent changed')
  63. if(saveTimeout1 || saveTimeout2) {
  64. clearTimeout(saveTimeout1);
  65. clearTimeout(saveTimeout2);
  66. }
  67. saveTimeout1 = setTimeout(saveToLocalStorage, 500);
  68. // saveTimeout2 = setTimeout(saveChanges, 1000);
  69. }
  70. editor.getSession().on('change', editorContentChanged);
  71. function setActiveTab(mode) {
  72. // console.log('setting mode', mode);
  73. var elementId = 'show-' + mode;
  74. $('#show-' + activeMode).removeClass('active');
  75. activeMode = mode;
  76. $('#' + elementId).addClass('active');
  77. var ed = $('#editor-' + mode);
  78. setEditorMode(mode);
  79. editor.getSession().off('change');
  80. editor.getSession().setValue(ed[0].innerHTML);
  81. editor.getSession().on('change', editorContentChanged);
  82. }
  83. $('#tabs button').click(function() {
  84. saveToLocalStorage();
  85. var mode = $(this).prop('id').substr(5);
  86. setActiveTab(mode);
  87. })
  88. function loadAsync(url, dataType) {
  89. return new Promise(function(resolve, reject) {
  90. $.ajax({
  91. type: 'GET',
  92. url: url,
  93. success: function(data) {
  94. resolve(data);
  95. },
  96. error: function(jqXHR) {
  97. reject(new Error(jqXHR.responseText));
  98. }
  99. }, dataType);
  100. });
  101. }
  102. function loadExample(exampleSlug) {
  103. // console.log('loadExample', exampleSlug);
  104. var serverPath = 'exemples/' + exampleSlug + '/';
  105. loadAsync(serverPath + 'script.js', 'text')
  106. .then(javascript => $editorJs.html(javascript))
  107. .then(() => loadAsync(serverPath + '/contenu.html', 'text'))
  108. .then(html => {
  109. $editorHtml.html(html);
  110. setHtmlContent(html);
  111. setActiveTab('html');
  112. setCurrentHash(exampleSlug);
  113. var sources = {
  114. html: $editorHtml.html(),
  115. javascript: $editorJs.html()
  116. };
  117. editorStorage.init(exampleSlug, sources);
  118. loadJS(serverPath + 'script.js');
  119. })
  120. .then(() => {
  121. var item = _.find(exampleList, { slug: exampleSlug });
  122. // console.log(item.test ? 'test' : 'no test');
  123. // loadJS('exemples/' + item.slug + '/test.js', function() {
  124. // $('#tests').show();
  125. // });
  126. });
  127. }
  128. function addFileSelectItem(item) {
  129. $fileSelect.append(
  130. '<option value="' + item.slug + '">' +
  131. item.title +
  132. '</option>'
  133. );
  134. }
  135. function loadExampleList() {
  136. $.get('exemples/liste.json', function(_exampleList) {
  137. exampleList = _exampleList;
  138. var restoredDraft;
  139. exampleList.forEach(addFileSelectItem);
  140. if(currentHash) {
  141. $fileSelect.val(currentHash);
  142. var item = _.find(exampleList, { slug: currentHash });
  143. if( ! item) {
  144. return;
  145. }
  146. restoredDraft = editorStorage.restore(item.slug);
  147. if(! restoredDraft) {
  148. loadExample(item.slug);
  149. }
  150. else {
  151. $editorHtml.html(restoredDraft.sources.html);
  152. setHtmlContent(restoredDraft.sources.html);
  153. $editorJs.html(restoredDraft.sources.javascript);
  154. loadJS('exemples/' + item.slug + '/script.js');
  155. // if(item.test) {
  156. // loadJS('exemples/' + item.slug + '/test.js', function() {
  157. // $('#tests').show();
  158. // });
  159. // }
  160. setActiveTab('html');
  161. }
  162. }
  163. }, 'json');
  164. }
  165. function setHtmlContent(html) {
  166. $htmlContent.empty();
  167. $htmlContent.html(html);
  168. }
  169. function notify(type, text) {
  170. $notification
  171. .addClass(type)
  172. .addClass('active');
  173. $notification.html(text);
  174. setTimeout(function() {
  175. $notification.removeClass('active');
  176. }, 2000);
  177. setTimeout(function() {
  178. $notification.removeClass(type);
  179. }, 3000);
  180. }
  181. function toggleEditor() {
  182. $addExampleBtn.toggle();
  183. $selectorNav.toggle();
  184. $exampleForm.toggle();
  185. }
  186. function saveExample(e) {
  187. e.preventDefault();
  188. var title = $(this).find('input[name="title"]').val();
  189. $.ajax({
  190. type: 'POST',
  191. url: '/examples',
  192. data: JSON.stringify({ title }),
  193. success: function(newExample) {
  194. clearAndCloseEditor();
  195. addFileSelectItem(newExample);
  196. $fileSelect.val(newExample.slug);
  197. $fileSelect.trigger('change');
  198. notify('success', "Exemple créé !");
  199. },
  200. error: function(jqXHR, textStatus, errorThrown ) {
  201. notify('error', 'Erreur: ' + jqXHR.responseText);
  202. },
  203. contentType: 'application/json',
  204. dataType: 'json'
  205. });
  206. }
  207. function clearAndCloseEditor() {
  208. $exampleForm.find('input').val('');
  209. toggleEditor();
  210. }
  211. function saveChanges() {
  212. var payload = editorStorage.getSources();
  213. $.ajax({
  214. type: 'PUT',
  215. url: '/examples/' + currentHash,
  216. data: JSON.stringify(payload),
  217. success: function(newExample) {
  218. notify('success', "Exemple sauvegardé !");
  219. loadExample(currentHash);
  220. },
  221. error: function(jqXHR, textStatus, errorThrown ) {
  222. notify('error', 'Erreur: ' + jqXHR.responseText);
  223. },
  224. contentType: 'application/json',
  225. dataType: 'json'
  226. });
  227. }
  228. setCurrentHash();
  229. $fileSelect.change(function() {
  230. loadExample($(this).val());
  231. });
  232. $addExampleBtn.click(toggleEditor);
  233. $exampleCancel.click(clearAndCloseEditor);
  234. $saveChanges.click(saveChanges);
  235. $exampleForm.submit(saveExample);
  236. loadExampleList();
  237. });