Удалось разобраться, вот что получилось:
Скрипты и стили
<?if (Loader::IncludeModule("fileman")){?>
<link rel="stylesheet" type="text/css" href="/bitrix/js/fileman/html_editor/html-editor.css">
<?CJSCore::Init(array('window','ajax','fx','uploader','ui.design-tokens', 'date', 'timer'));
foreach(array(
'range.js',
'html-actions.js',
'html-views.js',
'html-parser.js',
'html-base-controls.js',
'html-controls.js',
'html-components.js',
'html-snippets.js',
'html-editor.js',
) as $DIST){?>
<script src="/bitrix/js/fileman/html_editor/<?=$DIST?>"></script>
<?}?>
<script src="/bitrix/js/main/dd.js"></script>
<script>
BX.message(<?=CUtil::PhpToJSObject(\Bitrix\Main\Localization\Loc::loadLanguageFile($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/fileman/classes/general/html_editor_js.php'), false);?>);
var configBXHtmlEditor = {
cssIframePath:'<?=\CUtil::GetAdditionalFileURL('/bitrix/js/fileman/html_editor/iframe-style.css')?>',
designTokens:'<?=json_encode(\Bitrix\Main\UI\Extension::getHtml('ui.design-tokens'),JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_PARTIAL_OUTPUT_ON_ERROR)?>',
spellcheck_path:'<?=\CUtil::GetAdditionalFileURL('/bitrix/js/fileman/html_editor/html-spell.js')?>'
};
(function(window) {
if (!window.BXHtmlEditor){
var BXHtmlEditor = {
editors: {},
configs: {},
dialogs: {},
Controls: {},
SaveConfig: (config)=>{
BX.ready(()=>{
if (config && config.id) BXHtmlEditor.configs[config.id] = config;
});
},
Show: (config, id)=>{
BX.ready(()=>{
if ((!config || typeof config != 'object') && id && BXHtmlEditor.configs[id]) config = BXHtmlEditor.configs[id];
if (config && typeof config == 'object'){
if (!BXHtmlEditor.editors[config.id] || !BXHtmlEditor.editors[config.id].Check()){
BXHtmlEditor.editors[config.id] = new window.BXEditor(config);
}else{
BXHtmlEditor.editors[config.id].CheckAndReInit();
}
}
});
},
Hide: (id) => {
if(BXHtmlEditor.editors[id]) BXHtmlEditor.editors[config.id].Hide();
},
Get: (id) => {
return BXHtmlEditor.editors[id] || false;
},
OnBeforeUnload: ()=>{
for (var id in BXHtmlEditor.editors){
if (BXHtmlEditor.editors.hasOwnProperty(id) &&
BXHtmlEditor.editors[id].config.askBeforeUnloadPage === true &&
BXHtmlEditor.editors[id].IsShown() &&
BXHtmlEditor.editors[id].IsContentChanged() &&
!BXHtmlEditor.editors[id].IsSubmited() &&
BXHtmlEditor.editors[id].beforeUnloadHandlerAllowed !== false
){
if(typeof(BX.desktopUtils) != 'undefined' && typeof(BX.desktopUtils.isChangedLocationToBx) == 'function' && BX.desktopUtils.isChangedLocationToBx()) return;
return BXHtmlEditor.editors[id].config.beforeUnloadMessage || BX.message('BXEdExitConfirm');
}
}
},
ReplaceNewLines: (content) => {
content = content.replace(/<[^<>]*br>\n/ig, '#BX_BR#');
var contentTmp;
while (true){
contentTmp = content.replace(/([\s|\S]+)\n([\s|\S]+)/gi, (s, s1, s2) => {
if (s1.match(/>\s*$/) || s2.match(/^\s*</)) return s;
return s1 + '#BX_BR#' + s2;
});
if (contentTmp == content){
break;
}else{
content = contentTmp;
}
}
content = content.replace(/#BX_BR#/ig, "<br>\n");
return content;
},
ReplaceNewLinesBack: (content) =>{
content = content.replace(/<[^<>]*br>\n/ig, '#BX_BR#');
var contentTmp;
while (true){
contentTmp = content.replace(/([\s|\S]+)#BX_BR#([\s|\S]+)/gi, (s, s1, s2) => {
if (s1.match(/>\s*$/) || s2.match(/^\s*</)) return s;
return s1 + '\n' + s2;
});
if (contentTmp == content){
break;
}else{
content = contentTmp;
}
}
content = content.replace(/#BX_BR#/ig, "<br>\n");
return content;
}
};
window.BXHtmlEditor = BXHtmlEditor;
window.onbeforeunload = BXHtmlEditor.OnBeforeUnload;
}
BX.onCustomEvent(window, "OnBXHtmlEditorInit");
top.BXHtmlEditorAjaxResponse = {};
})(window);
</script>
<?}?>
Редактор:
<?if (Loader::IncludeModule("fileman")){?>
<div class="bx-html-editor" id="bx-html-editor-<?=$NAME?>" style="width:100%; height:250px;" data-name="<?=$NAME?>">
<div class="bxhtmled-toolbar-cnt" id="bx-html-editor-tlbr-cnt-<?=$NAME?>">
<div class="bxhtmled-toolbar" id="bx-html-editor-tlbr-<?=$NAME?>"></div>
</div>
<div class="bxhtmled-search-cnt" id="bx-html-editor-search-cnt-<?=$NAME?>" style="display: none;"></div>
<div class="bxhtmled-area-cnt" id="bx-html-editor-area-cnt-<?=$NAME?>">
<div class="bxhtmled-iframe-cnt" id="bx-html-editor-iframe-cnt-<?=$NAME?>"></div>
<div class="bxhtmled-textarea-cnt" id="bx-html-editor-ta-cnt-<?=$NAME?>"></div>
<div class="bxhtmled-resizer-overlay" id="bx-html-editor-res-over-<?=$NAME?>"></div>
<div id="bx-html-editor-split-resizer-<?=$NAME?>"></div>
</div>
<div class="bxhtmled-nav-cnt" id="bx-html-editor-nav-cnt-<?=$NAME?>" style="display: none;"></div>
<div class="bxhtmled-taskbar-cnt bxhtmled-taskbar-hidden" id="bx-html-editor-tskbr-cnt-<?=$NAME?>">
<div class="bxhtmled-taskbar-top-cnt" id="bx-html-editor-tskbr-top-<?=$NAME?>"></div>
<div class="bxhtmled-taskbar-resizer" id="bx-html-editor-tskbr-res-<?=$NAME?>">
<div class="bxhtmled-right-side-split-border">
<div data-bx-tsk-split-but="Y" class="bxhtmled-right-side-split-btn"></div>
</div>
</div>
<div class="bxhtmled-taskbar-search-nothing" id="bxhed-tskbr-search-nothing-<?=$NAME?>">HTMLED_SEARCH_NOTHING</div>
<div class="bxhtmled-taskbar-search-cont" id="bxhed-tskbr-search-cnt-<?=$NAME?>" data-bx-type="taskbar_search">
<div class="bxhtmled-search-alignment" id="bxhed-tskbr-search-ali-<?=$NAME?>">
<input type="text" class="bxhtmled-search-inp" id="bxhed-tskbr-search-inp-<?=$NAME?>" placeholder="HTMLED_SEARCH_PLACEHOLDER"/>
</div>
<div class="bxhtmled-search-cancel" data-bx-type="taskbar_search_cancel" title="HTMLED_SEARCH_CANCEL"></div>
</div>
</div>
<div id="bx-html-editor-file-dialogs-<?=$NAME?>" style="display: none;"></div>
</div>
<?}else{?>
<textarea rows="5" name="<?=$NAME?>"></textarea>
<?}?>
Скрипт редактора:
const editor = document.querySelectorAll('.bx-html-editor');
if(editor.length){
for (let i = 0; i < editor.length; i++){
window.BXHtmlEditor.Show({
id: editor[i].getAttribute('data-name'),
inputName:editor[i].getAttribute('data-name'),
content:'',
useFileDialogs:false,
width:"100%",
height:"200",
allowPhp:false,
limitPhpAccess:false,
templates:[],
templateId:'',
templateParams:[],
componentFilter:'',
snippets:[],
placeholder:"Text here...",
actionUrl:"/bitrix/admin/fileman_html_editor_action.php",
cssIframePath:configBXHtmlEditor.cssIframePath,
bodyClass:'',
bodyId:'',
designTokens:configBXHtmlEditor.designTokens,
spellcheck_path:configBXHtmlEditor.spellcheck_path,
usePspell:'N',
useCustomSpell:'Y',
bbCode:false,
askBeforeUnloadPage:true,
settingsKey:'user_settings__ChangeView',
showComponents:false,
showSnippets:false,
view:'wysiwyg',
splitVertical:false,
splitRatio:1,
taskbarShown:false,
taskbarWidth:250,
lastSpecialchars:false,
cleanEmptySpans:true,
lazyLoad:false,
showTaskbars:false,
showNodeNavi:false,
controlsMap:[
{"id":"ChangeView","wrap":true,"compact":true,"sort":10},
{"separator":true,"compact":false,"sort":11},
{"id":"Undo","compact":false,"sort":12},
{"id":"Redo","compact":false,"sort":13},
{"separator":true,"compact":false,"sort":14},
{"id":"Bold","compact":true,"sort":15},
{"id":"Italic","compact":true,"sort":16},
{"id":"Underline","compact":true,"sort":17},
{"id":"Strikeout","compact":true,"sort":18},
{"id":"RemoveFormat","compact":true,"sort":19},
{"id":"Color","compact":true,"sort":20},
{"id":"StyleSelector","compact":false,"sort":21},
{"id":"FontSelector","compact":false,"sort":22},
{"id":"FontSize","compact":false,"sort":23},
{"separator":true,"compact":false,"sort":24},
{"id":"OrderedList","compact":true,"sort":25},
{"id":"UnorderedList","compact":true,"sort":26},
{"id":"AlignList","compact":false,"sort":27},
{"id":"InsertHr","compact":false,"hidden":true,"sort":29},
{"id":"Sub","compact":false,"hidden":true,"sort":30},
{"id":"Sup","compact":false,"hidden":true,"sort":31},
{"id":"IndentButton","compact":true,"hidden":true,"sort":32},
{"id":"OutdentButton","compact":true,"hidden":true,"sort":33},
{"separator":true,"compact":false,"hidden":true,"sort":34},
{"id":"InsertChar","compact":false,"hidden":true,"sort":35},
{"id":"PrintBreak","compact":false,"hidden":true,"sort":36},
{"id":"PageBreak","compact":false,"hidden":true,"sort":37},
{"id":"Spellcheck","compact":false,"hidden":true,"sort":38},
{"separator":true,"compact":false,"hidden":true,"sort":39},
{"id":"InsertLink","compact":true,"hidden":true,"sort":40},
{"id":"InsertImage","compact":false,"hidden":true,"sort":41},
{"id":"InsertVideo","compact":true,"hidden":true,"sort":42},
{"id":"InsertTable","compact":false,"hidden":true,"sort":43},
{"separator":true,"compact":false,"sort":44},
{"id":"Fullscreen","compact":false,"sort":45},
{"id":"Viewmode","compact":true,"sort":46},
{"id":"More","compact":true,"sort":47}
],
autoResize:true,
autoResizeOffset:40,
minBodyWidth:350,
normalBodyWidth:555,
components:false,
isCopilotEnabled:false,
isCopilotImageEnabledBySettings:true,
isCopilotTextEnabledBySettings:true,
copilotParams:null,
isMentionUnavailable:false,
fontSize:'14px',
pasteSetColors:true,
pasteSetBorders:true,
pasteSetDecor:true,
pasteClearTableDimen:true,
linkDialogType:"internal"
});
}
}