editor.js 7.3 KB

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