roman.lesnikov@gmail.com 4 ani în urmă
părinte
comite
00e2c42561

+ 20 - 0
modules/boonex/editor/classes/BxEditorConfig.php

@@ -0,0 +1,20 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup   Editor integration
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxEditorConfig extends BxDolModuleConfig
+{
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+    }
+}
+
+/** @} */

+ 27 - 0
modules/boonex/editor/classes/BxEditorDb.php

@@ -0,0 +1,27 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup   Editor integration
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxEditorDb extends BxDolModuleDb
+{
+    function __construct(&$oConfig)
+    {
+        parent::__construct($oConfig);
+    }
+    
+    public function getSettings ($sMode)
+    {
+        return $this->getOne("SELECT group_concat(`name` ORDER BY `order` SEPARATOR ',') FROM `bx_editor_toolbar_buttons` WHERE `mode` = :mode AND `active` = 1", array(
+            'mode' => $sMode,
+        ));
+    }
+}
+
+/** @} */

+ 169 - 0
modules/boonex/editor/classes/BxEditorEditor.php

@@ -0,0 +1,169 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Editor integration
+ * @ingroup     UnaModules
+ * 
+ * @{
+ */
+
+/**
+ * Editor representation.
+ * @see BxDolEditor
+ */
+class BxEditorEditor extends BxDolEditor
+{
+    protected $_sModule;
+    protected $_oModule;
+    protected $_aButtons;
+
+    /**
+     * Common initialization params
+     */
+    protected static $CONF_COMMON = "
+        var oParams = {   
+			root_url: '{bx_url_root}',
+            bx_url_uploader: '{bx_url_uploader}',
+            name: '{bx_var_editor_name}',
+            selector: '{bx_var_selector}',
+			toolbar: {toolbar},
+			buttons: {buttons},
+			
+        }
+        {bx_var_editor_name} = bx_ex_editor_init({bx_var_editor_name}, oParams);";
+
+    protected $_oTemplate;
+    protected $_bJsCssAdded = false;
+
+    public function __construct ($aObject, $oTemplate)
+    {
+        parent::__construct ($aObject);
+
+        if ($oTemplate)
+            $this->_oTemplate = $oTemplate;
+        else
+            $this->_oTemplate = BxDolTemplate::getInstance();
+        
+        $this->_sModule = 'bx_editor';
+        $this->_oModule = BxDolModule::getInstance($this->_sModule);
+        
+        $this->_aButtons = $this->_oModule->_aButtons;
+    }
+
+    /**
+     * Attach editor to HTML element, in most cases - textarea.
+     * @param $sSelector - jQuery selector to attach editor to.
+     * @param $iViewMode - editor view mode: BX_EDITOR_STANDARD, BX_EDITOR_MINI, BX_EDITOR_FULL
+     * @param $bDynamicMode - is AJAX mode or not, the HTML with editor area is loaded dynamically.
+     */
+    public function attachEditor ($sSelector, $iViewMode = BX_EDITOR_STANDARD, $bDynamicMode = false, $aAttrs = [])
+    {
+        // set visual mode
+        switch ($iViewMode) {
+                
+            case BX_EDITOR_MINI:
+                $sToolbarItems = $this->_oModule->_oDb->getSettings('mini');
+                break;
+                
+            case BX_EDITOR_FULL:
+                $sToolbarItems = $this->_oModule->_oDb->getSettings('full');
+            break;
+                
+            case BX_EDITOR_STANDARD:
+            default:
+                $sToolbarItems = $this->_oModule->_oDb->getSettings('standard');
+        }
+        
+        if ($this->_sButtonsCustom !== false) {
+            $sToolbarItems = $this->_sButtonsCustom;
+        }
+        
+        $sToolbarItems = str_replace(',', "','", $sToolbarItems);
+        $sToolbarItems = str_replace(",'separator',", '],[', $sToolbarItems);
+        $sToolbarItems = "['" . $sToolbarItems . "']";
+        
+        $sEditorName = 'editor_' . str_replace(['-', ' '], '_', $aAttrs['form_id'] . '_' . $aAttrs['element_name']);
+        
+        $this->_oTemplate->addJsTranslation([
+            '_bx_editor_embed_popup_link',
+            '_bx_editor_embed_popup_embed',
+        ]);
+        
+        // initialize editor
+        $sInitEditor = $this->_replaceMarkers(self::$CONF_COMMON, array(
+            'bx_var_selector' => bx_js_string($sSelector, BX_ESCAPE_STR_APOS),
+            'bx_var_query_params' => isset($aAttrs['query_params']) ? json_encode($aAttrs['query_params']) : "''",
+            'bx_var_form_id' => $aAttrs['form_id'],
+            'toolbar' => $sToolbarItems ? '[' . $sToolbarItems . ']' : 'false',
+			'buttons' => json_encode($this->_aButtons),
+            'insert_as_plain_text' => getParam('sys_quill_insert_as_plain_text') == 'on' ? 'true' : 'false',
+            'bx_var_css_additional_class' => $sToolbarItems ? '' : 'bx-form-input-html-quill-empty',
+            'bx_var_element_name' => str_replace(['-', ' '], '_', $aAttrs['element_name']),
+            'bx_var_editor_name' => $sEditorName,
+            'bx_var_skin' => bx_js_string($this->_aObject['skin'], BX_ESCAPE_STR_APOS),
+            'bx_url_root' => bx_js_string(BX_DOL_URL_ROOT, BX_ESCAPE_STR_APOS),
+            'bx_url_uploader' => bx_js_string(BX_DOL_URL_ROOT . "storage.php?o=sys_images_editor&t=sys_images_editor&a=upload", BX_ESCAPE_STR_APOS)
+        ));
+
+        $sInitCallBack = "
+            bQuillEditorInited = true;
+        " . $sInitEditor;
+
+        if ($bDynamicMode) {
+            list($aJs, $aCss) = $this->_getJsCss(true);
+
+            $sScript = "var " . $sEditorName . "; " . $this->_oTemplate->addJsPreloaded($aJs, $sInitCallBack, "typeof bQuillEditorInited === 'undefined'", $sInitEditor);
+            $sScript = $this->_oTemplate->_wrapInTagJsCode($sScript);
+            $sScript = $this->_oTemplate->addCss($aCss, true) . $sScript;
+
+        } else {
+            $sScript = "var " . $sEditorName . "; " . $this->_oTemplate->addJsCodeOnLoad($sInitCallBack);
+            $sScript = $this->_oTemplate->_wrapInTagJsCode($sScript);
+        }
+
+        return $this->_addJsCss($bDynamicMode) . $sScript;
+    }
+    
+
+    /**
+     * Add css/js files which are needed for editor display and functionality.
+     */
+    protected function _addJsCss($bDynamicMode = false, $sInitEditor = '')
+    {
+        if ($bDynamicMode)
+            return '';
+        
+        if ($this->_bJsCssAdded)
+            return '';
+        
+        list($aJs, $aCss) = $this->_getJsCss();
+		
+        $this->_oTemplate->addJs($aJs);
+        $this->_oTemplate->addCss($aCss);
+        
+        $this->_bJsCssAdded = true;
+        
+        return '';
+    }
+    
+    protected function _getJsCss($bUseUrlsForJs = false)
+    {
+		$sJsPrefix = $bUseUrlsForJs ? BX_DOL_URL_MODULES : BX_DIRECTORY_PATH_MODULES;
+		$sJsSuffix = $bUseUrlsForJs ? '' : '|';
+		
+		$aCss = [
+			 BX_DIRECTORY_PATH_MODULES . 'boonex/editor/template/css/|main.css',  
+		];
+		$aJs = [
+            $sJsPrefix . 'boonex/editor/js/' . $sJsSuffix . 'editor.js',
+            'https://unpkg.com/@popperjs/core@2',
+            'https://unpkg.com/tippy.js@6'
+        ];
+		
+        return array($aJs, $aCss);
+    }
+}
+
+/** @} */

+ 42 - 0
modules/boonex/editor/classes/BxEditorGridToolbar.php

@@ -0,0 +1,42 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup   Editor integration
+ * @ingroup    UnaModules
+ *
+ * @{
+ */
+
+class BxEditorGridToolbar extends BxTemplGrid
+{
+    protected $_sModule;
+    protected $_oModule;
+    protected $_sMode;
+    
+    public function __construct ($aOptions, $oTemplate = false)
+    {
+        parent::__construct ($aOptions, $oTemplate);
+        
+        $this->_sModule = 'bx_editor';
+        $this->_oModule = BxDolModule::getInstance($this->_sModule);
+        
+        $this->_sMode = bx_get('page') !== false && bx_get('page') !== 'settings' ? bx_get('page') : 'mini';
+        $this->_aQueryAppend['mode'] = $this->_sMode;
+    }
+
+    protected function _getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage)
+    {
+        $this->_aOptions['source'] .= $this->_oModule->_oDb->prepareAsString(" AND `mode` = ? ", $this->_sMode);
+        return parent::_getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage);
+    }
+
+    protected function _getCellName ($mixedValue, $sKey, $aField, $aRow)
+    {
+        $sName = isset($this->_oModule->_aButtons[$mixedValue]) ? _t($this->_oModule->_aButtons[$mixedValue]['text']) : '';
+        return parent::_getCellDefault($sName, $sKey, $aField, $aRow);
+    }
+}
+
+/** @} */

