RDT1C/src/DataProcessors/ирПлатформа/Templates/ПросмотрMarkdownHTML/Ext/Template.txt
Администратор 631359a351 Адаптер Турбоконф (интерфейс) 1
1007619 	Bug 	Исправлен иногда некорректный расчет анализатором кода вызовов из расширения модуля в общие модули 	Действия
  История Гита 1
	1007618 	Bug 	Исправлены недочеты в отборе коммитов при полю "Что искать" 	Действия
  Консоль запросов 1
	1007609 	Bug 	Восстановлено запоминание сверток панелей при закрытии формы 	Действия
  Конструктор запроса 1
	1007605 	Task 	Команда "Заполнить настройки компоновки" разделена в подменю из двух команд "Очистить настройки" и "Заполнить настройки" 	Действия
  Поле текста программы 3
	1007598 	Task 	Теперь автодополнение в языке запросов предлагает имена новых параметров после "&" в правой части сравнения 	Действия
	1007610 	Bug 	Восстановлено заполнение списка автодополнения встроенными функциями и функциями модулей языка выражений компоновки данных 	Действия
	1007603 	Bug 	Устранен захват в структуре модуля первым методом инструкции препроцессора с предшествующим комментарием 	Действия
  Различные значения колонки 1
	1007611 	Bug 	Исправлена ошибка открытия из динамического списка в клиент-серверной базе 	Действия
  Чат ИИ 2
	1007620 	Bug 	Исправлены недочеты раскраски блоков кода 1С в ответах ИИ 	Действия
	1007616 	Bug 	Улучшена обработка ошибок соединения с Напарником
2025-11-23 20:59:39 +03:00

