editor.js 6.6 KB

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