266 lines
6.0 KiB
Django/Jinja
266 lines
6.0 KiB
Django/Jinja
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<title>Code + Mermaid</title>
|
||
|
||
<!-- Highlight.js с CDN -->
|
||
<link rel="stylesheet" href="https://unpkg.com/@highlightjs/cdn-assets@11.11.0/styles/atom-one-dark.min.css">
|
||
<script src="https://unpkg.com/@highlightjs/cdn-assets@11.11.0/highlight.min.js"></script>
|
||
<script src="https://unpkg.com/@highlightjs/cdn-assets@11.11.0/languages/go.min.js"></script>
|
||
<script>hljs.highlightAll();</script>
|
||
|
||
<!-- Mermaid.js с CDN -->
|
||
<script src="https://unpkg.com/mermaid/dist/mermaid.min.js " defer></script>
|
||
|
||
<script>
|
||
document.addEventListener('DOMContentLoaded', () => {
|
||
// Инициализация Mermaid
|
||
mermaid.initialize({ startOnLoad: false, theme: 'dark' });
|
||
|
||
// Инициализация вкладок
|
||
const tabs = document.querySelectorAll('.tab');
|
||
const tabContents = document.querySelectorAll('.tab-content');
|
||
|
||
// Активация первой вкладки
|
||
if (tabs.length > 0) {
|
||
tabs[0].classList.add('active');
|
||
tabContents[0].style.display = 'block';
|
||
mermaid.init(undefined, tabContents[0].querySelector('.mermaid'));
|
||
}
|
||
|
||
// Обработчик клика по вкладкам
|
||
tabs.forEach((tab, index) => {
|
||
tab.addEventListener('click', () => {
|
||
tabs.forEach(t => t.classList.remove('active'));
|
||
tabContents.forEach(c => c.style.display = 'none');
|
||
|
||
tab.classList.add('active');
|
||
tabContents[index].style.display = 'block';
|
||
|
||
// Инициализация Mermaid для активной вкладки, если еще не была инициализирована
|
||
const diagram = tabContents[index].querySelector('.mermaid');
|
||
if (!diagram.dataset.initialized) {
|
||
mermaid.init(undefined, diagram);
|
||
diagram.dataset.initialized = true;
|
||
}
|
||
});
|
||
});
|
||
|
||
// Логика перетаскивания
|
||
const resizer = document.getElementById('resizer');
|
||
const codeContainer = document.querySelector('.code-blocks');
|
||
const diagramContainer = document.querySelector('.diagram-container');
|
||
|
||
let isDragging = false;
|
||
|
||
resizer.addEventListener('mousedown', (e) => {
|
||
isDragging = true;
|
||
document.body.style.cursor = 'ew-resize';
|
||
});
|
||
|
||
document.addEventListener('mousemove', (e) => {
|
||
if (!isDragging) return;
|
||
|
||
const containerWidth = document.body.clientWidth;
|
||
const x = e.clientX;
|
||
const codeWidth = (x / containerWidth) * 100;
|
||
|
||
if (codeWidth >= 5 && codeWidth <= 95) {
|
||
codeContainer.style.flex = `0 0 ${codeWidth}%`;
|
||
diagramContainer.style.flex = `0 0 ${100 - codeWidth}%`;
|
||
}
|
||
});
|
||
|
||
document.addEventListener('mouseup', () => {
|
||
isDragging = false;
|
||
document.body.style.cursor = 'default';
|
||
});
|
||
|
||
document.addEventListener('mouseleave', () => {
|
||
isDragging = false;
|
||
document.body.style.cursor = 'default';
|
||
});
|
||
});
|
||
</script>
|
||
|
||
<style>
|
||
body {
|
||
display: flex;
|
||
margin: 0;
|
||
height: 100vh;
|
||
max-width: 100vw;
|
||
font-family: sans-serif;
|
||
background-color: #1e1e1e;
|
||
color: #e6e6e6;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.topbar {
|
||
background-color: #2d2d2d;
|
||
padding: 0.5rem 1rem;
|
||
border-bottom: 1px solid #444;
|
||
font-weight: bold;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0.5rem;
|
||
}
|
||
|
||
.topbar span {
|
||
color: #888;
|
||
}
|
||
|
||
.main-container {
|
||
display: flex;
|
||
flex: 1;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.code-container, .diagram-container {
|
||
flex: 1;
|
||
transition: width 0.2s ease;
|
||
}
|
||
|
||
.code-container {
|
||
overflow: visible;
|
||
}
|
||
|
||
.diagram-container {
|
||
overflow: auto;
|
||
}
|
||
|
||
.code-blocks {
|
||
background-color: #2d2d2d;
|
||
border-right: 1px solid #444;
|
||
padding: 1rem;
|
||
}
|
||
|
||
.code-container pre {
|
||
background: #1e1e1e;
|
||
color: #dcdcdc;
|
||
padding: 1rem;
|
||
border-radius: 4px;
|
||
margin: 0;
|
||
}
|
||
|
||
.code-blocks {
|
||
display: flex;
|
||
flex-direction: column;
|
||
overflow: auto;
|
||
flex: 1;
|
||
transition: width 0.2s ease;
|
||
margin: 0;
|
||
}
|
||
|
||
.diagram-container {
|
||
background-color: #2d2d2d;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.tabs {
|
||
display: flex;
|
||
border-bottom: 1px solid #444;
|
||
padding: 0 1rem;
|
||
background-color: #333;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.tab {
|
||
padding: 0.5rem 1rem;
|
||
cursor: pointer;
|
||
color: #ccc;
|
||
border-bottom: 2px solid transparent;
|
||
transition: all 0.2s;
|
||
display: block;
|
||
}
|
||
|
||
.tab.active {
|
||
border-bottom: 2px solid #007acc;
|
||
color: #007acc;
|
||
}
|
||
|
||
.tab:hover {
|
||
background-color: #444;
|
||
}
|
||
|
||
.tab-content {
|
||
flex: 1;
|
||
padding: 1rem;
|
||
display: none;
|
||
overflow: auto;
|
||
}
|
||
|
||
.mermaid {
|
||
color: #e6e6e6;
|
||
}
|
||
|
||
.mermaid .node rect,
|
||
.mermaid .node circle,
|
||
.mermaid .node ellipse {
|
||
fill: #3a3a3a !important;
|
||
stroke: #888 !important;
|
||
}
|
||
|
||
.mermaid .edgePath path {
|
||
stroke: #ccc !important;
|
||
}
|
||
|
||
.resizer {
|
||
width: 5px;
|
||
min-width: 5px;
|
||
background-color: #444;
|
||
cursor: ew-resize;
|
||
z-index: 10;
|
||
}
|
||
|
||
.resizer::after {
|
||
content: "";
|
||
position: absolute;
|
||
top: 0;
|
||
bottom: 0;
|
||
width: 1px;
|
||
background-color: #888;
|
||
left: 2px;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="topbar">
|
||
<span style="color: #007acc;">{{ handler_method }}</span>
|
||
<span style="color: #888;">::</span>
|
||
<span>{{ handler_path }}</span>
|
||
</div>
|
||
|
||
<div class="main-container">
|
||
<div class="code-blocks">
|
||
{% for escaped_source in escaped_sources %}
|
||
<div class="code-container">
|
||
<h3>{{escaped_source[0]}}</h3>
|
||
<pre><code class="language-python">
|
||
{{ escaped_source[1] }}
|
||
</code></pre>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
|
||
<div class="resizer" id="resizer"></div>
|
||
|
||
<div class="diagram-container">
|
||
<ul class="tabs">
|
||
{% for diagram in mmd_diagrams %}
|
||
<li class="tab">{{ diagram.name }}</li>
|
||
{% endfor %}
|
||
</ul>
|
||
|
||
{% for diagram in mmd_diagrams %}
|
||
<div class="tab-content">
|
||
<div class="mermaid">
|
||
{{ diagram.data }}
|
||
</div>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
</body>
|
||
</html> |