405 lines
15 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- для выполнения в Webkit 605 внутри поля HTML формы платформы 1С -->
<html>
<head>
<script type="text/javascript">
%ТекстJS%
</script>
<style type=text/css>
body {
margin: 2px;
}
pre {
font-family: Courier;
color: #0000FF;
font-size: 9pt;
}
.k { color: red; }
.c { color: green; }
.s { color: black; }
.n { color: black; }
.p { color: brown; }
TABLE {
BORDER-TOP: black 1px solid;
BORDER-RIGHT: black 1px solid;
BORDER-COLLAPSE: collapse;
BORDER-BOTTOM: black 1px solid;
BORDER-LEFT: black 1px solid;
border-color: #C2C2C2;
}
TH {
BORDER-TOP: black 1px solid;
BORDER-RIGHT: black 1px solid;
BORDER-BOTTOM: black 1px solid;
PADDING-BOTTOM: 5px;
PADDING-TOP: 5px;
PADDING-LEFT: 5px;
BORDER-LEFT: black 1px solid;
PADDING-RIGHT: 5px;
border-color: #C2C2C2;
}
TD {
BORDER-TOP: black 1px solid;
BORDER-RIGHT: black 1px solid;
BORDER-BOTTOM: black 1px solid;
PADDING-BOTTOM: 5px;
PADDING-TOP: 5px;
PADDING-LEFT: 5px;
BORDER-LEFT: black 1px solid;
PADDING-RIGHT: 5px;
border-color: #C2C2C2;
}
blockquote {
background: #f9f9f9;
border-left: 5px solid #ccc;
margin: 1.5em 10px;
padding: 0.5em 10px;
}
blockquote:before {
color: #ccc;
content: open-quote;
font-size: 4em;
line-height: 0.1em;
margin-right: 0.25em;
vertical-align: -0.4em;
}
blockquote p {
display: inline;
}
/* Стили для блоков кода 1С */
.code-block-1c {
border: 1px solid #ccc;
margin: 10px 0;
background: #f0f0f0;
}
.code-header, .code-footer {
background: #F0F0F0;
border-bottom: 1px solid #ccc;
padding: 2px 4px; /* Уменьшена высота */
font-size: 11px; /* Уменьшен размер шрифта */
display: flex;
justify-content: space-between;
align-items: center;
}
.code-footer {
border-top: 1px solid #ccc;
border-bottom: none;
}
.code-header span, .code-footer span {
font-weight: bold;
color: #666;
}
.code-header button, .code-footer button {
background: #e0e0e0; /* Приглушённый фон */
border: 1px solid #999; /* Приглушённая рамка */
color: #666; /* Приглушённый цвет текста */
margin: 0 2px;
margin-right: auto; /* Прижимаем к левому краю */
padding: 1px 6px; /* Уменьшено внутреннее пространство */
font-size: 10px; /* Уменьшен размер шрифта кнопки */
cursor: pointer;
}
.code-header button:hover, .code-footer button:hover {
background: #d0d0d0; /* Приглушённый фон при наведении */
}
.code-content {
padding: 8px;
margin: 0;
overflow: auto;
background: white;
font-family: 'Courier New', monospace;
font-size: 13px;
line-height: 1.2;
max-height: 400px;
}
/* Цвета синтаксиса 1С - стандартные цвета */
.c1c-keyword { color: #FF0000; } /* Красный для ключевых слов */
.c1c-symbol { color: #FF0000; } /* Красный для спецсимволов */
.c1c-comment { color: #008000; } /* Зеленый для комментариев */
.c1c-string { color: #000000; } /* Черный для строк */
.c1c-number { color: #000000; } /* Черный для чисел */
.c1c-constant { color: #0000FF; } /* Синий для констант */
.c1c-identifier { color: #0000FF; } /* Синий для идентификаторов */
</style>
</head>
<body>
<div id="content"></div>
<script>
function highlight1C(code) {
if (!code) return '';
code = code.replace(new RegExp('\\t', 'g'), ' ');
var keywords = [
'Процедура', 'Функция', 'КонецПроцедуры', 'КонецФункции',
'Если', 'Тогда', 'Иначе', 'КонецЕсли', 'Для', 'Каждого',
'Из', 'Цикл', 'КонецЦикла', 'Пока', 'Выполнять', 'Возврат',
'Продолжить', 'Прервать', 'Попытка', 'Исключение', 'КонецПопытки',
'ВызватьИсключение', 'Перем', 'Перейти', 'Не', 'И',
'Или', 'ИначеЕсли', 'Экспорт', 'Знач', 'Новый', 'Истина', "Ложь"
];
var constants = ['Истина', 'Ложь', 'Неопределено', 'Null'];
var tokens = [];
var tokenIndex = 0;
function createToken(content) {
var marker = '___TOKEN_' + tokenIndex + '___';
tokens.push({ marker: marker, content: content });
tokenIndex++;
return marker;
}
// Шаг 1: Обрабатываем строки ДО любого экранирования
// В строке пишем четыре слеша, чтобы в регулярку попало два (для экранирования точки)
var stringRegex = new RegExp('"([^"\\\\]|\\\\.)*"', 'g');
code = code.replace(stringRegex, function(match) {
return createToken('___STRING___' + match + '___STRING___');
});
// Шаг 2: Обрабатываем комментарии 1С (// ...)
code = code.replace(new RegExp('\\/\\/.*$', 'gm'), function(match) {
return createToken('<span class="c1c-comment">' + match + '</span>');
});
// Шаг 3: Обрабатываем директивы препроцессора &...
var directiveRegex = new RegExp('&[А-Яа-яЁёA-Za-z_][А-Яа-яЁёA-Za-z_0-9]*', 'g');
code = code.replace(directiveRegex, function(match) {
return createToken('<span class="c1c-keyword">' + match + '</span>');
});
// Шаг 3.5: Обрабатываем операторы сравнения < и > отдельно
code = code.replace(new RegExp('([<>])', 'g'), function(match) {
var safeChar = (match === '<') ? '&lt;' : '&gt;';
return createToken('<span class="c1c-symbol">' + safeChar + '</span>');
});
// Шаг 4: Экранируем HTML-опасные символы
var rgxStringMarker = new RegExp('___STRING___', 'g');
var rgxAmp = new RegExp('&', 'g');
var rgxLt = new RegExp('<', 'g');
var rgxGt = new RegExp('>', 'g');
for (var i = 0; i < tokens.length; i++) {
if (tokens[i].content.indexOf('___STRING___') !== -1) {
var stringContent = tokens[i].content.replace(rgxStringMarker, '');
var escapedString = stringContent
.replace(rgxAmp, '&amp;')
.replace(rgxLt, '&lt;')
.replace(rgxGt, '&gt;');
tokens[i].content = '<span class="c1c-string">' + escapedString + '</span>';
}
}
// Экранируем оставшийся код
code = code
.replace(rgxAmp, '&amp;')
.replace(rgxLt, '&lt;')
.replace(rgxGt, '&gt;');
// Шаг 5: Обрабатываем числа
code = code.replace(new RegExp('\\b(\\d+\\.?\\d*)\\b', 'g'), function(match) {
return createToken('<span class="c1c-number">' + match + '</span>');
});
// Шаг 6: Обрабатываем ключевые слова с кастомными границами
var wordBoundaryPrefix = '([^а-яёa-z0-9_]|^)';
var wordBoundarySuffix = '(?=[^а-яёa-z0-9_]|$)';
for (var i = 0; i < keywords.length; i++) {
// Экранируем спецсимволы в самом ключевом слове
var escapedKeyword = keywords[i].replace(new RegExp('[.*+?^${}()|[\\]\\\\]', 'g'), '\\$&');
var regex = new RegExp(wordBoundaryPrefix + '(' + escapedKeyword + ')' + wordBoundarySuffix, 'gi');
code = code.replace(regex, function(match, prefix, kw) {
return prefix + createToken('<span class="c1c-keyword">' + kw + '</span>');
});
}
// Шаг 7: Обрабатываем константы
for (var j = 0; j < constants.length; j++) {
var escapedConstant = constants[j].replace(new RegExp('[.*+?^${}()|[\\]\\\\]', 'g'), '\\$&');
var constRegex = new RegExp(wordBoundaryPrefix + '(' + escapedConstant + ')' + wordBoundarySuffix, 'gi');
code = code.replace(constRegex, function(match, prefix, cnst) {
return prefix + createToken('<span class="c1c-constant">' + cnst + '</span>');
});
}
// Шаг 8: Обрабатываем идентификаторы
var identRegexStr = '([^а-яёa-z0-9_]|^)([а-яёa-z_][а-яёa-z0-9_]*)(?=[^а-яёa-z0-9_]|$)';
var identRegex = new RegExp(identRegexStr, 'gi');
code = code.replace(identRegex, function(match, prefix, word) {
if (word.indexOf('___TOKEN_') !== 0) {
return prefix + createToken('<span class="c1c-identifier">' + word + '</span>');
}
return match;
});
// Шаг 9: Обрабатываем спецсимволы
// Внимание: внутри [] нужно экранировать минус и скобки
var symbolRegex = new RegExp('([{}()\\[\\].,;:=+\\-*\\/])', 'g');
code = code.replace(symbolRegex, function(match) {
if (match.indexOf('___TOKEN_') !== 0) {
return createToken('<span class="c1c-symbol">' + match + '</span>');
}
return match;
});
// Шаг 10: Восстанавливаем все токены
for (var i = 0; i < tokens.length; i++) {
// Экранируем маркер для использования в RegExp
var escapedMarker = tokens[i].marker.replace(new RegExp('[.*+?^${}()|[\\]\\\\]', 'g'), '\\$&');
var regex = new RegExp(escapedMarker, 'g');
code = code.replace(regex, tokens[i].content);
}
// Шаг 11: Чистка
code = code.replace(new RegExp('___TOKEN_\\d+___', 'g'), '');
code = code.replace(new RegExp('___STRING___', 'g'), '');
return code;
}
// Функция копирования в буфер
function copyToClipboard(text) {
try {
var textArea = document.createElement('textarea');
textArea.value = text;
textArea.style.position = 'fixed';
textArea.style.left = '-999999px';
textArea.style.top = '-999999px';
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
var successful = document.execCommand('copy');
document.body.removeChild(textArea);
return successful;
} catch (err) {
console.error('Не удалось скопировать текст: ', err);
return false;
}
}
// Обработчик кнопок
function handleCodeAction(action, btn) {
var codeBlock = btn.closest('.code-block-1c');
if (!codeBlock) {
codeBlock = btn.parentNode.parentNode;
}
var codeContent = codeBlock.querySelector('.code-content');
if (!codeContent) {
console.error('Не найден элемент с кодом');
return;
}
// Получаем чистый текст, убирая HTML-теги
var text = codeContent.textContent || codeContent.innerText || '';
if (action === 'copy') {
var success = copyToClipboard(text);
if (success) {
// Визуальная обратная связь
var originalText = btn.textContent;
btn.textContent = 'Скопировано!';
btn.style.backgroundColor = '#90EE90';
setTimeout(function() {
btn.textContent = originalText;
btn.style.backgroundColor = '';
}, 1500);
} else {
btn.textContent = 'Ошибка!';
btn.style.backgroundColor = '#FFB6C1';
setTimeout(function() {
btn.textContent = 'Копировать';
btn.style.backgroundColor = '';
}, 1500);
}
}
// Передаем событие в 1С
if (window.handle1CCodeAction) {
window.handle1CCodeAction(action, text);
}
}
// Инициализация marked
if (typeof marked !== 'undefined') {
var originalRenderer = new marked.Renderer();
var originalCode = originalRenderer.code;
marked.Renderer.prototype.code = function(code, language) {
if (language && (false
|| language.toLowerCase() === '1с'
|| language.toLowerCase() === '1c'
|| language.toLowerCase() === 'bsl'))
{
var highlighted = highlight1C(code);
var lines = code.split('\n'); // Исправлено: использовать \n для подсчета строк
var hasFooter = lines.length > 20;
var html = '<div class="code-block-1c">' +
'<div class="code-header">' +
'<span>1C</span>' +
'<div>' +
'<button onclick="handleCodeAction(\'copy\', this)">Копировать</button>' +
'<button onclick="handleCodeAction(\'compare\', this)">Сравнить</button>' +
'</div>' +
'</div>' +
'<pre class="code-content">' + highlighted + '</pre>';
if (hasFooter) {
html += '<div class="code-footer">' +
'<span>1C</span>' +
'<div>' +
'<button onclick="handleCodeAction(\'copy\', this)">Копировать</button>' +
'<button onclick="handleCodeAction(\'compare\', this)">Сравнить</button>' +
'</div>' +
'</div>';
}
html += '</div>';
return html;
}
return originalCode.call(this, code, language);
};
marked.setOptions({
breaks: true,
gfm: true
});
}
window._1CAPI = window._1CAPI || {};
// Функция установки текста (работает с marked и без него)
window._1CAPI.setText = function(text, fontSize) {
var contentElement = document.getElementById('content');
// Устанавливаем размер шрифта для блоков кода 1С
if (fontSize) {
// Создаем или обновляем стиль для размера шрифта
var styleId = 'dynamic-code-font-size';
var existingStyle = document.getElementById(styleId);
if (existingStyle) {
existingStyle.remove();
}
var style = document.createElement('style');
style.id = styleId;
style.textContent = '.code-block-1c .code-content, #content pre { font-size: ' + fontSize + ' !important; }';
document.head.appendChild(style);
}
if (typeof marked !== 'undefined') {
// Используем marked если доступен
try {
contentElement.innerHTML = marked(text);
return true;
} catch (e) {
console.error('Ошибка marked:', e);
// Fallback на простой текст
contentElement.innerText = text;
return false;
}
} else {
// Режим без marked - просто выводим текст как есть
contentElement.innerHTML = '<pre>' + highlight1C(text) + '</pre>';
return true;
}
};
</script>
</body>
</html>