Przejdź do głównej treści

Pierwsza natywna wtyczka Markdown o wysokiej wydajności dla JavaScript

Ostatnia aktualizacja:

Wtyczka edytora tekstu Markdown, która przekształca natywny obszar tekstowy w pełny zestaw do edycji — nie wymaga synchronizacji. WYSIWYG i zwykłe tryby Markdown, podgląd na żywo, znajdź i zamień, obsługa RTL, tryb ciemny. Współpracuje z Django, Laravel, Rails, Node.js, PHP i dowolnym stosem.

Instalacja

NPM (bundlery: Vite, webpack, Rollup itp.)

bash
npm install markdown-text-editor
javascript
1
2
import MarkdownEditor from 'markdown-text-editor';
new MarkdownEditor('#markdown-editor');

CDN: moduł ES

html
1
2
3
4
<script type="module">
  import MarkdownEditor from 'https://cdn.jsdelivr.net/npm/markdown-text-editor/+esm';
  new MarkdownEditor('#markdown-editor');
</script>

CDN: globalny znacznik skryptu (IIFE)

Nie ma potrzeby importowania — MarkdownEditor jest automatycznie dostępny jako zmienna globalna.

html
1
2
3
4
5
6
7
8
9
<form action="/api/save" method="POST">
  <textarea id="markdown-editor" name="content"># Hello World</textarea>
  <button type="submit">Save Content</button>
</form>

<script src="https://cdn.jsdelivr.net/npm/markdown-text-editor"></script>
<script>
  new MarkdownEditor('#markdown-editor');
</script>

Wersja demonstracyjna edytora Markdown

Szybki start

Przekaż obiekt opcji, aby dostosować edytor. Wszystkie opcje są opcjonalne — pomiń którąkolwiek, aby użyć wartości domyślnej.

javascript
1
2
3
4
const editor = new MarkdownEditor('#markdown-editor', {
  placeholder: 'Write your markdown...',
  toolbar: ['heading', 'bold', 'italic', 'strikethrough', 'ul', 'ol', 'checklist', 'blockquote', 'link', 'preview'],
});

Filozofia: „Najpierw rodzimy”

Większość redaktorów łamie standardowy przepływ pracy w sieci. MarkdownEditor to uwzględnia. Ponieważ znajduje się on bezpośrednio nad <textarea>, nie musisz uczyć się nowego sposobu obsługi danych.

  • Nie jest potrzebne wiązanie danych: od razu po wyjęciu z pudełka współpracuje z <form method="POST">
  • Dostęp standardowy: użyj document.getElementById('editor').value tak jak normalnego wejścia.
  • Niezależny od backendu: działa z dowolnym backendem (Python, Node.js, PHP itp.), tak jak normalne pole formularza

MarkdownEditor kontra EasyMDE / SimpleMDE

Większość edytorów przecen JavaScript — EasyMDE, SimpleMDE, edytory oparte na CodeMirror — Zastąp <textarea> elementem niestandardowym. Oznacza to przerwy w przesyłaniu formularza, .value nic nie zwraca i musisz napisać dodatkowy kod, aby ponownie odczytać zawartość. MarkdownEditor jest inny — ulepsza istniejący obszar tekstowy i nigdy go nie zastępuje.

Feature Edytor Markdown EasyMDE / SimpleMDE
Zachowany natywny obszar tekstowy ❌ Wymieniony
Przesyłanie formularza działa bez zmian ❌ Wymaga dodatkowego JS
Pobierz/ustaw wartość poprzez .value ❌ Potrzebny niestandardowy interfejs API
Tryb hybrydowy WYSIWYG
Wbudowane narzędzie Znajdź i zamień
RTL support
Kompatybilny z CSP (bez wbudowanego JS)
Zero konfliktów CSS
Tryb ciemny / motyw Limited
Rozmiar pakietu ~116 KB ~300KB+

Integracja frameworków

Ponieważ MarkdownEditor zachowuje natywny <textarea>, integruje się z każdym frameworkiem zaplecza bez dodatkowego kodu. Twój serwer otrzymuje treść przeceny dokładnie tak samo, jak z dowolnego standardowego pola formularza.

Django

Dodaj class do widżetu obszaru tekstowego i zainicjuj edytor — request.POST['content'] działa bez dodatkowych kroków.

python
1
2
3
4
5
6
7
8
# forms.py
class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ['content']
        widgets = {
            'content': forms.Textarea(attrs={'class': 'markdown-editor'}),
        }
javascript
1
2
new MarkdownEditor('.markdown-editor');
// request.POST['content'] contains the markdown on submit

Laravel