+ 85 - 0
modules/boonex/editor/classes/BxEditorModule.php

@@ -0,0 +1,85 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Editor integration
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxEditorModule extends BxDolModule
+{
+    public $_aButtons = [];
+    
+	function __construct(&$aModule)
+    {
+        parent::__construct($aModule);
+        
+        $this->_aButtons = [
+			'bold' => ['icon' => 'bold', 'text' => _t('_bx_editor_toolbar_action_bold'), 'command' => 'toggleBold()', 'checkOnSelect' => true],
+			'italic' => ['icon' => 'italic', 'text' => _t('_bx_editor_toolbar_action_italic'), 'command' => 'toggleItalic()', 'checkOnSelect' => true],
+			'underline' => ['icon' => 'underline', 'text' => _t('_bx_editor_toolbar_action_underline'), 'command' => 'toggleUnderline()', 'checkOnSelect' => true],
+			'strike' => ['icon' => 'strikethrough', 'text' => _t('_bx_editor_toolbar_action_strike'), 'command' => 'toggleStrike()', 'checkOnSelect' => true],
+			'subscript' => ['icon' => 'subscript', 'text' => _t('_bx_editor_toolbar_action_subscript'), 'command' => 'toggleSubscript()', 'checkOnSelect' => true],
+			'superscript' => ['icon' => 'superscript', 'text' => _t('_bx_editor_toolbar_action_superscript'), 'command' => 'toggleSuperscript()', 'checkOnSelect' => true],
+			'code' => ['icon' => 'code', 'text' => _t('_bx_editor_toolbar_action_code'), 'command' => 'toggleCode()', 'checkOnSelect' => true],
+			'highlight' => ['icon' => 'highlighter', 'text' => _t('_bx_editor_toolbar_action_highlight'), 'command' => 'toggleHighlight()', 'checkOnSelect' => true],
+			
+			'indent' => ['icon' => 'indent', 'text' => _t('_bx_editor_toolbar_action_indent'), 'command' => 'setBlockquote()'],
+			'outdent' => ['icon' => 'outdent', 'text' => _t('_bx_editor_toolbar_action_outdent'), 'command' => 'unsetBlockquote()'],
+			
+			'bulletList' => ['icon' => 'list-ul', 'text' => _t('_bx_editor_toolbar_action_bullet_list'), 'command' => 'toggleBulletList()', 'checkOnSelect' => true],
+			'orderedList' => ['icon' => 'list-ol', 'text' => _t('_bx_editor_toolbar_action_ordered_list'), 'command' => 'toggleOrderedList()', 'checkOnSelect' => true],
+			
+			'codeBlock' => ['icon' => 'code', 'text' => _t('_bx_editor_toolbar_action_code_block'), 'command' => 'toggleCodeBlock()', 'checkOnSelect' => true],
+			
+			'alignLeft' => ['icon' => 'align-left', 'text' => _t('_bx_editor_toolbar_action_align_left'), 'command' => 'setTextAlign("left")'],
+			'alignCenter' => ['icon' => 'align-center', 'text' => _t('_bx_editor_toolbar_action_align_center'), 'command' => 'setTextAlign("center")'],
+			'alignRight' => ['icon' => 'align-right', 'text' => _t('_bx_editor_toolbar_action_align_right'), 'command' => 'setTextAlign("right")'],
+			'alignJustify' => ['icon' => 'align-justify', 'text' => _t('_bx_editor_toolbar_action_align_justify'), 'command' => 'setTextAlign("justify")'],
+			
+			'h1' => ['text' => _t('_bx_editor_toolbar_action_h1'), 'command' => 'toggleHeading({ level: 1 })'],
+			'h2' => ['text' => _t('_bx_editor_toolbar_action_h2'), 'command' => 'toggleHeading({ level: 2 })'],
+			'h3' => ['text' => _t('_bx_editor_toolbar_action_h3'), 'command' => 'toggleHeading({ level: 3 })'],
+			'h4' => ['text' => _t('_bx_editor_toolbar_action_h4'), 'command' => 'toggleHeading({ level: 4 })'],
+			
+			'link' => ['icon' => 'link', 'text' => _t('_bx_editor_toolbar_action_link'), 'command' => 'bx_ex_editor_add_link(oEditor, oParams)', 'command_ex' => true],
+			'image' => ['icon' => 'image', 'text' => _t('_bx_editor_toolbar_action_image'), 'command' => 'bx_ex_editor_add_image(oEditor, oParams.bx_url_uploader)', 'command_ex' => true],
+			'embed' => ['icon' => 'share-alt', 'text' => _t('_bx_editor_toolbar_action_embed'), 'command' => 'bx_ex_editor_add_embed(oEditor, oParams)', 'command_ex' => true],
+		];
+    }
+
+    public function actionUpload()
+    {
+        header('Content-Type: application/json; charset=utf-8');
+
+        if (!($oStorage = BxDolStorage::getObjectInstance('bx_editor_files'))) {
+            echo json_encode(array('error' => '1'));
+            exit;
+        }
+
+        $iProfileId = bx_get_logged_profile_id();
+
+        if (!($iId = $oStorage->storeFileFromForm($_FILES['file'], false, $iProfileId))) {
+            echo json_encode(array('error' => '1'));
+            exit;
+        }
+
+        $oStorage->afterUploadCleanup($iId, $iProfileId);
+
+        $aFileInfo = $oStorage->getFile($iId);
+        if ($aFileInfo && in_array($aFileInfo['ext'], array('jpg', 'jpeg', 'jpe', 'png'))) {
+            $oTranscoder = BxDolTranscoderImage::getObjectInstance('bx_editor_image');
+            $sUrl = $oTranscoder->getFileUrl($iId);
+        }
+        else {
+            $sUrl = $oStorage->getFileUrlById($iId);
+        }
+
+        echo json_encode(array('link' => $sUrl));
+    }
+}
+
+/** @} */

