elvsc

19 commits
Updated 2026-04-30 16:50:05
templates/repository
templates/repository/tree.html
{% extends "repository.html" %}

{% block stylesheet %}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/default.min.css">
{% endblock stylesheet %}

{% block view %}
<style>
.tree-box {
    margin-top: 1rem;
    border: 1px solid var(--border-color);
    border-radius: 8px;
    overflow: hidden;
    background: var(--bg-0);

    .tree-header {
        padding: 0.6rem 1rem;
        background: var(--bg-1);
        border-bottom: 1px solid var(--border-color);
        font-family: var(--code-font), monospace;
        font-size: var(--font-size-base);
        color: var(--text-1);
    }

    ul {
        list-style: none;
        margin: 0;
        padding: 0;
    }

    li {
        display: flex;
        align-items: center;
        padding: 0.4rem 1rem;
        border-bottom: 1px solid var(--border-color);
        font-family: var(--code-font), monospace;
        font-size: var(--font-size-base);
        transition: background 0.15s;

        &:last-child { border-bottom: none; }
        &:hover { background: var(--bg-1); }

        a {
            text-decoration: none;
            color: var(--text-0);
            flex: 1;

        }

        .icon {
            margin-right: 0.6rem;
            color: var(--text-1);
            display: inline-flex;
        }

        &.dir a { font-weight: 600; }
        &.parent { color: var(--text-1); }
        &.parent a { color: var(--text-1); }
    }

    a:hover {
        background-color: var(--bg-1);
        color: var(--text-0);
    }
}

.code-box {
    margin-top: 1.5rem;
    border: 1px solid var(--border-color);
    border-radius: 8px;
    overflow: hidden;
    background: var(--bg-0);

    .code-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 0.5rem 1rem;
        background: var(--bg-1);
        border-bottom: 1px solid var(--border-color);
        font-family: var(--code-font), monospace;
        font-size: var(--font-size-base);

        .filename {
            display: flex;
            align-items: center;
            gap: 0.4rem;
            color: var(--text-0);

            svg { color: var(--text-1); }
        }


        button {
            background: var(--bg-0);
            border: 1px solid var(--border-color);
            color: var(--text-0);
            padding: 0.3rem 0.7rem;
            border-radius: 6px;
            cursor: pointer;
            font-size: var(--font-size-base);
            font-family: inherit;
            display: inline-flex;
            align-items: center;
            gap: 0.3rem;
            transition: all 0.15s;

            &:hover {
                background: var(--bg-2);
                border-color: var(--text-2);
            }
            &.copied {
                color: var(--secondary-color);
                border-color: var(--secondary-color);
            }
        }
    }

    .code-content {
        overflow-x: auto;
        background: var(--bg-1);
        display: flex;

        .line-numbers {
            margin: 0;
            padding: 16px 12px 16px 12px;

            text-align: right;
            font-family: var(--code-font), monospace;
            font-size: var(--font-size-base);
            line-height: var(--line-height);

            border-right: 1px solid var(--border-color);
            user-select: none;
        }

        pre {
            margin: 0;
            padding: 16px;

            font-family: var(--code-font), monospace;
            font-size: var(--font-size-base);
            line-height: var(--line-height);

            color: var(--text-0);
            user-select: text;
            display: block;

            code {
                margin: 0;
                padding: 0;
                background: var(--bg-1);
            }
        }
    }
}
</style>

<div class="tree-box">
    <div class="tree-header">{{ current_dir.display() }}</div>
    <ul>
        {%- if current_dir != Path::new(".") %}
        <li class="parent dir">
            <span class="icon">
                <svg height="14" width="14" viewBox="0 0 16 16"><path fill="currentColor" d="M7.78 12.53a.75.75 0 0 1-1.06 0L2.47 8.28a.75.75 0 0 1 0-1.06l4.25-4.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L4.81 7h7.44a.75.75 0 0 1 0 1.5H4.81l2.97 2.97a.75.75 0 0 1 0 1.06Z"/></svg>
            </span>
            <a href="{{ public }}/{{ summary.name }}/{{ bookmark }}/tree/{{ current_dir.display() }}/../index.html">..</a>
        </li>
        {% endif -%}

        {%- for directory in adjacent_directories %}
        <li class="dir">
            <span class="icon">
                <svg height="14" width="14" viewBox="0 0 16 16"><path fill="currentColor" d="M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3h-6.5a.25.25 0 0 1-.2-.1l-.9-1.2A1.75 1.75 0 0 0 5.25 1h-3.5Z"/></svg>
            </span>
            <a href="{{ public }}/{{ summary.name }}/{{ bookmark }}/tree/{{ current_dir.display() }}/{{ directory }}/index.html">{{ directory }}/</a>
        </li>
        {% endfor -%}

        {%- for (file, _) in adjacent_files %}
        <li class="file">
            <span class="icon">
                <svg height="14" width="14" viewBox="0 0 16 16"><path fill="currentColor" d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z"/></svg>
            </span>
            <a href="{{ public }}/{{ summary.name }}/{{ bookmark }}/tree/{{ current_dir.display() }}/{{ file }}.html">{{ file }}</a>
        </li>
        {% endfor -%}
    </ul>
</div>

{%- if let Some(content) = content %}
<div class="code-box">
    <div class="code-header">
        <span class="filename">
            <svg height="14" width="14" viewBox="0 0 16 16"><path fill="currentColor" d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Z"/></svg>
            {{ current_dir.display() }}/{{ current_name }}
        </span>
    </div>
    <div class="code-content">
        <div class="line-numbers" id="line-numbers"></div>
        <pre tabindex="0" spellcheck="false"
                          onfocus="this.setAttribute('contenteditable','true')"
                          onblur="this.removeAttribute('contenteditable')"
                          oninput="return false"
                          onkeydown="if(!(e=event).ctrlKey&&!e.metaKey)e.preventDefault()"><code {%- if let Some(lang) = content.language %} class="language-{{ lang }}" {% endif %} id="code-block">{{ content.file }}</code></pre>
    </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"></script>

{%- if let Some(lang) = content.language %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/languages/{{ lang }}.min.js"></script>
{% endif %}

<script>
hljs.highlightAll();

const block = document.getElementById('code-block');
const lineCount = block.textContent.split('\n').length;
document.getElementById('line-numbers').innerHTML = Array.from(
  { length: lineCount },
  (_, i) => i + 1
).join('<br>');

</script>
{% endif -%}
{% endblock view %}