Użyj f.text_area z klasą — $request->input('content') odbiera bezpośrednio przecenę.

html
1
2
<textarea name="content" class="markdown-editor">{{ old('content') }}</textarea>
<script>new MarkdownEditor('.markdown-editor');</script>

Ruby on Rails

Współpracuje z form_with od razu po wyjęciu z pudełka — params[:content] zawiera przecenę. W przypadku Turbo Drive użyj turbo:load zamiast DOMContentLoaded.

javascript
1
2
3
4
5
6
document.addEventListener('turbo:load', () => {
    document.querySelectorAll('.markdown-editor:not([data-mde-init])').forEach(el => {
        el.setAttribute('data-mde-init', 'true');
        new MarkdownEditor(el);
    });
});

Node.js / Express

req.body.content otrzymuje przecenę po przesłaniu formularza — bez etapu synchronizacji, bez niestandardowej ekstrakcji.

html
1
2
3
<textarea name="content" class="markdown-editor"></textarea>
<script src="https://cdn.jsdelivr.net/npm/markdown-text-editor"></script>
<script>new MarkdownEditor('.markdown-editor');</script>

PHP

$_POST['content'] działa dokładnie tak samo jak każdy standardowy obszar tekstowy — wystarczy go dodać, a obsługa istniejącego formularza nie będzie wymagała żadnych zmian.

html
1
2
3
4
5
6
<form method="POST" action="save.php">
  <textarea name="content" class="markdown-editor"></textarea>
  <button type="submit">Save</button>
</form>
<script src="https://cdn.jsdelivr.net/npm/markdown-text-editor"></script>
<script>new MarkdownEditor('.markdown-editor');</script>

Konfiguracja

Możesz w pełni dostosować zachowanie i interfejs edytora, przekazując obiekt options. Jeśli pominiesz opcję, zostanie użyta wartość domyślna.

Nieruchomość Typ Domyślny Zamiar
mode string 'plain' Ustawia widok początkowy. Użyj hybrydy, aby uzyskać doświadczenie WYSIWYG lub zwykłej, aby uzyskać surową składnię.
placeholder string 'Write...' Tekst wyświetlany, gdy edytor jest pusty.
toolbar array [...] Określa, które narzędzia pojawiają się i w jakiej kolejności.
footer false | object wszystko widoczne Steruje paskiem stanu widocznym pod edytorem. Ustaw wartość false, aby całkowicie ją ukryć, lub przekaż obiekt, aby przełączać poszczególne statystyki.
theme string dziedziczny Jawnie ustawia motyw edytora (jasny, ciemny, śnieżna, ciemna jagoda). Jeśli zostanie pominięty, edytor dziedziczy data-theme od najbliższego elementu nadrzędnego lub samego <textarea>.
minHeight number 200 Minimalna wysokość w pikselach, do której edytor się zmniejszy, gdy treść będzie krótka. W połączeniu z maxHeight ustawia zakres automatycznego wzrostu.
maxHeight number 500 Maksymalna wysokość w pikselach, do jakiej może urosnąć edytor w trybie innym niż pełnoekranowy. Gdy treść przekroczy tę wysokość, w edytorze pojawi się pasek przewijania. Edytor posiada również uchwyt przeciągania, dzięki czemu użytkownicy mogą ręcznie zmieniać jego rozmiar powyżej tego limitu.
onChange function undefined Wywołanie zwrotne uruchamiane przy każdej zmianie treści — pisaniu, akcjach na pasku narzędzi, cofaniu/ponawianiu i kontynuacji listy. Odbiera bieżący ciąg przeceny jako jedyny argument.

🛠 Dostosowywanie paska narzędzi

Pasek narzędzi jest modułowy. Modyfikując tablicę, możesz stworzyć minimalne środowisko lub w pełni funkcjonalny pakiet mocy.

Dostępne narzędzia

Kategoria Klucze narzędziowe
Typografia heading, bold, italic, strikethrough, blockquote
Listy ul (kula), ol (numerowane), checklist
Kod code (wbudowane), codeblock (ogrodzony blok)
Wkładki hr (reguła pozioma), table (szablon tabeli)
Głoska bezdźwięczna link, image
Redagowanie undo, redo, indent, outdent
Pogląd preview

Informacje o narzędziu

