BxBaseEditorQuill.php 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) UNA, Inc - https://una.io
  4. * MIT License - https://opensource.org/licenses/MIT
  5. *
  6. * @defgroup UnaBaseView UNA Base Representation Classes
  7. * @{
  8. */
  9. /**
  10. * Quill editor representation.
  11. * @see BxDolEditor
  12. */
  13. class BxBaseEditorQuill extends BxDolEditor
  14. {
  15. /**
  16. * Common initialization params
  17. */
  18. protected static $CONF_COMMON = <<<EOS
  19. hljs.configure({ // optionally configure hljs
  20. languages: ['javascript', 'php', 'html', 'css']
  21. });
  22. $( "{bx_var_selector}" ).after( "<div id='editor_{bx_var_editor_name}' class='bx-def-font-inputs bx-form-input-textarea bx-form-input-html'>" + $( "{bx_var_selector}" ).val() + "</div>" );
  23. $( "{bx_var_selector}" ).hide();
  24. if (typeof bQuillRegistred === 'undefined') {
  25. Quill.register("modules/imageUploader", ImageUploader);
  26. bQuillRegistred = true;
  27. }
  28. var quill_{bx_var_editor_name} = new Quill('#editor_{bx_var_editor_name}', {
  29. theme: '{bx_var_skin}',
  30. modules: {
  31. syntax: true,
  32. toolbar: [{toolbar}],
  33. mention: {
  34. // allowedChars: /^[A-Za-z\sÅÄÖåäö]*$/,
  35. mentionDenotationChars: ["@"],
  36. source: function (searchTerm, renderList, mentionChar) {
  37. $.getJSON('{bx_url_root}searchExtended.php?action=get_authors&', { term: searchTerm}, function(data){
  38. renderList(data, searchTerm);
  39. });
  40. },
  41. renderItem: function(item, searchTerm){
  42. item.value = '<a href="' + item.url + '" target="_blank" >' + item.label + '</a>';
  43. return '<a href="' + item.url + '" target="_blank" >@' + item.label + '</a>';
  44. },
  45. onSelect: function(item, insertItem){
  46. insertItem(item)
  47. }
  48. },
  49. imageUploader: {
  50. upload: file => {
  51. return new Promise((resolve, reject) => {
  52. const formData = new FormData();
  53. formData.append("file", file);
  54. fetch("{bx_url_root}storage.php?o=sys_images_editor&t=sys_images_editor&a=upload", {
  55. method: "POST",
  56. body: formData
  57. }
  58. )
  59. .then(response => response.json())
  60. .then(result => {
  61. console.log(result);
  62. resolve(result.link);
  63. })
  64. .catch(error => {
  65. reject("Upload failed");
  66. console.error("Error:", error);
  67. });
  68. });
  69. }
  70. }
  71. }
  72. });
  73. quill_{bx_var_editor_name}.on('text-change', function(delta, oldDelta, source) {
  74. $('{bx_var_selector}').val(quill_{bx_var_editor_name}.container.firstChild.innerHTML);
  75. });
  76. EOS;
  77. /**
  78. * Standard view initialization params
  79. */
  80. protected static $CONF_STANDARD = "";
  81. /**
  82. * Minimal view initialization params
  83. */
  84. protected static $CONF_MINI = "";
  85. /**
  86. * Full view initialization params
  87. */
  88. protected static $CONF_FULL = "";
  89. protected $_oTemplate;
  90. protected $_bJsCssAdded = false;
  91. public function __construct ($aObject, $oTemplate)
  92. {
  93. parent::__construct ($aObject);
  94. if ($oTemplate)
  95. $this->_oTemplate = $oTemplate;
  96. else
  97. $this->_oTemplate = BxDolTemplate::getInstance();
  98. }
  99. /**
  100. * Attach editor to HTML element, in most cases - textarea.
  101. * @param $sSelector - jQuery selector to attach editor to.
  102. * @param $iViewMode - editor view mode: BX_EDITOR_STANDARD, BX_EDITOR_MINI, BX_EDITOR_FULL
  103. * @param $bDynamicMode - is AJAX mode or not, the HTML with editor area is loaded dynamically.
  104. */
  105. public function attachEditor ($sSelector, $iViewMode = BX_EDITOR_STANDARD, $bDynamicMode = false, $aAttrs = [])
  106. {
  107. // set visual mode
  108. switch ($iViewMode) {
  109. case BX_EDITOR_MINI:
  110. $sToolbarItems = getParam('sys_quill_toolbar_mini');
  111. $sCustomInit = self::$CONF_MINI;
  112. break;
  113. case BX_EDITOR_FULL:
  114. $sToolbarItems = getParam('sys_quill_toolbar_full');
  115. $sCustomInit = self::$CONF_FULL;
  116. break;
  117. case BX_EDITOR_STANDARD:
  118. default:
  119. $sToolbarItems = getParam('sys_quill_toolbar_standard');
  120. $sCustomInit = self::$CONF_STANDARD;
  121. }
  122. if ($this->_sButtonsCustom !== false) {
  123. $sToolbarItems = $this->_sButtonsCustom;
  124. }
  125. $sCss = 'editor.less';
  126. $aCss = BxDolTemplate::getInstance()->_lessCss(array(
  127. 'path' => $this->_oTemplate->getCssPath($sCss),
  128. 'url' => $this->_oTemplate->getCssUrl($sCss)
  129. ));
  130. // initialize editor
  131. $sInitEditor = $this->_replaceMarkers(self::$CONF_COMMON, array(
  132. 'bx_var_custom_init' => $sCustomInit,
  133. 'bx_var_selector' => bx_js_string($sSelector, BX_ESCAPE_STR_APOS),
  134. 'bx_var_form_id' => $aAttrs['form_id'],
  135. 'toolbar' => $sToolbarItems ? $sToolbarItems : "[]",
  136. 'bx_var_element_name' => str_replace(['-', ' '], '_', $aAttrs['element_name']),
  137. 'bx_var_editor_name' => str_replace(['-', ' '], '_', $aAttrs['form_id'] . '_' . $aAttrs['element_name']),
  138. 'bx_var_skin' => bx_js_string($this->_aObject['skin'], BX_ESCAPE_STR_APOS),
  139. 'bx_url_root' => bx_js_string(BX_DOL_URL_ROOT, BX_ESCAPE_STR_APOS),
  140. 'bx_var_css_path' => bx_js_string($aCss['url'], BX_ESCAPE_STR_APOS),
  141. ));
  142. if ($bDynamicMode) {
  143. list($aJs, $aCss) = $this->_getJsCss(true);
  144. $sCss = $this->_oTemplate->addCss($aCss, true);
  145. $sCss = $this->_oTemplate->addCss([
  146. BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'quill/|quill.' . $this->_aObject['skin'] . '.css',
  147. BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'quill/|quill.custom.css',
  148. BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'quill/|quill.mention.css',
  149. BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'highlight/|default.min.css',
  150. BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'quill/quill.imageUploader.min.css'
  151. ], true);
  152. $sScript = $sCss . "<script>
  153. if (typeof bQuillEditorInited === 'undefined') {
  154. bx_get_scripts(" . json_encode($aJs) . ", function () {
  155. bQuillEditorInited = true;
  156. $sInitEditor
  157. });
  158. } else {
  159. setTimeout(function () {
  160. console.log(999);
  161. $sInitEditor
  162. }, 10); // wait while html is rendered in case of dynamic adding html with tinymce
  163. }
  164. if (typeof bQuillEditorInited === 'undefined')
  165. bQuillEditorInited = true;
  166. </script>";
  167. } else {
  168. $sScript = "
  169. <script>
  170. $(document).ready(function () {
  171. $sInitEditor
  172. });
  173. </script>";
  174. }
  175. return $this->_addJsCss($bDynamicMode) . $sScript;
  176. }
  177. /**
  178. * Add css/js files which are needed for editor display and functionality.
  179. */
  180. protected function _addJsCss($bDynamicMode = false, $sInitEditor = '')
  181. {
  182. if ($bDynamicMode)
  183. return '';
  184. if ($this->_bJsCssAdded)
  185. return '';
  186. list($aJs, $aCss) = $this->_getJsCss();
  187. $this->_oTemplate->addJs($aJs);
  188. $this->_oTemplate->addCss($aCss);
  189. $this->_bJsCssAdded = true;
  190. return '';
  191. }
  192. protected function _getJsCss($bUseUrlsForJs = false)
  193. {
  194. $sJsPrefix = $bUseUrlsForJs ? BX_DOL_URL_PLUGINS_PUBLIC : BX_DIRECTORY_PATH_PLUGINS_PUBLIC;
  195. $sJsSuffix = $bUseUrlsForJs ? '' : '|';
  196. $aJs = array(
  197. $sJsPrefix . 'highlight/' . $sJsSuffix . 'highlight.min.js',
  198. $sJsPrefix . 'quill/' . $sJsSuffix . 'quill.min.js',
  199. $sJsPrefix . 'quill/' . $sJsSuffix . 'quill.mention.js',
  200. $sJsPrefix . 'quill/' . $sJsSuffix . 'quill.imageUploader.min.js'
  201. );
  202. $aCss = array(
  203. BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'quill/|quill.' . $this->_aObject['skin'] . '.css',
  204. BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'quill/|quill.custom.css',
  205. BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'quill/|quill.mention.css',
  206. BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'highlight/|default.min.css',
  207. BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'quill/quill.imageUploader.min.css'
  208. );
  209. return array($aJs, $aCss);
  210. }
  211. }
  212. /** @} */