Обновлены стили для компонента спойлеров, улучшена анимация и добавлены новые визуальные эффекты. Обновлен файл service worker с новой версией для кэширования. Оптимизирована логика рендеринга токенов в markdown, улучшена обработка вложенных элементов и ссылок.
This commit is contained in:
parent
e3b98ea8d3
commit
30f9daaec8
@ -82,7 +82,7 @@ define(['./workbox-9dc17825'], (function (workbox) { 'use strict';
|
|||||||
"revision": "3ca0b8505b4bec776b69afdba2768812"
|
"revision": "3ca0b8505b4bec776b69afdba2768812"
|
||||||
}, {
|
}, {
|
||||||
"url": "index.html",
|
"url": "index.html",
|
||||||
"revision": "0.nsn25edhihg"
|
"revision": "0.b1jpidvaji"
|
||||||
}], {});
|
}], {});
|
||||||
workbox.cleanupOutdatedCaches();
|
workbox.cleanupOutdatedCaches();
|
||||||
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
||||||
|
|||||||
@ -671,7 +671,8 @@ header {
|
|||||||
|
|
||||||
/* Анимация пульсации для offline индикатора */
|
/* Анимация пульсации для offline индикатора */
|
||||||
@keyframes pulse {
|
@keyframes pulse {
|
||||||
0%, 100% {
|
0%,
|
||||||
|
100% {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
}
|
}
|
||||||
@ -4409,7 +4410,7 @@ textarea:focus {
|
|||||||
|
|
||||||
/* Стили для скрытого текста (спойлеров) */
|
/* Стили для скрытого текста (спойлеров) */
|
||||||
.spoiler {
|
.spoiler {
|
||||||
background: linear-gradient(45deg, #f0f0f0, #e8e8e8);
|
background: linear-gradient(45deg, rgba(var(--accent-color-rgb), 0.15), rgba(var(--accent-color-rgb), 0.25));
|
||||||
color: transparent;
|
color: transparent;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
@ -4417,11 +4418,15 @@ textarea:focus {
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
position: relative;
|
position: relative;
|
||||||
border: 1px solid #ddd;
|
display: inline-block;
|
||||||
|
vertical-align: baseline;
|
||||||
|
border: 1px solid rgba(var(--accent-color-rgb), 0.3);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
backdrop-filter: blur(2px);
|
backdrop-filter: blur(2px);
|
||||||
-webkit-backdrop-filter: blur(2px);
|
-webkit-backdrop-filter: blur(2px);
|
||||||
text-shadow: 0 0 8px rgba(0, 0, 0, 0.3);
|
text-shadow: 0 0 8px rgba(var(--accent-color-rgb), 0.3);
|
||||||
|
isolation: isolate;
|
||||||
|
z-index: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.spoiler::before {
|
.spoiler::before {
|
||||||
@ -4431,27 +4436,30 @@ textarea:focus {
|
|||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
background: rgba(255, 255, 255, 0.8);
|
background: rgba(var(--accent-color-rgb), 0.1);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
filter: blur(1px);
|
filter: blur(1px);
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
|
box-sizing: border-box;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.spoiler:hover {
|
.spoiler:hover {
|
||||||
background: linear-gradient(45deg, #e8e8e8, #d8d8d8);
|
background: linear-gradient(45deg, rgba(var(--accent-color-rgb), 0.25), rgba(var(--accent-color-rgb), 0.35));
|
||||||
transform: scale(1.02);
|
transform: scale(1.02);
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
box-shadow: 0 2px 8px rgba(var(--accent-color-rgb), 0.25);
|
||||||
|
border-color: rgba(var(--accent-color-rgb), 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.spoiler:hover::before {
|
.spoiler:hover::before {
|
||||||
background: rgba(255, 255, 255, 0.9);
|
background: rgba(var(--accent-color-rgb), 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
.spoiler.revealed {
|
.spoiler.revealed {
|
||||||
background: linear-gradient(45deg, #e8f5e8, #d4edda);
|
background: linear-gradient(45deg, rgba(var(--accent-color-rgb), 0.15), rgba(var(--accent-color-rgb), 0.2));
|
||||||
color: #155724;
|
color: var(--accent-color);
|
||||||
border-color: #c3e6cb;
|
border-color: rgba(var(--accent-color-rgb), 0.4);
|
||||||
box-shadow: 0 0 0 2px rgba(40, 167, 69, 0.25);
|
box-shadow: 0 0 0 2px rgba(var(--accent-color-rgb), 0.25);
|
||||||
text-shadow: none;
|
text-shadow: none;
|
||||||
user-select: text;
|
user-select: text;
|
||||||
-webkit-user-select: text;
|
-webkit-user-select: text;
|
||||||
@ -4463,8 +4471,8 @@ textarea:focus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.spoiler.revealed:hover {
|
.spoiler.revealed:hover {
|
||||||
background: linear-gradient(45deg, #d4edda, #c3e6cb);
|
background: linear-gradient(45deg, rgba(var(--accent-color-rgb), 0.2), rgba(var(--accent-color-rgb), 0.25));
|
||||||
box-shadow: 0 0 0 2px rgba(40, 167, 69, 0.35);
|
box-shadow: 0 0 0 2px rgba(var(--accent-color-rgb), 0.35);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Стили для файлов */
|
/* Стили для файлов */
|
||||||
|
|||||||
@ -25,49 +25,54 @@ const spoilerExtension = {
|
|||||||
|
|
||||||
// Функция для рендеринга вложенных токенов
|
// Функция для рендеринга вложенных токенов
|
||||||
function renderTokens(tokens: any[], renderer: any): string {
|
function renderTokens(tokens: any[], renderer: any): string {
|
||||||
return tokens.map((token) => {
|
return tokens
|
||||||
// Используем кастомный renderer если он есть
|
.map((token) => {
|
||||||
if (renderer[token.type]) {
|
// Используем кастомный renderer если он есть
|
||||||
return renderer[token.type](token);
|
if (renderer[token.type]) {
|
||||||
}
|
return renderer[token.type](token);
|
||||||
// Fallback для встроенных типов токенов
|
|
||||||
if (token.type === 'text') {
|
|
||||||
return token.text || '';
|
|
||||||
}
|
|
||||||
if (token.type === 'strong') {
|
|
||||||
return `<strong>${renderTokens(token.tokens || [], renderer)}</strong>`;
|
|
||||||
}
|
|
||||||
if (token.type === 'em') {
|
|
||||||
return `<em>${renderTokens(token.tokens || [], renderer)}</em>`;
|
|
||||||
}
|
|
||||||
if (token.type === 'codespan') {
|
|
||||||
return `<code>${token.text || ''}</code>`;
|
|
||||||
}
|
|
||||||
if (token.type === 'del') {
|
|
||||||
return `<del>${renderTokens(token.tokens || [], renderer)}</del>`;
|
|
||||||
}
|
|
||||||
if (token.type === 'link') {
|
|
||||||
// Для ссылок используем кастомный renderer если доступен
|
|
||||||
if (renderer.link) {
|
|
||||||
return renderer.link(token);
|
|
||||||
}
|
}
|
||||||
// Fallback для встроенных ссылок
|
// Fallback для встроенных типов токенов
|
||||||
const href = token.href || '';
|
if (token.type === "text") {
|
||||||
const title = token.title ? ` title="${token.title}"` : '';
|
return token.text || "";
|
||||||
const text = token.tokens && token.tokens.length > 0
|
|
||||||
? renderTokens(token.tokens, renderer)
|
|
||||||
: (token.text || '');
|
|
||||||
return `<a href="${href}"${title}>${text}</a>`;
|
|
||||||
}
|
|
||||||
if (token.type === 'spoiler') {
|
|
||||||
// Для спойлеров используем кастомный renderer если доступен
|
|
||||||
if (renderer.spoiler) {
|
|
||||||
return renderer.spoiler(token);
|
|
||||||
}
|
}
|
||||||
return `<span class="spoiler" title="Нажмите, чтобы показать">${token.text || ''}</span>`;
|
if (token.type === "strong") {
|
||||||
}
|
return `<strong>${renderTokens(token.tokens || [], renderer)}</strong>`;
|
||||||
return token.text || '';
|
}
|
||||||
}).join('');
|
if (token.type === "em") {
|
||||||
|
return `<em>${renderTokens(token.tokens || [], renderer)}</em>`;
|
||||||
|
}
|
||||||
|
if (token.type === "codespan") {
|
||||||
|
return `<code>${token.text || ""}</code>`;
|
||||||
|
}
|
||||||
|
if (token.type === "del") {
|
||||||
|
return `<del>${renderTokens(token.tokens || [], renderer)}</del>`;
|
||||||
|
}
|
||||||
|
if (token.type === "link") {
|
||||||
|
// Для ссылок используем кастомный renderer если доступен
|
||||||
|
if (renderer.link) {
|
||||||
|
return renderer.link(token);
|
||||||
|
}
|
||||||
|
// Fallback для встроенных ссылок
|
||||||
|
const href = token.href || "";
|
||||||
|
const title = token.title ? ` title="${token.title}"` : "";
|
||||||
|
const text =
|
||||||
|
token.tokens && token.tokens.length > 0
|
||||||
|
? renderTokens(token.tokens, renderer)
|
||||||
|
: token.text || "";
|
||||||
|
return `<a href="${href}"${title}>${text}</a>`;
|
||||||
|
}
|
||||||
|
if (token.type === "spoiler") {
|
||||||
|
// Для спойлеров используем кастомный renderer если доступен
|
||||||
|
if (renderer.spoiler) {
|
||||||
|
return renderer.spoiler(token);
|
||||||
|
}
|
||||||
|
return `<span class="spoiler" title="Нажмите, чтобы показать">${
|
||||||
|
token.text || ""
|
||||||
|
}</span>`;
|
||||||
|
}
|
||||||
|
return token.text || "";
|
||||||
|
})
|
||||||
|
.join("");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Кастомный renderer для внешних ссылок и чекбоксов
|
// Кастомный renderer для внешних ссылок и чекбоксов
|
||||||
@ -75,9 +80,9 @@ const renderer: any = {
|
|||||||
link(token: any) {
|
link(token: any) {
|
||||||
const href = token.href;
|
const href = token.href;
|
||||||
const title = token.title;
|
const title = token.title;
|
||||||
|
|
||||||
// Правильно обрабатываем вложенные токены для форматирования внутри ссылок
|
// Правильно обрабатываем вложенные токены для форматирования внутри ссылок
|
||||||
let text = '';
|
let text = "";
|
||||||
if (token.tokens && token.tokens.length > 0) {
|
if (token.tokens && token.tokens.length > 0) {
|
||||||
text = renderTokens(token.tokens, this);
|
text = renderTokens(token.tokens, this);
|
||||||
} else if (token.text) {
|
} else if (token.text) {
|
||||||
@ -101,9 +106,9 @@ const renderer: any = {
|
|||||||
listitem(token: any) {
|
listitem(token: any) {
|
||||||
const task = token.task;
|
const task = token.task;
|
||||||
const checked = token.checked;
|
const checked = token.checked;
|
||||||
|
|
||||||
// Правильно обрабатываем вложенные токены для форматирования
|
// Правильно обрабатываем вложенные токены для форматирования
|
||||||
let content = '';
|
let content = "";
|
||||||
if (token.tokens && token.tokens.length > 0) {
|
if (token.tokens && token.tokens.length > 0) {
|
||||||
// Рендерим вложенные токены используя наш renderer
|
// Рендерим вложенные токены используя наш renderer
|
||||||
content = renderTokens(token.tokens, this);
|
content = renderTokens(token.tokens, this);
|
||||||
@ -174,7 +179,7 @@ export const extractTags = (content: string): string[] => {
|
|||||||
|
|
||||||
const tag = match[1];
|
const tag = match[1];
|
||||||
// Проверяем, есть ли уже тег с таким же именем (регистронезависимо)
|
// Проверяем, есть ли уже тег с таким же именем (регистронезависимо)
|
||||||
if (!tags.some(t => t.toLowerCase() === tag.toLowerCase())) {
|
if (!tags.some((t) => t.toLowerCase() === tag.toLowerCase())) {
|
||||||
tags.push(tag);
|
tags.push(tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user