+ 57 - 0
modules/boonex/editor/classes/BxEditorStudioPage.php

@@ -0,0 +1,57 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup   Editor integration
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxEditorStudioPage extends BxTemplStudioModule
+{
+    protected $_sModule;
+    protected $_oModule;
+
+    function __construct($sModule, $mixedPageName, $sPage = "")
+    {
+        $this->_sModule = 'bx_editor';
+        $this->_oModule = BxDolModule::getInstance($this->_sModule);
+        
+        parent::__construct($sModule, $mixedPageName, $sPage);
+
+        $this->aMenuItems = array(
+            'settings' => array('name' => 'mini', 'icon' => 'battery-empty', 'title' => '_bx_editor_mini'),
+            'standard' => array('name' => 'standard', 'icon' => 'battery-half', 'title' => '_bx_editor_standard'),
+            'full' => array('name' => 'full', 'icon' => 'battery-full', 'title' => '_bx_editor_full'),
+        );
+    }
+    
+    protected function getSettings()
+    {
+        return $this->getGrid('mini');
+    }
+    
+    protected function getStandard()
+    {
+        return $this->getGrid('standard');
+    }
+    
+    protected function getFull()
+    {
+        return $this->getGrid('full');
+    }
+    
+    protected function getGrid($sMode)
+    {
+        $sGrid = 'bx_editor_toolbar';
+        $oGrid = BxDolGrid::getObjectInstance($sGrid, BxDolStudioTemplate::getInstance());
+        if(!$oGrid)
+            return '';
+
+        return $oGrid->getCode();
+    }
+}
+
+/** @} */

+ 20 - 0
modules/boonex/editor/classes/BxEditorTemplate.php

@@ -0,0 +1,20 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup   Editor integration
+ * @ingroup    UnaModules
+ *
+ * @{
+ */
+
+class BxEditorTemplate extends BxDolModuleTemplate
+{
+    function __construct(&$oConfig, &$oDb)
+    {
+        parent::__construct($oConfig, $oDb);
+    }
+}
+
+/** @} */

+ 77 - 0
modules/boonex/editor/install/config.php

@@ -0,0 +1,77 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Editor integration
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'deprecated' => 1,
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_editor',
+    'title' => 'Editor',
+    'note' => 'Editor integration.',
+    'version' => '14.0.0.DEV',
+    'vendor' => 'BoonEx',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '13.0.x'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/editor/',
+    'home_uri' => 'editor',
+
+    'db_prefix' => 'bx_editor_',
+    'class_prefix' => 'BxEditor',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Editor',
+
+	/**
+     * Storage objects to automatically delete files from upon module uninstallation.
+     * Note. Don't add storage objects used in transcoder objects.
+     */
+    'storages' => array(
+    	'bx_editor_files'
+    ),
+    
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    ),
+    'uninstall' => array (
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array(
+        'execute_sql' => 1,
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+);
+
+/** @} */

+ 20 - 0
modules/boonex/editor/install/installer.php

@@ -0,0 +1,20 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Editor integration
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxEditorInstaller extends BxDolStudioInstaller
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}
+
+/** @} */

+ 53 - 0
modules/boonex/editor/install/langs/en.xml

