Server IP : 80.87.202.40 / Your IP : 216.73.216.169 Web Server : Apache System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64 User : bitrix ( 600) PHP Version : 8.2.27 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/bitrix/ext_www/rospirotorg.ru/bitrix/js/burlakastudio.realcommenter/ |
Upload File : |
'use strict'; /** * Модуль "Полноценные Комментарии D7" под Битрикс * Официальный сайт модуля: www.realcommenter.com * Официальный сайт разработчика: burlaka.studio * Автор и разработчик: Алексей Бурлака (AlexeyGfi) -> alexeygfi@gmail.com */ function realcommenter_forms_scan_and_init() { /** * Ищем все не проинициализиваронные формы */ let forms = document.querySelectorAll( realcommenter_get_selector('tree') + ' ' + realcommenter_get_selector('form') + ':not(._ambushed)' + ':not([data-inited])'); forms.forEach(function (item) { realcommenter_form_init(item); }); } window.addEventListener('load', realcommenter_forms_scan_and_init); document.addEventListener('form_placed', realcommenter_forms_scan_and_init); function realcommenterFormAutoReambush() { let links = document.querySelectorAll( realcommenter_get_selector('comment') + realcommenter_get_selector('response_to_autoreambush') + ' [data-zero]' + ':not([data-reambushed])' ) links.forEach(link => { link.setAttribute('data-reambushed', '1'); link.setAttribute('data-form-silent', '1'); link.click(); }); } /** * Инициализируем форму комментирования * @param form */ function realcommenter_form_init(form) { // Страховка if (form.hasAttribute('data-inited')) { return; } // Поля ввода let inputs = form.querySelectorAll(realcommenter_get_selector('form_inputs')); inputs.forEach(function (item) { item.addEventListener('change', realcommenter_form_memorizer); }); // Рейтинг let ratingWrappers = form.querySelectorAll('.itape_rating'/*realcommenter_get_selector('form_inputs')*/); ratingWrappers.forEach(function (wraper) { let monitor = wraper.querySelector('[data-shape]'); let shapes = wraper.querySelectorAll('[data-shape] > *'); let field = wraper.querySelector('[type="hidden"][data-input][data-addit-id]'); if (!monitor || !shapes.length || !field) { return; } monitor.setAttribute('data-value', field.value); let proxyOptions = { monitor: monitor, field: field }; shapes.forEach(shape => { let shapeCallback = realcommenterRatingProcessCallback.bind(shape, proxyOptions); shape.addEventListener('mouseover', shapeCallback); shape.addEventListener('click', shapeCallback); }); // item.addEventListener('change', realcommenter_form_memorizer); }); // Экшн-элементы let submits = form.querySelectorAll('[data-submit]'); submits.forEach(function (item) { item.addEventListener('click', realcommenter_form_action.bind(item, item.getAttribute('data-submit'), false)); }); // Комментарий отмечаем как такой, что в нём открыта форма комментирования let comment_obj = form.closest(realcommenter_get_selector('comment')); if (comment_obj) { comment_obj.classList.toggle('_incomment', true); } // Кнопка закрытия формы let closer = form.querySelector(realcommenter_get_selector('form_closer')); if (closer) { closer.addEventListener('click', realcommenter_form_close.bind(closer, form)); } // Нужна ли загрузка формы авторизации let bf_auth = form.querySelector(realcommenter_get_selector('form_auth')); if (bf_auth) { realcommenter_auth_init(bf_auth); } // Во время режима редактирования - область уже загруженных файлов let files_to_edit = form.querySelectorAll( '.brf_edit_uploads [' + realcommenter_get_selector('image_gallery_initer_attr') + '],.brf_edit_uploads [data-file-id]' ); if (files_to_edit.length) { files_to_edit.forEach(function (item) { let del_obj = document.createElement('del'); item.appendChild(del_obj); let ins_obj = document.createElement('ins'); del_obj.appendChild(ins_obj); ins_obj.addEventListener('click', function () { this.classList.toggle('_marked_to_del'); }.bind(item)); }); } // Кнопка загрузчика файлов let upload_picker = form.querySelector(realcommenter_get_selector('upload_picker')); if (upload_picker) { if (typeof window['realcommenter_dragndrop_ajax_request'] === 'undefined') { realcommenter_drag_n_drop_init_JS(function () { this.addEventListener('click', realcommenter_dragndrop_ajax_request); }.bind(upload_picker)); } else { upload_picker.addEventListener('click', realcommenter_dragndrop_ajax_request); } } // Визуальный редактор let editor_area = form.querySelector(realcommenter_get_selector('form_editor_area')); if (editor_area && editor_area.hasAttribute('data-html-editor')) { BX.loadScript( realcommenter_get_jscss_url('talk_editor.js'), function (editorArea) { //this - наша форма /** * Нужно получить html-код для проброса в редактор * Это либо textarea (и его value) + после чтения textarea удаляем * ...либо innerHTML */ let _content; let _textarea = editorArea.querySelector('textarea'); if (_textarea) { _content = _textarea.value; } else { _content = editorArea.innerHTML; } editorArea.innerHTML = ''; let node_to_id = this.getAttribute(realcommenter_get_selector('form_attribute_to')); let node_to_target = this.getAttribute(realcommenter_get_selector('form_attribute_target')); realcommenterHtmlEditorPlaceAndInit( editorArea, 'RCM_EDITOR_' + node_to_id + '_' + node_to_target, _content, form.hasAttribute('data-silent-mode') ); }.bind(form, editor_area) ); } else { if (!form.hasAttribute('data-silent-mode')) { setTimeout(realcommenterFormActivateTextfield.bind(this, form.parentNode), 50); } } // reCaptcha2 let talk_obj = form.closest(realcommenter_get_selector('tree')); if (talk_obj && BX.message['REALCOMMENTER_RECAPTCHA2_SITEKEY']) { BX.loadScript( realcommenter_get_jscss_url('recaptcha2.js'), function () { if ( typeof window['realcommenter_recaptcha2_cpu'] !== 'undefined' && window['realcommenter_recaptcha2_cpu'] ) { window['realcommenter_recaptcha2_cpu'](); } }.bind() ); } /** * reCaptcha3 * * При инициализации третьей версии нам нужно *один* раз получить токен * и дальше уже с ним работать */ if (talk_obj && BX.message['REALCOMMENTER_RECAPTCHA3_SITEKEY']) { BX.loadScript( realcommenter_get_jscss_url('recaptcha3.js'), function () { if ( typeof window['realcommenter_recaptcha3_cpu'] !== 'undefined' && window['realcommenter_recaptcha3_cpu'] ) { window['realcommenter_recaptcha3_cpu'](); } }.bind() ); } form.setAttribute('data-inited', '1'); } function realcommenterRatingProcessCallback(proxyOptions) { // this -- our single shape proxyOptions.field.value = +this.getAttribute('data-value'); proxyOptions.monitor.setAttribute('data-value', proxyOptions.field.value); } function realcommenter_form_action(action, skip_recaptcha3) { let _form = this.closest(realcommenter_get_selector('form')); let formData = realcommenter_form_parse_form(_form); if (!Object.keys(formData).length) { return false; } if ( typeof realcommenter_recaptcha3_sitekey !== 'undefined' && realcommenter_recaptcha3_sitekey() && !skip_recaptcha3 ) { realcommenter_recaptcha3_cpu(realcommenter_form_action.bind(this, action, true)); return; } // Чистим возможные ошибки внутри realcommenter_form_find_and_destroy(_form, '.' + realcommenter_get_selector('form_error_area_classname')); // Снимаем форме возможный css-класс о том, что внутри формы есть ошибки _form.classList.toggle(realcommenter_get_selector('form_has_errors'), false); let data = { request_type: action, form_data: formData, target_node: _form.getAttribute(realcommenter_get_selector('form_attribute_to')), target_position: _form.getAttribute(realcommenter_get_selector('form_attribute_target')) }; if (action === 'add') { data['browserTitle'] = document.title; let h1 = document.querySelector('h1'); if (h1) { data['h1Title'] = h1.innerText; } } realcommenter_ajaxion.bind(this, { url: '/bitrix/admin/burlakastudio.realcommenter.talk_form.php', onsuccess: realcommenter_form_ajaxed_processor, data: data })(); } function realcommenter_form_ajaxed_processor(result) { if (typeof result['ERROR'] !== 'undefined' && Object.keys(result['ERROR']).length) { if (typeof result['request']['target_node'] !== 'undefined' && result['request']['target_node']) { let _selector = '#FORM_SELECTOR#[#FORM_TO_ATTRIBUTE#="#TARGET_NODE#"]'; _selector = _selector.replace(/#FORM_SELECTOR#/, realcommenter_get_selector('form_')); _selector = _selector.replace(/#FORM_TO_ATTRIBUTE#/, realcommenter_get_selector('form_attribute_to')); _selector = _selector.replace(/#TARGET_NODE#/, result['request']['target_node']); let _form = document.querySelector(_selector); if (!_form) { return; } _form.classList.toggle(realcommenter_get_selector('form_has_errors'), true); let _messages = []; _messages.push(result['ERROR']); if (result['STOP_FILTER_WORDS']) { _messages.push( BX.message('itape_filter_fired_on') + '<strong>' + result['STOP_FILTER_WORDS'].join('</strong>, <strong>') + '</strong>' ); } if (result['STOP_TAGS']) { _messages.push( BX.message('itape_filter_by_tag_fired_on') + '<strong>' + result['STOP_TAGS'].join('</strong>, <strong>') + '</strong>' ); } realcommenter_form_notice_from_object(_messages, _selector, realcommenter_get_selector('form_error_area_classname')); } return; } if (typeof result['MSG_OF_RESULT'] !== 'undefined' && result['MSG_OF_RESULT']) { /** * Пришло сообщение, которое нужно опубликовать в форме. * Например, после отправки нового комментария, который отправлен, но в неактивном состоянии */ if ( typeof result['request']['target_node'] !== 'undefined' || typeof result['request']['target_position'] !== 'undefined' ) { let _form = realcommenter_find_form_by_to_and_target(result['request']['target_node'], result['request']['target_position']); if (_form) { /** * Вычищаем лишнее, * находим бади */ let body_for_msg = null; _form.children.forEach = [].forEach; _form.children.forEach(function (item) { if ( !~item.className.indexOf('brf_header') && !~item.className.indexOf('brf_body') ) { item.parentNode.removeChild(item); return; } if (~item.className.indexOf('brf_body')) { body_for_msg = item; } }); if (body_for_msg) { body_for_msg.innerHTML = result['MSG_OF_RESULT']; } } } return; } switch (result['request']['request_type']) { case 'save' : console.log('save'); break; case 'preview' : console.log('preview'); break; case 'add' : /** * Добавлен новый комментарий, result[ 'RESULT' ] содержит его id * Пользователь, всё-равно где находится (постраничка, подгрузка порциями, вверху, внизу) * ...должен увидеть свой комментарий. * * Воспользуемся механизмом expand-а комментария, он как раз нам подходит. * • создаём контейнер для отображения комментария; * • скроллим к нему; * • пинаем подгрузку. */ if ( typeof result['RESULT'] === 'undefined' || !result['RESULT'] || typeof result['request']['talk_id'] === 'undefined' || !result['request']['talk_id'] ) { return; } /** * Если это ответ на комментарий - даём код комментария * ...иначе позицию формы из нулевого уровня */ realcommenter_show_added_comment(result['RESULT'], result['request']['talk_id'], ( (result['request']['target_node'] && parseInt(result['request']['target_node'])) ? result['request']['target_node'] : result['request']['target_position'] )); if (result['request']['target_position']) { realcommenter_form_closer_ping({ talk_id: result['request']['talk_id'], target_position: result['request']['target_position'] }); } break; case 'edit' : /** * Отредактирован комментарий, result[ 'RESULT' ] содержит его id * Нужно перечитать комментарий * * Воспользуемся механизмом expand-а комментария, он как раз нам подходит. */ if ( typeof result['RESULT'] === 'undefined' || !result['RESULT'] || typeof result['request']['talk_id'] === 'undefined' || !result['request']['talk_id'] ) { return; } let any_child = document.querySelector( realcommenter_get_selector('comment') + realcommenter_get_selector('comment_id') + result['RESULT'] + ' *:first-child' ); if (any_child) { // Нужно подскроллить, потому что форма редактирования находилась значительно ниже комментария let comment_obj = document.querySelector( realcommenter_get_selector('comment') + realcommenter_get_selector('comment_id') + result['RESULT'] ); realcommenter_expand_branch.bind(any_child, { scroll_to_new_comment: 1 })(); } break; default: console.log('undefined action'); } } function realcommenter_find_and_expand(commentId) { let any_child = document.querySelector( realcommenter_get_selector('comment') + realcommenter_get_selector('comment_id') + commentId + ' *:first-child' ); if (any_child) { // Нужно подскроллить, потому что форма редактирования находилась значительно ниже комментария let comment_obj = document.querySelector( realcommenter_get_selector('comment') + realcommenter_get_selector('comment_id') + commentId ); realcommenter_expand_branch.bind(any_child, { scroll_to_new_comment: 1 })(); } } function realcommenter_find_form_by_to_and_target(form_to, form_target) { if (!form_to && !form_target) { return; } let _form = false; if (form_target) { _form = document.querySelector( realcommenter_get_selector('form') + '[data-form-target="' + form_target + '"]' ); } if (!_form && form_to) { _form = document.querySelector( realcommenter_get_selector('form') + '[data-form-to="' + form_to + '"]' ); } return _form; } function realcommenter_form_pull() { //this - наша ссылка. /** * Ситуации: * • даём ответ на комментарий (есть родительский контейнер с кодом комментария) * • публикуем комментарий перед обсуждением * • публикуем комментарий после обсуждения * + * • редактируем комментарий */ let comment_id = ''; let comment_target = ''; if (this.getAttribute('data-zero')) { let add_parent = this.closest(realcommenter_get_selector('add_node')); if (add_parent) { comment_target = add_parent.getAttribute('data-new-comment'); } } else { let parent_comment = realcommenter_get_closest_comment(this); if (!parent_comment) { return false; } let comment_id_matches = parent_comment.getAttribute('id'); comment_id_matches = comment_id_matches.match(/[0-9]+/); if (!comment_id_matches) { return false; } comment_id = comment_id_matches.shift(); } if (!comment_id && !comment_target) { return; } // Нужно число! Потому что BX.ajax потом из false делает "false" let edit_form = +this.hasAttribute('data-to-edit'); realcommenter_ajaxion.bind(this, { url: '/bitrix/admin/burlakastudio.realcommenter.talk_form.php', onsuccess: realcommenter_form_place, data: { request_type: 'get', comment_id: comment_id, comment_target: comment_target, edit_form: edit_form, /** * Чтобы не подсвечивалось поле ввода (.focus) * ...например, у нас автораскрытие форм и форма внизу обсуждения дёргает нас на себя */ silent_mode: +this.hasAttribute('data-form-silent') } })(); } function realcommenter_form_place(result) { if (typeof result['ERROR'] !== 'undefined' && Object.keys(result['ERROR']).length) { console.log('ERROR'); console.log(result); return; } if (result['FORM_HTML'] !== 'undefined' && result['FORM_HTML']) { let commentId = result['request']['comment_id']; let commentTarget = result['request']['comment_target']; let talkId = result['request']['talk_id']; let talkObj = realcommenter_get_talk_by_id(talkId); if (talkObj && (commentTarget || commentId)) { /** * Либо комментарий в нулевой уровень (приоритет) * ...либо у нас ответ на какой-то другой комментарий */ let targetBlock = null; if (commentTarget) { targetBlock = talkObj.querySelector( realcommenter_get_selector('add_node') + '[data-new-comment="' + commentTarget + '"] + ' + ' ' + realcommenter_get_selector('subnode') ); } else { /** * Если мы даём ответ на какой-то комментарий, * форму интегрируем перед остальными ответами, чтобы их отображение * не зависело от наших действий */ let commentRowObj = talkObj.querySelector( realcommenter_get_selector('comment') + '[id="answercontainer_' + commentId + '"]' ); if (commentRowObj) { targetBlock = commentRowObj.querySelector( realcommenter_get_selector('comment') + ' > ' + realcommenter_get_selector('subnode') ); if (targetBlock.children.length) { let forFormObj = document.createElement('div'); forFormObj.className = realcommenter_get_selector_simple('form_tmp_wrapper'); targetBlock.insertBefore(forFormObj, targetBlock.children[0]); targetBlock = forFormObj; } } } if (targetBlock) { targetBlock.innerHTML = result['FORM_HTML']; let event = new CustomEvent('form_placed', { bubbles: true, cancelable: true, detail: targetBlock } ); if (!+result['request']['silent_mode']) { if (!!+result['request']['edit_form']) { realcommenter_tool_scrollTo(targetBlock, -100); } } document.dispatchEvent(event); } } } } /** * Эта функция используется тогда, когда посетитель кликнул на ссылку добавления комментария "в виде формы", * открылась форма и чтобы оправдать его ожидания (он же кликал на текстовое поле), * нужно зафокусировать первое текстовое поле на его пути */ function realcommenterFormActivateTextfield(parent_obj) { let form_obj = parent_obj.querySelector(realcommenter_get_selector('form')); if (!form_obj) { return; } // Первое, что встречается по пути let text_obj = form_obj.querySelector('input[type="text"], textarea'); if (text_obj) { text_obj.focus(); } } function realcommenter_form_notice_from_object(messages_tree, obj_css_selector, css_class) { if (!messages_tree || !obj_css_selector) { return; } if (!css_class) { css_class = 'errors'; } let _message = []; for (let e in messages_tree) { if (!messages_tree.hasOwnProperty(e)) { continue; } _message.push(messages_tree[e]); } if (obj_css_selector) { let target_obj = false; /** * Нам могут передать и сразу объект */ if (obj_css_selector instanceof HTMLElement) { target_obj = obj_css_selector; } else { target_obj = document.querySelector(obj_css_selector); } if (target_obj) { let msg_obj = document.createElement('div'); msg_obj.className = css_class; msg_obj.innerHTML = '<div>' + _message.join('</div><div>') + '</div>'; target_obj.appendChild(msg_obj); } } else { console.log(message.join('\n')); } } function realcommenter_form_parse_form(_form) { if (!_form) { return false; } if (!realcommenter_form_valid(_form)) { return false; } let _result = {}; // Поля ввода let inputs = _form.querySelectorAll(realcommenter_get_selector('form_inputs')); inputs.forEach(function (item) { /** * Ситуация: * визуальный редактор Битрикса, ввели что-то внутрь и сразу нажали отправить комментарий. * * Визуальный редактор не успевает выбросить наружу текст и валидатор говорит: нет значения, * ...хотя оно фактически внесено * * !!! Но учитываем, что редактор может быть в режиме html */ let _value = ''; if (~item.id.indexOf('RCM_EDITOR')) { if (window[item.id].sEditorMode === 'code') { _value = item.value; } else { _value = window[item.id].GetEditorContent(); } } else if (item.value) { _value = item.value; } if (!_value) { return; } /** * Нужно обеспечить это: * * form_data[ ADDI[1] ] * form_data[ ADDI ] [1] * * form_data[ ADDI ] * form_data[ ADDI ] [1][] */ let inputNameRaw = item.getAttribute('data-input'); let baseName = inputNameRaw.match(/^[^\[]+/)[0]; let deepParts = inputNameRaw.match(/\[([^\]]*)\]/g); if (!deepParts || !deepParts.length) { _result[baseName] = _value; } else { // Here is accumulation effect possible if (typeof _result[baseName] === 'undefined') { _result[baseName] = {}; } let scopeDeep = _result[baseName]; deepParts.forEach((deep, index, arr) => { deep = deep.replace(/(\[|\])/g, ''); // final step if (index >= arr.length - 1) { if (Array.isArray(scopeDeep)) { scopeDeep.push(_value); } else { scopeDeep[deep] = _value; } } else { let nextDeep = arr[index + 1].replace(/(\[|\])/g, ''); if (typeof scopeDeep[deep] === 'undefined') { /** * Next depth type depends to the next value - * number or empty (tail, accumulation by []) */ if (nextDeep === '' || isFinite(+nextDeep)) { scopeDeep[deep] = []; } else { scopeDeep[deep] = {}; } } scopeDeep = scopeDeep[deep]; } }); } if (item.hasAttribute('data-editor-type')) { _result['editor_type'] = item.getAttribute('data-editor-type'); } }); // Ранее загруженные — те, которые остались let files_to_edit = _form.querySelectorAll( '.brf_edit_uploads [' + realcommenter_get_selector('image_gallery_initer_attr') + ']._marked_to_del,.brf_edit_uploads [data-file-id]._marked_to_del' ); if (files_to_edit.length) { _result['UF_UPLOADED_TO_DEL'] = []; files_to_edit.forEach(function (item) { let file_id = (item.hasAttribute(realcommenter_get_selector('image_gallery_initer_attr')) ? item.getAttribute(realcommenter_get_selector('image_gallery_initer_attr')) : item.getAttribute('data-file-id') ); _result['UF_UPLOADED_TO_DEL'].push(file_id); }); } // Подгруженные файлы let files = _form.querySelectorAll(realcommenter_get_selector('form_files')); if (files.length) { _result['UF_UPLOADS'] = []; files.forEach(function (item) { _result['UF_UPLOADS'].push(item.value); }); } // recaptcha2 let recaptcha2_widget = _form.querySelector('.recaptcha2'); if (recaptcha2_widget) { if ( recaptcha2_widget.hasAttribute('data-inited') && recaptcha2_widget.hasAttribute('data-recaptcha2-widget-id') ) { let widget_id = +recaptcha2_widget.getAttribute('data-recaptcha2-widget-id'); let widget_response = window['grecaptcha'].getResponse(widget_id); if (widget_response) { _result['RECAPTCHA2_RESPONSE'] = widget_response; } } } // recaptcha3 if (BX.message['RECAPTCHA3_TOKEN']) { _result['RECAPTCHA3_TOKEN'] = BX.message['RECAPTCHA3_TOKEN']; } return _result; } function realcommenter_form_valid(_form) { if (!_form) { return false; } realcommenter_find_and_destroy_error_blocks_inside(_form); let _errors = []; // Поля ввода let inputs = _form.querySelectorAll( realcommenter_get_selector('form_inputs') + realcommenter_get_selector('input_required') ); inputs.forEach(function (item) { /** * Ситуация: * визуальный редактор Битрикса, ввели что-то внутрь и сразу нажали отправить комментарий. * * Визуальный редактор не успевает выбросить наружу текст и валидатор говорит: нет значения, * ...хотя оно фактически внесено */ let _value = ''; if (~item.id.indexOf('RCM_EDITOR')) { _value = window[item.id].GetEditorContent(); } else if (item.value) { _value = item.value; } if (!_value) { _errors.push(item); item.classList.toggle('_error', true); } else { let _data_input = item.getAttribute('data-input'); if (_data_input && ~_data_input.toLowerCase().indexOf('email')) { if (!_value.match(/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/)) { _errors.push(item); item.classList.toggle('_error', true); } } } }); // recaptcha2 let recaptcha2_widget = _form.querySelector('.recaptcha2'); if (recaptcha2_widget) { recaptcha2_widget.classList.toggle('recaptcha_error', false); let recaptcha2_has_error = false; if ( !recaptcha2_widget.hasAttribute('data-inited') || !recaptcha2_widget.hasAttribute('data-recaptcha2-widget-id') ) { recaptcha2_has_error = true; } else { let widget_id = +recaptcha2_widget.getAttribute('data-recaptcha2-widget-id'); let widget_response = window['grecaptcha'].getResponse(widget_id); if (!widget_response) { recaptcha2_has_error = true; } } if (recaptcha2_has_error) { _errors.push(recaptcha2_widget); recaptcha2_widget.classList.toggle('recaptcha_error', true); } } if (_errors.length) { let submit_area = _form.querySelector(realcommenter_get_selector('submit_block')); if (submit_area) { let more_case = realcommenterNumLang(_errors.length); let _error_msg = BX.message('FORM_REQUIRED_INPUTS_MSG') + _errors.length + BX.message('FORM_REQUIRED_INPUTS_CASE_' + more_case); realcommenter_form_notice_from_object({ message: _error_msg }, submit_area); } return false; } return true; } function realcommenter_form_find_and_destroy(obj, css_selector) { if (!css_selector || !obj) { return; } let _list = obj.querySelectorAll(css_selector); _list.forEach(function (item) { item.parentNode.removeChild(item); }); } function realcommenter_form_find_and_turn_off(obj, css_selector, className) { if ( typeof obj === 'undefined' || !obj || typeof css_selector === 'undefined' || !css_selector || typeof className === 'undefined' || !className ) { return; } let _list = obj.querySelectorAll(css_selector); _list.forEach(function (item) { item.classList.toggle(className, false); }); } /** * TODO: memorizer */ function realcommenter_form_memorizer() { //this - наше поле ввода } function realcommenter_form_close(_form) { // this - кнопка закрытия if ( typeof this === 'undefined' || !this || typeof _form === 'undefined' || !_form ) { return; } // Снимаем с комментария отметку про форму внутри let comment_obj = _form.closest(realcommenter_get_selector('comment')); if (comment_obj) { comment_obj.classList.toggle('_incomment', false); } /** * Если мы воткнули форму в нулевой уровень (за границами дерева), * мы можем просто её удалить. * * Иначе мы должна находиться в контейнере с классом ._tmp_for_form * Такой случай -- приоритет, удаляем его либо просто форму */ let _tmp_parent = _form.closest(realcommenter_get_selector('form_tmp_wrapper')); if (_tmp_parent) { _tmp_parent.parentNode.removeChild(_tmp_parent); } else { _form.parentNode.removeChild(_form); } } function realcommenter_form_closer_ping(ping_options) { let form_obj = document.querySelector( '[data-talk-id="' + ping_options['talk_id'] + '"]' + ' ' + realcommenter_get_selector('form') + '[' + realcommenter_get_selector('form_attribute_target') + '=' + ping_options['target_position'] + ']' ); if (!form_obj) { return; } let closer_obj = form_obj.querySelector(realcommenter_get_selector('form_closer')); if (!closer_obj) { return; } realcommenter_form_close.bind(closer_obj, form_obj)(); }