index.html 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset='utf-8' />
  5. <meta name="viewport" content="width=device-width, user-scalable=no" />
  6. <title>Thread App Tracim</title>
  7. <link rel='shortcut icon' href='favicon.ico'>
  8. <link rel="stylesheet" type="text/css" href="./font/font-awesome-4.7.0/css/font-awesome.css">
  9. <link href="https://fonts.googleapis.com/css?family=Quicksand:300,400,500,700" rel="stylesheet">
  10. <link rel="stylesheet" type="text/css" href="./dev/bootstrap-4.0.0-beta.css">
  11. </head>
  12. <body>
  13. <script src="./dev/jquery-3.2.1.js"></script>
  14. <script src="./dev/popper-1.12.3.js"></script>
  15. <script src="./dev/bootstrap-4.0.0-beta.2.js"></script>
  16. <div id='content'></div>
  17. <script src='./thread.app.dev.js'></script>
  18. <script type='text/javascript'>
  19. GLOBAL_renderApp = app => {
  20. switch (app.appData.name) {
  21. case 'PageHtml':
  22. appPageHtml.renderApp('appContainer'); break
  23. case 'Thread':
  24. appThread.renderApp('appContainer'); break
  25. }
  26. }
  27. GLOBAL_dispatchEvent = (data) => {
  28. var event = new CustomEvent('appCustomEvent', {detail: data})
  29. document.dispatchEvent(event)
  30. }
  31. GLOBAL_unmountApp = () => {
  32. switch (appName) {
  33. case 'PageHtml':
  34. appPageHtml.hideApp('appContainer'); break
  35. case 'Thread':
  36. appThread.hideApp('appContainer'); break
  37. }
  38. }
  39. // only usefull if app doesn't handle fileContent himself
  40. GLOBAL_handleRequireRedraw = () => {
  41. var rez = appA.destroyApp('app')
  42. if (rez) GLOBAL_drawApp('redraw')
  43. else console.log('Erreur, failed at destroying app')
  44. }
  45. </script>
  46. <script type='text/javascript'>
  47. // appPageHtml.renderApp('content')
  48. </script>
  49. <script type="text/javascript" src="/asset/tinymce/jquery.tinymce.min.js"></script>
  50. <script type="text/javascript" src="/asset/tinymce/tinymce.min.js"></script>
  51. <script type='text/javascript'>
  52. if (window.matchMedia("(min-width:1200px)").matches) {
  53. var jsScript = document.createElement("script");
  54. jsScript.type = "text/javascript";
  55. jsScript.src = "https://cloud.tinymce.com/stable/tinymce.min.js?apiKey=dfdhxdokxj2wagzkbxfgysgh86d6rr9m3dln0172vo3shipc";
  56. jsScript.onload = function() {
  57. function base64EncodeAndTinyMceInsert (files) {
  58. for (var i = 0; i < files.length; i++) {
  59. if (files[i].size > 1000000)
  60. files[i].allowed = confirm(files[i].name + " fait plus de 1mo et peut prendre du temps à insérer, voulez-vous continuer ?")
  61. }
  62. for (var i = 0; i < files.length; i++) {
  63. if (files[i].allowed !== false && files[i].type.match('image.*')) {
  64. var img = document.createElement('img')
  65. var fr = new FileReader()
  66. fr.readAsDataURL(files[i])
  67. fr.onloadend = function (e) {
  68. img.src = e.target.result
  69. tinymce.activeEditor.execCommand('mceInsertContent', false, img.outerHTML)
  70. }
  71. }
  72. }
  73. }
  74. // HACK: The tiny mce source code modal contain a textarea, but we
  75. // can't edit it (like it's readonly). The following solution
  76. // solve the bug: https://stackoverflow.com/questions/36952148/tinymce-code-editor-is-readonly-in-jtable-grid
  77. $(document).on('focusin', function(e) {
  78. if ($(e.target).closest(".mce-window").length) {
  79. e.stopImmediatePropagation();
  80. }
  81. });
  82. tinymce.init({
  83. selector: 'textarea',
  84. height: 130,
  85. // width: 530,
  86. menubar: false,
  87. resize: false,
  88. plugins: [
  89. 'advlist autolink lists link image charmap print preview anchor textcolor',
  90. 'searchreplace visualblocks code fullscreen',
  91. 'insertdatetime media table contextmenu paste code help'
  92. ],
  93. toolbar: 'insert | formatselect | bold italic underline strikethrough forecolor backcolor | link | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | table | code ',
  94. content_css: [
  95. '//fonts.googleapis.com/css?family=Lato:300,300i,400,400i',
  96. '//www.tinymce.com/css/codepen.min.css'
  97. ],
  98. setup: function ($editor) {
  99. //////////////////////////////////////////////
  100. // add custom btn to handle image by selecting them with system explorer
  101. $editor.addButton('customInsertImage', {
  102. icon: 'mce-ico mce-i-image',
  103. title: 'Image',
  104. onclick: function () {
  105. var hiddenTinyMceInput = $('#hidden_tinymce_fileinput')
  106. if (hiddenTinyMceInput.length > 0) hiddenTinyMceInput.remove()
  107. fileTag = document.createElement('input')
  108. fileTag.id = 'hidden_tinymce_fileinput'
  109. fileTag.type = 'file'
  110. $('body').append(fileTag)
  111. hiddenTinyMceInput.on('change', function () {
  112. base64EncodeAndTinyMceInsert($(this)[0].files)
  113. })
  114. hiddenTinyMceInput.click()
  115. }
  116. })
  117. //////////////////////////////////////////////
  118. // Handle drag & drop image into TinyMce by encoding them in base64 (to avoid uploading them somewhere and keep saving comment in string format)
  119. $editor
  120. .on('drag dragstart dragend dragover dragenter dragleave drop', function (e) {
  121. e.preventDefault()
  122. e.stopPropagation()
  123. })
  124. .on('drop', function(e) {
  125. base64EncodeAndTinyMceInsert(e.dataTransfer.files)
  126. })
  127. }
  128. });
  129. }
  130. document.getElementsByTagName("body")[0].appendChild(jsScript);
  131. }
  132. </script>
  133. </body>
  134. </html>