@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+    <string name="_sys_module_editor"><![CDATA[Editor]]></string>
+    <string name="_bx_editor"><![CDATA[Editor]]></string>
+
+    <string name="_bx_editor_setting"><![CDATA[Editor Setting]]></string>
+
+    <string name="_bx_editor_information"><![CDATA[Information]]></string>
+    <string name="_bx_editor_information_block"><![CDATA[]]></string>
+	
+	
+	<string name="_bx_editor_toolbar_action_bold"><![CDATA[Bold]]></string>
+	<string name="_bx_editor_toolbar_action_italic"><![CDATA[Italic]]></string>
+	<string name="_bx_editor_toolbar_action_underline"><![CDATA[Underline]]></string>
+	<string name="_bx_editor_toolbar_action_strike"><![CDATA[Strike]]></string>
+	<string name="_bx_editor_toolbar_action_subscript"><![CDATA[Subscript]]></string>
+	<string name="_bx_editor_toolbar_action_superscript"><![CDATA[Superscript]]></string>
+	<string name="_bx_editor_toolbar_action_code"><![CDATA[Code]]></string>
+	<string name="_bx_editor_toolbar_action_highlight"><![CDATA[Highlight]]></string>
+	<string name="_bx_editor_toolbar_action_indent"><![CDATA[Indent]]></string>
+	<string name="_bx_editor_toolbar_action_outdent"><![CDATA[Outdent]]></string>
+	<string name="_bx_editor_toolbar_action_bullet_list"><![CDATA[Bullet List]]></string>
+	<string name="_bx_editor_toolbar_action_ordered_list"><![CDATA[Ordered List]]></string>
+	<string name="_bx_editor_toolbar_action_code_block"><![CDATA[Code block]]></string>
+	<string name="_bx_editor_toolbar_action_align_left"><![CDATA[Align left]]></string>
+	<string name="_bx_editor_toolbar_action_align_center"><![CDATA[Align center]]></string>
+	<string name="_bx_editor_toolbar_action_align_right"><![CDATA[Align right]]></string>
+	<string name="_bx_editor_toolbar_action_align_justify"><![CDATA[Align justify]]></string>
+	<string name="_bx_editor_toolbar_action_h1"><![CDATA[H1]]></string>
+	<string name="_bx_editor_toolbar_action_h2"><![CDATA[H2]]></string>
+	<string name="_bx_editor_toolbar_action_h3"><![CDATA[H3]]></string>
+	<string name="_bx_editor_toolbar_action_h4"><![CDATA[H4]]></string>
+	<string name="_bx_editor_toolbar_action_link"><![CDATA[Link]]></string>
+	<string name="_bx_editor_toolbar_action_image"><![CDATA[Image]]></string>
+	<string name="_bx_editor_toolbar_action_embed"><![CDATA[Embed]]></string>
+	
+	<string name="_bx_editor_embed_popup_header"><![CDATA[Paste an URL for embed]]></string>
+	<string name="_bx_editor_embed_popup_link"><![CDATA[Paste an URL]]></string>
+    <string name="_bx_editor_embed_popup_embed"><![CDATA[Paste an Embe\d]]></string>
+	
+	<string name="_bx_editor_option_toolbar_mini"><![CDATA[Buttons for mini editor]]></string>
+	<string name="_bx_editor_option_toolbar_standard"><![CDATA[Buttons for standard editor]]></string>
+	<string name="_bx_editor_option_toolbar_full"><![CDATA[Buttons for full editor]]></string>
+    
+    
+    <string name="_bx_editor_mini"><![CDATA[Mini]]></string>
+    <string name="_bx_editor_standard"><![CDATA[Standard]]></string>
+    <string name="_bx_editor_full"><![CDATA[Full]]></string>
+    <string name="_bx_editor_grid_column_title_name"><![CDATA[Name]]></string>
+    <string name="_bx_editor_grid_column_title_icon"><![CDATA[Icon]]></string>
+    
+    	
+</resources>

+ 15 - 0
modules/boonex/editor/install/sql/disable.sql

@@ -0,0 +1,15 @@
+-- Settings
+DELETE FROM `top`, `toc`, `to` USING `sys_options_types` AS `top` LEFT JOIN `sys_options_categories` AS `toc` ON `top`.`id`=`toc`.`type_id` LEFT JOIN `sys_options` AS `to` ON `toc`.`id`=`to`.`category_id` WHERE `top`.`name` = 'bx_editor';
+
+-- Editor
+DELETE FROM `sys_objects_editor` WHERE `object` = 'bx_editor';
+
+UPDATE `sys_options` SET `value` = 'sys_quill' WHERE `name` = 'sys_editor_default';
+
+-- Injections
+DELETE FROM `sys_injections` WHERE `name` IN('bx_editor');
+
+-- GRIDS
+DELETE FROM `sys_objects_grid` WHERE `object` LIKE 'bx_editor_toolbar%';
+DELETE FROM `sys_grid_fields` WHERE `object` LIKE 'bx_editor_toolbar%';
+DELETE FROM `sys_grid_actions` WHERE `object` LIKE 'bx_editor_toolbar%';

+ 39 - 0
modules/boonex/editor/install/sql/enable.sql