Narzędzie Opis
heading Otwiera menu rozwijane umożliwiające wybranie poziomu nagłówka H1–H6
bold Włącza pogrubione formatowanie tekstu.
italic Umożliwia formatowanie tekstu kursywą.
strikethrough Umożliwia przekreślenie tekstu.
ol (Lista uporządkowana): Konwertuje tekst na format listy numerowanej.
ul (Lista nieuporządkowana): Konwertuje tekst na listę punktowaną.
checklist Dodaje pola wyboru do tekstu, dzięki czemu doskonale nadaje się do zadań, list rzeczy do zrobienia lub śledzenia stanu ukończenia.
blockquote Zaznacz cytowany lub podkreślony tekst.
code Zawija zaznaczony tekst pojedynczymi znacznikami dla kodu wbudowanego. Ponowne kliknięcie usuwa tylne znaczniki.
codeblock Zawija zaznaczony tekst w ogrodzonym bloku kodu z potrójnym znacznikiem. Ponowne kliknięcie usuwa ogrodzenia.
hr Wstawia linijkę poziomą --- w miejscu kursora, w osobnej linii.
table Wstawia startowy szablon tabeli przecen 2x3 w pozycji kursora.
image Umożliwia wstawianie obrazów za pomocą składni przecen.
link Umożliwia dodawanie hiperłączy do tekstu.
undo Aby cofnąć ostatnie zmiany.
redo Aby ponownie zastosować ostatnio cofnięte zmiany.
indent Aby zwiększyć poziom wcięcia.
outdent Aby zmniejszyć poziom wcięcia.
preview Przełącza pełnoekranowy podgląd obok siebie. Pola wyboru w panelu podglądu można kliknąć i natychmiast zaktualizować źródło przeceny. Naciśnij Escape, aby wyjść z trybu pełnoekranowego.
💡 Wskazówki dotyczące wdrożenia:
  • Zmiana kolejności: przyciski pojawiają się dokładnie w takiej kolejności, w jakiej zostały wymienione w tablicy
  • Usuwanie: po prostu pomiń dowolny klucz (np. image) z tablicy, aby całkowicie wyłączyć tę funkcję dla użytkownika
  • Natywna rezerwa: jeśli nie podasz placeholdera w JS, wtyczka automatycznie użyje atrybutu placeholder z Twojego <textarea> kodu HTML

Stopka znajduje się pod edytorem i pokazuje linię, kolumnę kursora, liczbę znaków dokumentu i opcjonalnie liczbę słów – wszystko aktualizowane w czasie rzeczywistym. Jest ona domyślnie widoczna i każdą statystykę można przełączać niezależnie.

Klawisz Typ Domyślny Opis
line boolean true Pokaż bieżący numer linii.
col boolean true Pokaż bieżący numer kolumny.
chars boolean true Pokaż całkowitą liczbę znaków.
words boolean false Pokaż całkowitą liczbę słów. Domyślnie wyłączone — ustaw na true, aby włączyć.

Przykłady użycia

javascript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
// Default — line, col, and chars visible
new MarkdownEditor('#editor');

// Disable the footer entirely
new MarkdownEditor('#editor', { footer: false });

// Hide only character count
new MarkdownEditor('#editor', { footer: { chars: false } });

// Hide line and column, keep character count
new MarkdownEditor('#editor', { footer: { line: false, col: false } });

// Show only line number
new MarkdownEditor('#editor', { footer: { col: false, chars: false } });

// Enable word count alongside the defaults
new MarkdownEditor('#editor', { footer: { words: true } });

// Show word count only
new MarkdownEditor('#editor', { footer: { line: false, col: false, chars: false, words: true } });

🔀 Tryby edycji

