editor.js 7.7 KB

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