@@ -0,0 +1,39 @@
+-- Settings
+
+SET @iTypeOrder = (SELECT MAX(`order`) FROM `sys_options_types` WHERE `group` = 'modules');
+INSERT INTO `sys_options_types` (`group`, `name`, `caption`, `icon`, `order`) VALUES 
+('modules', 'bx_editor', '_bx_editor_adm_stg_cpt_type', 'bx_editor@modules/boonex/editor/|std-icon.svg', IF(NOT ISNULL(@iTypeOrder), @iTypeOrder + 1, 1));
+SET @iTypeId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options_categories` (`type_id`, `name`, `caption`, `order` )  
+VALUES (@iTypeId, 'bx_editor_general', '_bx_editor_adm_stg_cpt_category_general', 1);
+SET @iCategId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
+
+('bx_editor_option_toolbar_mini', "['bold', 'italic', 'underline','strike','subscript','superscript','code','highlight'],['indent','outdent', 'bulletList', 'codeBlock', 'orderedList'],['alignLeft','alignCenter','alignRight','alignJustify'],['h1','h2','h3','h4'],['link','image','embed']", @iCategId, '_bx_editor_option_toolbar_mini', 'digit', '', '', '', 1),
+
+('bx_editor_option_toolbar_standard', "['bold', 'italic', 'underline','strike','subscript','superscript','code','highlight'],['indent','outdent', 'bulletList', 'codeBlock', 'orderedList'],['alignLeft','alignCenter','alignRight','alignJustify'],['h1','h2','h3','h4'],['link','image','embed']", @iCategId, '_bx_editor_option_toolbar_standard', 'digit', '', '', '', 2),
+('bx_editor_option_toolbar_full', "['bold', 'italic', 'underline','strike','subscript','superscript','code','highlight'],['indent','outdent', 'bulletList', 'codeBlock', 'orderedList'],['alignLeft','alignCenter','alignRight','alignJustify'],['h1','h2','h3','h4'],['link','image','embed']", @iCategId, '_bx_editor_option_toolbar_full', 'digit', '', '', '', 3);
+
+-- Editor
+
+INSERT INTO `sys_objects_editor` (`object`, `title`, `skin`, `override_class_name`, `override_class_file`) VALUES
+('bx_editor', 'editor', '', 'BxEditorEditor', 'modules/boonex/editor/classes/BxEditorEditor.php');
+
+UPDATE `sys_options` SET `value` = 'bx_editor' WHERE `name` = 'sys_editor_default';
+
+-- Injections
+
+INSERT INTO `sys_injections` (`name`, `page_index`, `key`, `type`, `data`, `replace`, `active`) VALUES
+('bx_editor', 0, 'injection_footer', 'service', 'a:2:{s:6:"module";s:9:"bx_editor";s:6:"method";s:9:"injection";}', 0, 1);
+
+-- GRIDS: administration
+INSERT INTO `sys_objects_grid` (`object`, `source_type`, `source`, `table`, `field_id`, `field_order`, `field_active`, `paginate_url`, `paginate_per_page`, `paginate_simple`, `paginate_get_start`, `paginate_get_per_page`, `filter_fields`, `filter_fields_translatable`, `filter_mode`, `sorting_fields`, `sorting_fields_translatable`, `visible_for_levels`, `show_total_count`, `override_class_name`, `override_class_file`) VALUES
+('bx_editor_toolbar', 'Sql', 'SELECT `ta`.* FROM `bx_editor_toolbar_buttons` AS `ta` WHERE 1 ', 'bx_editor_toolbar_buttons', 'id', 'order', 'active', '', 100, NULL, 'start', '', '', '', 'like', '', '', 2147483647, 1, 'BxEditorGridToolbar', 'modules/boonex/editor/classes/BxEditorGridToolbar.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_editor_toolbar', 'order', '', '2%', 0, '0', '', 1),
+('bx_editor_toolbar', 'switcher', '', '8%', 0, '0', '', 2),
+('bx_editor_toolbar', 'name', '_bx_editor_grid_column_title_name', '70%', 1, '16', '', 3);
+

+ 111 - 0
modules/boonex/editor/install/sql/install.sql

@@ -0,0 +1,111 @@
+-- TABLE: types of categories
+CREATE TABLE IF NOT EXISTS `bx_editor_toolbar_buttons` (
+  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `active` tinyint(4) NOT NULL default '0',
+  `order` tinyint(4) NOT NULL default '0',
+  `name` varchar(64) NOT NULL DEFAULT '',
+  `mode` varchar(10) NOT NULL DEFAULT '',
+  PRIMARY KEY (`id`)
+);
+
+INSERT INTO `bx_editor_toolbar_buttons`(`active`, `order`, `name`, `mode`) VALUES
+(1, 0, 'bold', 'full'),
+(1, 1, 'italic', 'full'),
+(1, 2, 'underline', 'full'),
+(1, 3, 'strike', 'full'),
+(1, 4, 'subscript', 'full'),
+(1, 5, 'superscript', 'full'),
+(1, 6, 'code', 'full'),
+(1, 7, 'highlight', 'full'),
+(1, 8, 'separator', 'full'),
+(1, 9, 'indent', 'full'),
+(1, 10, 'outdent', 'full'),
+(1, 11, 'bulletList', 'full'),
+(1, 12, 'codeBlock', 'full'),
+(1, 13, 'orderedList', 'full'),
+(1, 14, 'separator', 'full'),
+(1, 15, 'alignLeft', 'full'),
+(1, 16, 'alignCenter', 'full'),
+(1, 17, 'alignRight', 'full'),
+(1, 18, 'alignJustify', 'full'),
+(1, 19, 'separator', 'full'),
+(1, 20, 'h1', 'full'),
+(1, 21, 'h2', 'full'),
+(1, 22, 'h3', 'full'),
+(1, 23, 'h4', 'full'),
+(1, 24, 'separator', 'full'),
+(1, 25, 'link', 'full'),
+(1, 26, 'image', 'full'),
+(1, 27, 'embed', 'full'),
+
+(1, 0, 'bold', 'standard'),
+(1, 1, 'italic', 'standard'),
+(1, 2, 'underline', 'standard'),
+(1, 3, 'strike', 'standard'),
+(0, 4, 'subscript', 'standard'),
+(0, 5, 'superscript', 'standard'),
+(0, 6, 'code', 'standard'),
+(0, 7, 'highlight', 'standard'),
+(1, 8, 'separator', 'standard'),
+(0, 9, 'indent', 'standard'),
+(0, 10, 'outdent', 'standard'),
+(1, 11, 'bulletList', 'standard'),
+(0, 12, 'codeBlock', 'standard'),
+(1, 13, 'orderedList', 'standard'),
+(1, 14, 'separator', 'standard'),
+(1, 15, 'alignLeft', 'standard'),
+(1, 16, 'alignCenter', 'standard'),
+(1, 17, 'alignRight', 'standard'),
+(1, 18, 'alignJustify', 'standard'),
+(1, 19, 'separator', 'standard'),
+(1, 20, 'h1', 'standard'),
+(1, 21, 'h2', 'standard'),
+(1, 22, 'h3', 'standard'),
+(1, 23, 'h4', 'standard'),
+(1, 24, 'separator', 'standard'),
+(1, 25, 'link', 'standard'),
+(1, 26, 'image', 'standard'),
+(1, 27, 'embed', 'standard'),
+
+(1, 0, 'bold', 'mini'),
+(1, 1, 'italic', 'mini'),
+(1, 2, 'underline', 'mini'),
+(0, 3, 'strike', 'mini'),
+(0, 4, 'subscript', 'mini'),
+(0, 5, 'superscript', 'mini'),
+(0, 6, 'code', 'mini'),
+(0, 7, 'highlight', 'mini'),
+(0, 8, 'separator', 'mini'),
+(0, 9, 'indent', 'mini'),
+(0, 10, 'outdent', 'mini'),
+(0, 11, 'bulletList', 'mini'),
+(0, 12, 'codeBlock', 'mini'),
+(0, 13, 'orderedList', 'mini'),
+(1, 14, 'separator', 'mini'),
+(1, 15, 'alignLeft', 'mini'),
+(1, 16, 'alignCenter', 'mini'),
+(1, 17, 'alignRight', 'mini'),
+(1, 18, 'alignJustify', 'mini'),
+(0, 19, 'separator', 'mini'),
+(0, 20, 'h1', 'mini'),
+(0, 21, 'h2', 'mini'),
+(0, 22, 'h3', 'mini'),
+(0, 23, 'h4', 'mini'),
+(1, 24, 'separator', 'mini'),
+(1, 25, 'link', 'mini'),
+(1, 26, 'image', 'mini'),
+(1, 27, 'embed', 'mini');
+
+-- Studio page and widget
+
+INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
+(3, 'bx_editor', '_bx_editor', '_bx_editor', 'bx_editor@modules/boonex/editor/|std-icon.svg');
+SET @iPageId = LAST_INSERT_ID();
+
+SET @iParentPageId = (SELECT `id` FROM `sys_std_pages` WHERE `name` = 'home');
+SET @iParentPageOrder = (SELECT MAX(`order`) FROM `sys_std_pages_widgets` WHERE `page_id` = @iParentPageId);
+INSERT INTO `sys_std_widgets` (`page_id`, `module`, `type`, `url`, `click`, `icon`, `caption`, `cnt_notices`, `cnt_actions`) VALUES
+(@iPageId, 'bx_editor', 'integrations', '{url_studio}module.php?name=bx_editor', '', 'bx_editor@modules/boonex/editor/|std-icon.svg', '_bx_editor', '', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:11:"get_actions";s:6:"params";a:0:{}s:5:"class";s:18:"TemplStudioModules";}');
+INSERT INTO `sys_std_pages_widgets` (`page_id`, `widget_id`, `order`) VALUES
+(@iParentPageId, LAST_INSERT_ID(), IF(ISNULL(@iParentPageOrder), 1, @iParentPageOrder + 1));
+

+ 7 - 0
modules/boonex/editor/install/sql/uninstall.sql

@@ -0,0 +1,7 @@
+-- TABLES
+DROP TABLE IF EXISTS `bx_editor_toolbar_buttons`;
+
+-- Studio page and widget
+DELETE FROM `tp`, `tw`, `twb`, `tpw` 
+USING `sys_std_pages` AS `tp` LEFT JOIN `sys_std_widgets` AS `tw` ON `tp`.`id` = `tw`.`page_id` LEFT JOIN `sys_std_widgets_bookmarks` AS `twb` ON `tw`.`id` = `twb`.`widget_id` LEFT JOIN `sys_std_pages_widgets` AS `tpw` ON `tw`.`id` = `tpw`.`widget_id`
+WHERE  `tp`.`name` = 'bx_editor';

+ 162 - 0
modules/boonex/editor/js/editor.js

@@ -0,0 +1,162 @@
+function bx_ex_editor_init(oEditor, oParams)
+{
+	import(sUrlRoot + '/modules/boonex/editor/js/libs.js').then((Module) => {
+		$(oParams.selector).after("<div class=\"mt-px flex items-center p-2 bg-white dark:bg-gray-800 shadow ring-1 ring-gray-300 dark:ring-gray-700 rounded-t-md\"><div id='" + oParams.name + "_toolbar' class='editor_toolbar flex space-x-0.5 w-full justify-start items-center flex-wrap'></div></div><div id='" + oParams.name + "' class='bx-def-font-inputs bx-form-input-textarea bx-form-input-html bx-form-input-html-editor mt-px text-gray-700 dark:text-gray-300  w-full p-4  ring-1 ring-gray-300 dark:ring-gray-700 dark:focus:placeholder-700 bg-gray-50 dark:bg-gray-900/50 placeholder-gray-500 focus:outline-none focus:bg-white dark:focus:bg-gray-900 focus:placeholder-gray-300 dark:focus:placeholder-gray-700  focus:text-gray-900 dark:focus:text-gray-100 text-base border-0 flex-wrap" + oParams.css_class + "'></div>" );
+    	$(oParams.selector).hide();
+		oEditor = new Module.Editor({
+			element: document.querySelector('#' + oParams.name),
+			extensions: [
+				Module.Document, 
+				Module.Paragraph, 
+				Module.Text, 
+				Module.Heading,
+				Module.Bold, 
+				Module.Italic, 
+				Module.Strike,
+				Module.Underline, 
+				Module.Subscript,
+				Module.Superscript, 
+				Module.Blockquote,
+				Module.BulletList,
+				Module.OrderedList,
+				Module.ListItem,
+				Module.Code,
+				Module.Highlight,
+				Module.CodeBlock,
+				Module.Highlight,
+				Module.Heading,
+				Module.Link,
+				Module.Image.configure({
+                  allowBase64: true,
+                }),
+				Module.Mention.configure({
+                    HTMLAttributes: {
+                        class: 'mention',
+                        },
+                    suggestion: {
+                      },
+                }),
+				Module.Span,
+				Module.Iframe,
+				Module.Div,
+				Module.Embed,
+                Module.EventHandler.configure({
+                  uploaderUrl: oParams.bx_url_uploader,
+                }),
+				Module.TextAlign.configure({
+					types: ['heading', 'paragraph'],
+				})
+
+			],
+			editorProps: {
+				attributes: {
+					class: 'prose prose-sm sm:prose lg:prose-lg xl:prose-2xl m-5 focus:outline-none',
+				},
+			},
+			  
+			content: $(oParams.selector).val(),
+			onUpdate({ editor }) {
+				$(oParams.selector).val(editor.getHTML());
+			},
+			onSelectionUpdate({ editor }) {
+				bx_ex_editor_check(editor, oParams);
+			}
+		});
+		
+		oParams.toolbar.forEach(
+			elements => {
+				elements.forEach(
+					element => {
+						var oBtnData = eval("oParams.buttons." + element);
+						if (oBtnData){
+							var oBtn = $('<button title = "' + oBtnData.text + '">' + (oBtnData.icon ? '<i class="sys-icon ' + oBtnData.icon + ' w-5 opacity-70 group-hover:opacity-100"></i>': oBtnData.text) + '</button>').attr({
+								 class: "group justify-center  border border-transparent hover:border-gray-200/50 text-gray-600 dark:text-gray-400 active:bg-gray-300 active:border-gray-300 dark:active:bg-black/50   hover:bg-gray-200/50 dark:hover:text-gray-200 dark:hover:bg-gray-700/50 dark:hover:border-gray-700/50 dark:active:border-gray-700 hover:text-gray-800 flex items-center px-2 py-1.5  text-sm font-medium rounded-md",
+                                 type: 'button',
+								 id: element
+							});
+							$('#' + oParams.name + '_toolbar').append(oBtn);
+							$('#' + oParams.name + '_toolbar button#' + element).bind( "click", function() {
+								if(oBtnData.command_ex && oBtnData.command_ex == true)
+									eval(oBtnData.command);
+								else
+									eval('oEditor.commands.' + oBtnData.command);
+								
+								bx_ex_editor_check(oEditor, oParams);
+							});
+						}
+					}
+				)
+			}
+		);
+	});
+}
+
+function bx_ex_editor_add_link(oEditor, oParams)
+{
+	if(oEditor.isActive('link')){
+		oEditor.commands.unsetLink()
+	}
+	else{
+		bx_prompt(_t('_bx_editor_embed_popup_link'), '', function(oPopup){
+			 oEditor.commands.setLink({ href: $(oPopup).find("input[type = 'text']").val() })
+		});
+	}
+}
+
+function bx_ex_editor_add_image(oEditor, uploaderUrl)
+{
+	var input = document.createElement('input');
+	input.type = 'file';
+
+	input.onchange = e => { 
+		bx_ex_editor_upload(oEditor, uploaderUrl, e.target.files[0])
+	}
+
+	input.click();
+}
+
+function bx_ex_editor_upload(oEditor, uploaderUrl, file)
+{
+    const formData = new FormData();
+    formData.append("file", file);
+    fetch(uploaderUrl, {
+            method: "POST",
+            body: formData
+        }
+    )
+    .then(response => response.json())
+    .then(result => {
+        if ('undefined' != typeof(result.link))
+            oEditor.commands.setImage({ src: result.link });
+            oEditor.commands.setParagraph()
+    })
+    .catch(error => {
+    });
+}
+
+function bx_ex_editor_add_embed(oEditor, oParams)
+{
+	bx_prompt(_t('_bx_editor_embed_popup_embed'), '', function(oPopup){
+        oEditor.commands.setEmbed({ class: 'bx-embed-link', source: $(oPopup).find("input[type = 'text']").val() })
+    });
+}
+
+function bx_ex_editor_check(oEditor, oParams)
+{
+	oParams.toolbar.forEach(
+	elements => {
+		elements.forEach(
+			element => {
+				var oBtnData = eval("oParams.buttons." + element);
+				if (oBtnData && oBtnData.checkOnSelect && oBtnData.checkOnSelect == true){
+					if(oEditor.isActive(element))
+						$('#' + oParams.name + '_toolbar button#' + element).addClass('selected');
+					else
+						$('#' + oParams.name + '_toolbar button#' + element).removeClass('selected');
+				}
+			}
+		)
+	})
+}
+
+

+ 71 - 0
modules/boonex/editor/js/embed.js

@@ -0,0 +1,71 @@
+import{Node, mergeAttributes, textblockTypeInputRule, nodeInputRule} from 'https://esm.sh/@tiptap/core';
+var inputRegex = /(!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\))$/;
+import{Plugin,PluginKey,TextSelection} from 'https://esm.sh/v85/prosemirror-state@1.4.0/es2022/prosemirror-state.js';
+var a = Node.create({
+    name: 'embed',
+    addOptions: function () {
+        return {
+            inline: false,
+            allowBase64: false,
+            HTMLAttributes: {}
+        };
+    },
+    inline: function () {
+        return this.options.inline;
+    },
+    group: function () {
+        return this.options.inline ? 'inline' : 'block';
+    },
+    draggable: true,
+    addAttributes: function () {
+        return {
+            class: {
+                default: null
+            },
+            source: {
+                default: null
+            },
+            title: {
+                default: null
+            }
+        };
+    },
+    parseHTML: function () {
+        return [
+            {
+                tag: this.options.allowBase64
+                    ? 'div[class]'
+                    : 'div[class]:not([src^="data:"])'
+            },
+        ];
+    },
+    renderHTML: function (_a) {
+        var HTMLAttributes = _a.HTMLAttributes;
+        return ['div', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)];
+    },
+    addCommands: function () {
+        var _this = this;
+        return {
+            setEmbed: function (options) { return function (_a) {
+                var commands = _a.commands;
+                return commands.insertContent({
+                    type: _this.name,
+                    attrs: options
+                });
+            }; }
+        };
+    },
+    addInputRules: function () {
+        return [
+            nodeInputRule({
+                find: inputRegex,
+                type: this.type,
+                getAttributes: function (match) {
+                    var className = match[2], source = match[3], title = match[4];
+                    return { class: className, source: source, title: title };
+                }
+            }),
+        ];
+    }
+});
+export{a as Embed,a as default};

+ 38 - 0
modules/boonex/editor/js/eventHandler.js

@@ -0,0 +1,38 @@
+import{Extension} from 'https://esm.sh/@tiptap/core';
+import{Plugin, PluginKey} from 'https://esm.sh/v85/prosemirror-state@1.4.0/es2022/prosemirror-state.js';
+
+var a = Extension.create({
+    name: 'eventHandler',
+    addOptions: function () {
+        return {
+            uploaderUrl: ""
+        };
+    },
+    addProseMirrorPlugins: function () {
+        var _this = this;
+        console.log(_this.options.uploaderUrl)
+        return [
+            new Plugin({
+                key: new PluginKey('eventHandler'),
+                uploaderUrl: _this.options.uploaderUrl,
+                props: {
+                    handlePaste: function (view, event, slice) { 
+                        const dT = event.clipboardData || window.clipboardData;
+                        const images = dT.files;
+                        if (images.length === 0)
+                            return
+                        event.preventDefault();
+                        
+                        for (var i = 0; i < images.length; i++) {
+      
+                            bx_ex_editor_upload(_this.editor, this.spec.uploaderUrl, images[i])
+                           
+                        }
+                    }
+                }
+            }),
+        ];
+    }
+});
+
+export{a as EventHandler ,a as default};

+ 33 - 0
modules/boonex/editor/js/libs.js

@@ -0,0 +1,33 @@
+import {Editor, Mark, mergeAttributes,Node } from 'https://esm.sh/@tiptap/core'
+import Document from 'https://esm.sh/@tiptap/extension-document'
+import Paragraph from 'https://esm.sh/@tiptap/extension-paragraph'
+import Text from 'https://esm.sh/@tiptap/extension-text'
+import Bold from 'https://esm.sh/@tiptap/extension-bold'
+import Italic from 'https://esm.sh/@tiptap/extension-italic'
+import Strike from 'https://esm.sh/@tiptap/extension-strike'
+import Underline from 'https://esm.sh/@tiptap/extension-underline'
+import Subscript from 'https://esm.sh/@tiptap/extension-subscript'
+import Superscript from 'https://esm.sh/@tiptap/extension-superscript'
+import Blockquote from 'https://esm.sh/@tiptap/extension-blockquote'
+import Code from 'https://esm.sh/@tiptap/extension-code'
+import Highlight from 'https://esm.sh/@tiptap/extension-highlight'
+
+import ListItem from 'https://esm.sh/@tiptap/extension-list-item'
+import OrderedList from 'https://esm.sh/@tiptap/extension-ordered-list'
+import BulletList from 'https://esm.sh/@tiptap/extension-bullet-list'
+import CodeBlock from 'https://esm.sh/@tiptap/extension-code-block'
+
+import TextAlign from 'https://esm.sh/@tiptap/extension-text-align'
+import Heading from 'https://esm.sh/@tiptap/extension-heading'
+
+import Link from 'https://esm.sh/@tiptap/extension-link'
+import Image from 'https://esm.sh/@tiptap/extension-image'
+
+import Mention from 'https://esm.sh/@tiptap/extension-mention'
+
+import Embed from '/modules/boonex/editor/js/embed.js'
+import EventHandler  from '/modules/boonex/editor/js/eventHandler.js'
+//import Image from '/modules/boonex/editor/js/image.js'
+
+
+export { Editor, Document, Paragraph, Text, Bold, Italic, Strike, Underline, Subscript, Superscript, Blockquote, BulletList, ListItem, Code, Highlight, CodeBlock, OrderedList, TextAlign, Heading, Link, Image, Mention, Mark, mergeAttributes, Embed, EventHandler };

+ 20 - 0
modules/boonex/editor/request.php

@@ -0,0 +1,20 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Editor integration
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+check_logged();
+
+if ( empty($aRequest) || empty($aRequest[0]) ) {
+    BxDolRequest::processAsFile($aModule, $aRequest);
+} else {
+    BxDolRequest::processAsAction($aModule, $aRequest);
+}
+
+/** @} */

+ 23 - 0
modules/boonex/editor/template/css/main.css

@@ -0,0 +1,23 @@
+.bx-form-input-html-editor{
+	border: none !important;
+    border-radius: 0 0 0.375rem 0.375rem !important;
+}
+
+.bx-form-input-html-editor .bx-embed-link{
+    width:100%;
+    background: #E1ED10;
+    height: 100px;
+    content: attr(source);
+}
+.bx-form-input-html-editor .bx-embed-link::before{
+    content: attr(source);
+    width: 100%;
+    display: block;
+    height: 100%;
+    line-height: 100px;
+    position: relative;
+    text-align: center;
+    vertical-align: baseline;
+    font-size: 16px;
+    border:1px solid #000;
+}

+ 96 - 0
modules/boonex/editor/template/images/icons/std-icon.svg

@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   width="606px"
+   height="606px"
+   viewBox="0 0 606 606"
+   version="1.1"
+   id="svg30"
+   sodipodi:docname="std-icon.svg"
+   inkscape:version="1.1.2 (b8e25be833, 2022-02-05)"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg">
+  <sodipodi:namedview
+     id="namedview32"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     inkscape:pagecheckerboard="0"
+     showgrid="false"
+     inkscape:zoom="0.33415842"
+     inkscape:cx="507.24444"
+     inkscape:cy="677.82221"
+     inkscape:window-width="1920"
+     inkscape:window-height="996"
+     inkscape:window-x="-8"
+     inkscape:window-y="-8"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="g23" />
+ 
+  <defs
+     id="defs5">
+    <path
+       d="M552.268958,552.268958 C600,504.537813 600,431.458333 600,300 C600,168.541667 600,95.4621875 552.268958,47.7310417 C504.537813,0 431.458333,0 300,0 C168.541667,0 95.4621875,0 47.7310417,47.7310417 C0,95.4621875 0,168.541667 0,300 C0,431.458333 0,504.537813 47.7310417,552.268958 C95.4621875,600 168.541667,600 300,600 C431.458333,600 504.537813,600 552.268958,552.268958 Z"
+       id="path-2" />
+  </defs>
+  <g
+     id="Page-1"
+     stroke="none"
+     stroke-width="1"
+     fill="none"
+     fill-rule="evenodd">
+    <g
+       id="vk"
+       transform="translate(3.000000, 3.000000)">
+      <g
+         id="Squircle2-Copy-6">
+        <g
+           id="Shape">
+          <use
+             fill="#0098f7"
+             xlink:href="#path-2"
+             id="use7" />
+          <use
+             stroke="#000000"
+             stroke-width="4.04"
+             fill="url(#linearGradient-1)"
+             xlink:href="#path-2"
+             id="use9" />
+        </g>
+      </g>
+      <g
+         id="VK_Logo_White_On_Blue"
+         transform="translate(55.000000, 170.000000) scale(0.6, 0.6)"
+         fill="#FFFFFF" />
+    </g>
+  </g>
+  <g
+     id="g23"
+     transform="matrix(0.51141684,0,0,0.45445804,46.778812,78.252465)">
+    <g
+       transform="matrix(0.1,0,0,-0.1,0,511)"
+       id="g21"
+       style="fill:#ffffff">
+      <path
+         d="m 5891.8,4113.1 c -283.4,-143 -303.8,-500.4 -40.8,-694.4 61.3,-48.5 112.3,-53.6 451.9,-61.3 l 380.4,-7.7 V 107.4 -3132.4 h -367.6 c -337,0 -372.7,-5.1 -449.3,-56.2 -127.6,-86.8 -183.8,-181.3 -196.6,-319.1 -12.8,-165.9 66.4,-306.4 222.1,-382.9 112.3,-58.7 122.5,-58.7 1199.9,-58.7 1077.4,0 1087.6,0 1199.9,58.7 163.4,81.7 217,168.5 217,349.8 0,168.5 -45.9,252.8 -191.5,349.8 -76.6,53.6 -112.3,58.7 -449.3,58.7 H 7500.3 V 110 3352.3 h 367.6 c 337,0 372.7,5.1 449.3,58.7 145.5,97 191.5,181.3 191.5,349.8 0,181.3 -53.6,268.1 -217,352.3 -112.3,56.2 -122.5,56.2 -1199.9,56.2 -1077.5,0 -1087.7,0 -1200,-56.2 z"
+         id="path13"
+         style="fill:#ffffff" />
+      <path
+         d="m 369.6,2318.3 c -130.2,-45.9 -217,-130.2 -250.2,-240 -15.3,-61.3 -23,-748 -17.9,-2024.5 7.7,-1917.3 7.7,-1932.6 61.3,-2004.1 30.6,-38.3 91.9,-94.5 140.4,-122.5 84.2,-51.1 137.8,-51.1 3043.2,-58.7 l 2953.8,-5.1 v 408.5 408.5 H 3606.8 913.4 V 110 1539.7 h 2693.4 2693.4 v 408.5 408.5 H 3384.7 C 979.8,2354.1 448.8,2349 369.6,2318.3 Z"
+         id="path15"
+         style="fill:#ffffff" />
+      <path
+         d="m 7883.1,1948.2 v -408.5 h 600 600 V 110 -1319.7 h -600 -600 v -408.5 -411 l 862.9,7.7 c 845.1,7.7 862.9,7.7 954.8,66.4 53.6,33.2 114.9,102.1 145.5,168.5 53.7,107.2 53.7,137.8 53.7,2006.6 0,1868.8 0,1899.4 -53.6,2006.7 -30.6,66.4 -91.9,135.3 -145.5,168.5 -91.9,58.7 -109.8,58.7 -954.8,66.4 l -862.9,7.7 v -411.1 z"
+         id="path17"
+         style="fill:#ffffff" />
+      <path
+         d="m 2376.3,1156.7 c -68.9,-28.1 -91.9,-74 -541.2,-1067.1 -211.9,-469.8 -360,-829.7 -360,-875.7 0,-112.3 120,-227.2 237.4,-227.2 120,0 206.8,76.6 275.7,242.5 l 58.7,140.4 h 441.7 444.2 l 74,-163.4 c 40.9,-91.9 97,-176.2 125.1,-191.5 63.8,-35.7 196.6,-35.7 260.4,-2.5 56.1,30.6 125.1,153.2 125.1,222.1 0,89.4 -788.9,1830.5 -857.8,1891.8 -66.3,58.7 -181.2,71.5 -283.3,30.6 z M 2634.2,115.1 c 63.8,-158.3 117.4,-293.6 117.4,-298.7 0,-7.7 -114.9,-12.8 -255.3,-12.8 -140.4,0 -255.3,5.1 -255.3,10.2 0,12.8 227.2,551.4 245.1,582.1 20.4,33.2 15.3,43.4 148.1,-280.8 z"
+         id="path19"
+         style="fill:#ffffff" />
+    </g>
+  </g>
+</svg>