MarkdownEditor oferuje dwa różne sposoby pisania i formatowania treści. Możesz przełączać się między tradycyjnym widokiem skupionym na składni lub nowoczesnym, opartym na wizualizacjach.

  • plain (Domyślne): czyste, wydajne środowisko Markdown, w którym widoczna jest składnia (taka jak **bold** lub # nagłówek). Idealny dla programistów i purystów Markdown
  • hybrid: środowisko inspirowane WYSIWYG, które renderuje formatowanie (pogrubienie, kursywa, nagłówki) w czasie rzeczywistym podczas pisania, zachowując jednocześnie podstawową strukturę Markdown.
javascript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// Default initialization (Plain Mode)
new MarkdownEditor('#markdown-editor');

// Explicit Plain Mode
new MarkdownEditor('#markdown-editor', {
    mode: 'plain'
});

// Hybrid (Visual) Mode
new MarkdownEditor('#markdown-editor', {
    mode: 'hybrid'
});

Podgląd trybu hybrydowego i zwykłego:

Tryb hybrydowy

Formatowanie wizualne jest renderowane w czasie rzeczywistym podczas pisania.

Tryb zwykły (domyślny)

Koncentruje się na surowej składni Markdown, aby zapewnić lekkość.

🌙 Tematyka

MarkdownEditor automatycznie dziedziczy motyw z otaczającej strony — nie jest wymagana żadna konfiguracja. Edytor odczytuje data-theme od najbliższego przodka podczas inicjalizacji, dzięki czemu pozostaje zsynchronizowany z motywem Twojej witryny od razu po wyjęciu z pudełka.

Sposób rozwiązania tematu (kolejność priorytetów)

  1. theme opcja — jawne nadpisanie przekazane w obiekcie opcji
  2. data-theme na <textarea> — ustawiane bezpośrednio na elemencie
  3. data-theme na dowolnym przodku — np. <html>, <body> lub opakowanie <div>

Dostępne motywy

'jasny' (domyślnie), 'ciemny', 'jasny', 'ciemny'

Opcja 1 — dziedzicz z <html> lub dowolnego przodka (konfiguracja zerowa)
html
1
2
3
4
5
6
<html data-theme="dark">
  ...
  <textarea id="markdown-editor"></textarea>
  <script>
    new MarkdownEditor('#markdown-editor'); // picks up dark automatically
  </script>
Opcja 2 — ustaw data-theme bezpośrednio na <textarea>
html
1
2
3
4
<textarea id="markdown-editor" data-theme="dark"></textarea>
<script>
  new MarkdownEditor('#markdown-editor');
</script>
Opcja 3 — jawna opcja theme (zastępuje wszystko)
javascript
1
2
3
new MarkdownEditor('#markdown-editor', {
    theme: 'dark'
});

🎨 Motyw niestandardowy za pomocą zmiennych CSS

Możesz w pełni dostosować wygląd edytora, zastępując jego zmienne CSS w elemencie .markdown-editor-wrapper lub dowolnym selektorze [data-theme]. Wszystkie kolory wykorzystują przestrzeń kolorów OKLCH, aby uzyskać spójne percepcyjnie rezultaty.

Zmienny Zamiar Światło domyślne Ciemny domyślny
--color-base Tło redaktora oklch(100% 0 0) oklch(10.9% 0 0)
--color-on-base Podstawowy kolor tekstu oklch(22% 0 0) oklch(98% 0 0)
--color-primary Akcent podstawowy (aktywny pasek narzędzi, linki) oklch(51.1% .262 277) oklch(66.4% .184 286)
--color-on-primary Tekst na powierzchniach w kolorze podstawowym oklch(96.2% .018 272) oklch(10% .01 270)
--color-secondary Akcent wtórny oklch(59.1% .293 323) oklch(65% .18 220)
--color-accent Podświetl akcent (kod wbudowany, kursywa) oklch(54.1% .281 293) oklch(75% .18 50)
--color-neutral Powierzchnie neutralne (granice, przegrody) oklch(15% 0 0) oklch(85% 0 0)
--color-error Kolor stanu błędu oklch(57.7% .245 27) oklch(60% .22 30)
--border-radius Zaokrąglenie narożników ramki edytora 0.25rem
Przykład niestandardowego motywu

Zastąp dowolną zmienną w .markdown-editor-wrapper po zainicjowaniu edytora lub zdefiniuj niestandardowy blok [data-theme] w swoim arkuszu stylów:

css
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
/* Override individual variables */
.markdown-editor-wrapper {
    --color-primary: oklch(60% 0.2 30);   /* orange accent */
    --border-radius: 0.5rem;
}

/* Or define a full custom theme */
[data-theme="brand"] .markdown-editor-wrapper,
.markdown-editor-wrapper[data-theme="brand"] {
    --color-base:       oklch(15% 0.01 250);
    --color-on-base:    oklch(95% 0 0);
    --color-primary:    oklch(65% 0.22 145);   /* green */
    --color-on-primary: oklch(10% 0 0);
    --color-accent:     oklch(75% 0.18 60);
    --color-neutral:    oklch(80% 0 0);
    --border-radius:    0.75rem;
}
javascript
new MarkdownEditor('#markdown-editor', { theme: 'brand' });

Interfejs API treści

Jedną z głównych zalet MarkdownEditor jest to, że zapewnia doskonałą synchronizację podstawowego <textarea>. Niezależnie od tego, czy używasz nowoczesnego frameworku JavaScript, czy tradycyjnego backendu, takiego jak Django, PHP czy Laravel, przepływ pracy pozostaje prosty i natywny.

Czytanie i pisanie treści

1. Sposób rodzimy (zalecany)

Ponieważ edytor rozszerza standardowy obszar tekstowy, możesz używać znanych metod DOM. To najszybszy sposób na interakcję z danymi bez konieczności poznawania nowego API.

javascript
1
2
3
4
5
// Retrieve content via ID
const markdown = document.getElementById('markdown-editor').value;

// Set content via ID (The editor UI updates automatically)
document.getElementById('markdown-editor').value = "# New Heading Content";

2. Używanie odniesienia do zmiennej

Jeśli masz odwołanie do elementu Textarea, możesz go użyć bezpośrednio — nie jest potrzebny żaden interfejs API specyficzny dla biblioteki.

javascript
1
2
3
4
5
6
7
const textarea = document.getElementById('markdown-editor');

// Retrieve content
const markdown = textarea.value;

// Set content (the editor UI reflects this immediately)
textarea.value = "## Updated via JS";

3. Ustawianie początkowej zawartości po stronie serwera

Zalecanym sposobem ustawienia treści początkowej jest bezpośrednio w kodzie HTML <textarea> — działa to naturalnie z każdym frameworkiem backendowym (Django, Laravel, Rails, PHP itp.), a edytor renderuje ją automatycznie podczas init.

html
1
2
<!-- Recommended: set content server-side -->
<textarea id="markdown-editor"># Hello World</textarea>

Aby przeczytać lub zaktualizować treść w czasie wykonywania, użyj natywnej wartości textarea. Po aktualizacji wywołaj editor.render(), aby odświeżyć podgląd i warstwę hybrydową.

javascript
1
2
3
4
5
6
7
8
const textarea = document.getElementById('markdown-editor');

// Read
const markdown = textarea.value;

// Update at runtime
textarea.value = '# New content';
editor.render();

4. Zburzenie edytora — destroy()

Wywołaj funkcję editor.destroy(), aby usunąć opakowanie DOM edytora i przywrócić oryginalny <textarea> do jego pozycji w dokumencie. Przydatne w aplikacjach jednostronicowych podczas odmontowywania widoku.

javascript
1
2
3
4
const editor = new MarkdownEditor('#markdown-editor');

// Remove the editor and restore the plain textarea
editor.destroy();

Reagowanie na zmiany za pomocą onChange

Przekaż wywołanie zwrotne onChange, aby otrzymywać powiadomienia o każdej zmianie treści. Odbiera bieżący ciąg przeceny.

javascript
1
2
3
4
5
const editor = new MarkdownEditor('#markdown-editor', {
    onChange(value) {
        console.log('Content changed:', value.length, 'characters');
    }
});

Wersja robocza jest automatycznie zapisywana w localStorage

Użyj onChange, aby zapisać wersję roboczą przy każdym naciśnięciu klawisza. Przywróć go, wypełniając obszar tekstowy przed inicjalizacją edytora.

javascript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
const DRAFT_KEY = 'my-page-draft';

// Restore saved draft before init (only if textarea starts empty)
const textarea = document.getElementById('markdown-editor');
const saved = localStorage.getItem(DRAFT_KEY);
if (saved && !textarea.value) textarea.value = saved;

// Save on every change
const editor = new MarkdownEditor('#markdown-editor', {
    onChange(value) {
        localStorage.setItem(DRAFT_KEY, value);
    }
});

// Clear draft after successful form submission
document.querySelector('form').addEventListener('submit', () => {
    localStorage.removeItem(DRAFT_KEY);
});

Przesyłanie formularza

Ponieważ MarkdownEditor jest zbudowany bezpośrednio na natywnym <textarea>, jest kompatybilny z każdym frameworkiem backendowym (Django, Laravel, PHP, Ruby on Rails itp.) od razu po wyjęciu z pudełka.

Tutaj błyszczy filozofia „Native-First”. Nie musisz ręcznie synchronizować danych przed przesłaniem formularza. Przeglądarka traktuje edytor dokładnie tak, jak standardowe pole wejściowe.

html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<form method="POST" action="/api/submit">
  <textarea id="markdown-editor" name="content" class="h-48" rows="5">
    # Initial Content
  </textarea>

  <button type="submit">Submit to Server</button>
</form>

<script>
  // Just initialize it. That's it.
  new MarkdownEditor('#markdown-editor');
</script>

Uwaga: inicjalizacja wtyczki MarkdownEditor jest obowiązkowa

Po prostu użyj standardowego <formularz> HTML. Atrybut name w obszarze tekstowym jest tym, czego Twój serwer użyje do identyfikacji treści.

🚀 Dlaczego to zmienia zasady gry dla backendów

Ponieważ edytor zachowuje natywne zachowanie <textarea>, serwer obsługuje dane jako standardowy ciąg znaków. Nie jest wymagana żadna dodatkowa logika — nie ma preventDefault() ani ręcznej konstrukcji FormData.

💡 Dlaczego jest to „funkcja zabójcza”:

Większość edytorów (np. Quill, Editor.js, simpleMDE, easyMDE) zapisuje dane w złożonych strukturach JSON. Jeśli programista z nich korzysta, musi przepisać schemat bazy danych i logikę renderowania.

Dzięki MarkdownEditor programista może wykorzystać starą witrynę i zastąpić zwykły <textarea> Twoim edytorem, a backend nawet nie zauważy, że się to zmieniło. Po prostu otrzymuje ten sam surowy tekst, co zawsze, ale użytkownik otrzymuje 10 razy lepsze wrażenia.

Ramy / język Jak uzyskać dostęp do treści Markdown
PHP $_POST['content']
Django request.POST.get('content')
Node.js (Express) req.body.content
Laravel $request->input('content')
Ruby on Rails params[:content]

🖼️ Zaawansowane przesyłanie obrazu

Natywna obsługa przesyłania obrazów — zamiast polegania na wolnych, obciążających pamięć ciągach Base64 — to znacząca korzyść zarówno pod względem wydajności, jak i SEO.

Opcje konfiguracji

Narzędzie do tworzenia obrazów obsługuje konfigurację fileInput do obsługi bezpośredniego przesyłania na serwer.

  • accept: zdefiniuj tablicę dozwolonych formatów obrazów (np. „webp”, „avif”)
  • uploadUrl: Określ punkt końcowy zaplecza, do którego obiekt File zostanie wysłany za pośrednictwem POST
  • params: opcjonalny obiekt do wysyłania dodatkowych danych (takich jak tokeny CSRF, identyfikatory użytkowników lub nazwy folderów) wraz z plikiem obrazu

Przykład użycia (pełna konfiguracja)

javascript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
const options = {
  placeholder: 'Start writing...',
  toolbar: [
    'link',
    {
      image: {
        fileInput: {
            accept: ['webp', 'avif'], // restrict the image upload format
            uploadUrl: '/api/upload', // Your upload endpoint
            params: {
                _token: 'your_csrf_token_here', // Essential for Laravel/Django
                folder: 'blog_posts'
            }
        },
        // Supports boolean: true/false OR object: { required: true }
        altInput: { required: true }
      }
    },
    'preview'
  ],
}
const editor = new MarkdownEditor('#markdown-editor', options);

📡 Integracja serwerów

Żądanie

Edytor wysyła żądanie POST jako multipart/form-data. Domyślnie zawiera:

  • image_file: Rzeczywisty obiekt pliku
  • image_alt: tekst alternatywny wprowadzony przez użytkownika
  • ...plus wszelkie niestandardowe dane zdefiniowane w obiekcie params

Wymagana odpowiedź

Aby potwierdzić pomyślne przesłanie i wstawić obraz do edytora, Twój serwer musi zwrócić następującą strukturę JSON:

json
1
2
3
4
{
  "success": true,
  "image_path": "https://cdn.yourdomain.com/uploads/image.webp"
}

Uwaga: upewnij się, że używasz klucza image_path jako adresu URL przesłanego obrazu.

Walidacja tekstu alternatywnego obrazu (altInput)

Aby mieć pewność, że Twoje treści pozostaną dostępne i przyjazne dla SEO, MarkdownEditor domyślnie wymusza sprawdzanie poprawności tekstu alternatywnego.

  • Zachowanie domyślne: jeśli nie zdefiniowano altInput, domyślnie jest to { wymagane: true
  • Wymuś dostępność: użytkownicy nie będą mogli wstawić obrazu, dopóki nie zostanie podany opis alternatywny

1. Domyślne (nie wymaga konfiguracji)

javascript
1
2
3
4
// Alt text is REQUIRED by default
image: {
  fileInput: { uploadUrl: '/api/upload' }
}

2. Skrót (wyłącz weryfikację)

Jeśli chcesz zezwolić na obrazy bez opisów, po prostu ustaw wartość logiczną na false.

javascript
1
2
3
image: {
  altInput: false // Users can now skip the alt text field
}

3. Oparte na obiektach (jawne)

javascript
1
2
3
4
5
image: {
    altInput: {
        required: false // Disables alt text validation — users can skip the alt field
    }
}

Standardowe użycie obrazu (bez fileInput)

Jeśli fileInput nie jest skonfigurowane, edytor domyślnie korzysta z prostego modalu opartego na adresie URL. Jest to idealne rozwiązanie, jeśli Twoi użytkownicy głównie łączą się z zewnętrznymi hostami obrazów.

javascript
1
2
3
4
5
6
7
8
const options = {
  toolbar: [
    'link',
    'image',
    'preview'
  ],
}
const editor = new MarkdownEditor('#markdown-editor', options);

💡 Po co używać parametrów?

W frameworkach takich jak Laravel czy Django nie można przesyłać plików bez tokena CSRF. Dodając _token do obiektu params, Twoje żądanie bezproblemowo przejdzie przez oprogramowanie pośredniczące bezpieczeństwa zaplecza, zachowując filozofię „Zero Logic” dla kontrolerów po stronie serwera.

⌨️ Skróty klawiaturowe

Typowe czynności formatowania można uruchomić bezpośrednio z klawiatury, bez dotykania paska narzędzi. Każdy skrót jest także pokazany w podpowiedzi odpowiedniego przycisku na pasku narzędzi.

Skrót Działanie
Ctrl + B  /  ⌘ B Przełącz opcję Pogrubienie
Ctrl + I  /  ⌘ I Przełącz opcję Kursywa
Ctrl + K  /  ⌘ K Wstaw łącze
Ctrl + `  /  ⌘ ` Przełącz wbudowany Kod
Ctrl + Shift + S  /  ⌘ ⇧ S Przełącz opcję Przekreślenie
Ctrl + Z  /  ⌘ Z Anulować
Ctrl + Shift + Z  /  ⌘ ⇧ Z Przerobić
Tab Wcięcie wybranych linii
Shift + Tab Zmniejsz wybrane linie
Ctrl + F  /  ⌘ F Otwórz panel Znajdź
Ctrl + H  /  ⌘ H Otwórz panel Znajdź i zamień
Escape Zamknij panel Znajdź / Wyjdź z podglądu pełnoekranowego

🔍 Znajdź i amp; Zastępować

W edytorze dostępny jest wbudowany panel wyszukiwania i zamiany — nie jest potrzebne żadne rozszerzenie przeglądarki ani osobne narzędzie.

  • Naciśnij Ctrl + F (lub ⌘ F), aby otworzyć panel Znajdź
  • Naciśnij Ctrl + H (lub ⌘ H), aby otworzyć Find & Wymień panel
  • Wyszukiwanie nie uwzględnia wielkości liter i wyświetla licznik meczów na żywo (np. 3 z 12)
  • Nawiguj po dopasowaniach za pomocą przycisków ▲ / ▼ lub Enter / Shift + Enter
  • Opcja Zamień zastępuje aktualnie podświetlone dopasowanie; Opcja Zamień wszystko zastępuje wszystkie wystąpienia na raz
  • Naciśnij Escape, aby zamknąć panel i powrócić do edytora

Panel unosi się w prawym górnym rogu obszaru zawartości edytora i nie zakłóca pisania.

Cechy

🔌 Integracja formularzy natywnych

Działa dokładnie tak jak standardowy <textarea>. Żadnych skomplikowanych interfejsów API — po prostu użyj atrybutu value lub name. To „po prostu działa” ze standardowymi formularzami HTML w PHP, Django lub Node.js.

🖼️ Zaawansowane przesyłanie obrazu

Skonfiguruj przesyłanie natywnego serwera za pośrednictwem interfejsu API. Unikaj ciężkich ciągów Base64, aby zapewnić szybsze ładowanie strony i lepsze SEO, hostując obrazy we własnej sieci CDN.

🔀 Tryby hybrydowe i zwykłe

Przełączaj się między trybem Hybrid (WYSIWYG) do edycji wizualnej lub trybem Plain Markdown, aby uzyskać tradycyjne wrażenia z kodowania.

🚀 Wysoka wydajność

Mały pakiet ~116KB zoptymalizowany pod kątem „Ciężkich treści”. Obsługuje ogromne dokumenty i duże pliki bez opóźnień wejściowych i spadków wydajności. Odrzucone aktualizacje podglądu, obliczenia stylu w pamięci podręcznej i bezkonfliktowa obsługa klawiatury — więc klawisze Tab i Enter zawsze wykonują dokładnie jedną czynność.

🌍 Wbudowana obsługa RTL

Natywna obsługa języków pisanych od prawej do lewej, takich jak arabski, urdu i perski. Idealny do tworzenia aplikacji dostępnych na całym świecie.

✨ Podświetlanie składni

Zwiększona czytelność dzięki przejrzystemu kodowi i formatowaniu przecen.

🌙 Motywy adaptacyjne

Zawiera automatyczną obsługę trybu ciemnego. Synchronizuje się z ustawieniami systemu lub biblioteką Frutjam UI, zapewniając płynne wrażenia wizualne.

📝 Inteligentna edycja

Automatyczna kontynuacja listy w stylu GitHuba dla list uporządkowanych, list nieuporządkowanych i list kontrolnych — naciśnij Enter, a edytor będzie kontynuował wzorzec. Pola wyboru w okienku podglądu można kliknąć i natychmiast synchronizować ze źródłem przecen.

📱 W pełni responsywny

Płynny, dostosowany do urządzeń mobilnych interfejs użytkownika, który idealnie dopasowuje się do komputerów stacjonarnych, tabletów i smartfonów, umożliwiając edycję w dowolnym miejscu.

📦 Uniwersalne wsparcie

Kompatybilny z ESM, UMD, CommonJS i IIFE. Działa od razu po uruchomieniu za pośrednictwem CDN (<script src>), npm lub dowolnego programu pakującego (Vite, webpack, Rollup) — nie jest wymagana dodatkowa konfiguracja.

♿ Dostępne domyślnie

Wbudowana pełna obsługa ARIA — punkt orientacyjny paska narzędzi, oznaczony obszar podglądu, przyciski przyjazne dla czytnika ekranu, wciśnięty aria na przełączniku podglądu, wyłączony i aria-wyłączony na nieaktywnych narzędziach oraz prawidłowe przywracanie ostrości po zamknięciu modów.

🛡️ Zero konfliktów CSS

Style edytora są w pełni ograniczone do .markdown-editor-wrapper. Globalna inspekcja wstępna Tailwinda jest wykluczona, więc edytor może bezpiecznie współpracować z Bootstrapem, Tailwindem lub jakimkolwiek innym frameworkiem, nie naruszając ich stylu.

⌨️ Skróty klawiaturowe

Ctrl+B, Ctrl+I, Ctrl+K, Ctrl+`, Ctrl+Shift+S — typowe akcje formatowania bez dotykania myszy. Każdy skrót jest pokazany w etykiecie przycisku paska narzędzi.

🔍 Znajdź i amp; Zastępować

Naciśnij Ctrl+F, aby znaleźć lub Ctrl+H, aby otworzyć, znajdź & i zamień. Wyszukiwanie bez rozróżniania wielkości liter z licznikiem dopasowań na żywo, nawigacją następny/poprzedni, pojedynczym zastępowaniem i zastępowaniem wszystkich — bez opuszczania edytora.

🔒 Podgląd bezpiecznego XSS

Wyrenderowany podgląd jest oczyszczany za pomocą DOMPurify przed zapisaniem w DOM. Tagi skryptów, wbudowane procedury obsługi zdarzeń i złośliwe adresy URL w spreparowanych danych wejściowych Markdown są usuwane automatycznie — nie jest wymagana żadna konfiguracja.

▶️ Podgląd w czasie rzeczywistym

Zobacz, jak Twoje przeceny są renderowane natychmiastowo podczas pisania.

🔗 Łatwa integracja

Bezproblemowo integruj się z dowolnym projektem internetowym przy minimalnej konfiguracji.

🛠️ Konfigurowalny pasek narzędzi

Dynamicznie konfiguruj i zmieniaj kolejność opcji paska narzędzi, takich jak pogrubienie, kursywa i inne.

Przykład pełnej konfiguracji

Użyj tego obszernego przykładu, aby zainicjować MarkdownEditor ze wszystkimi podstawowymi funkcjami, w tym niestandardową kolejnością pasków narzędzi i zaawansowaną obsługą przesyłania obrazów.

javascript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
const editor = new MarkdownEditor('#markdown-editor', {
    mode: 'hybrid',
    placeholder: 'Start writing...',
    footer: {
        line: true,
        col: true,
        chars: true,
        words: true,
    },
    onChange(value) {
        console.log('Content updated:', value.length, 'characters');
    },
    toolbar: [
        'heading', 'bold', 'italic', 'strikethrough', 'blockquote',
        'ul', 'ol', 'checklist',
        'code', 'codeblock', 'hr', 'table',
        {
            image: {
                fileInput: {
                    accept: ['webp', 'avif', 'png'],
                    uploadUrl: '/api/upload'
                }
            }
        },
        'link', 'undo', 'redo', 'indent', 'outdent', 'preview'
    ],
});

// Read content natively
const markdown = document.getElementById('markdown-editor').value;

// destroy() when the view unmounts (SPAs)
// editor.destroy();

Uznałeś to za przydatne?

Gwiazda GitHuba pomaga innym programistom odkryć edytor. Jest częścią Frutjam. Gwiazdka też pomaga.

Gwiazda na GitHubie

Używasz kodu Claude'a, kursora lub innego edytora AI?

Cherry MCP na żądanie udostępnia edytorowi AI dokładne nazwy i strukturę klas Edytor Markdownów. Żadnych więcej zajęć z halucynacjami.

Try Cherry MCP