mirror of
https://github.com/jaandrle/deka-dom-el
synced 2025-07-29 07:00:16 +02:00
🔤 intro
This commit is contained in:
162
README.md
162
README.md
@@ -2,94 +2,110 @@
|
|||||||
| [source code on GitHub](https://github.com/jaandrle/deka-dom-el)
|
| [source code on GitHub](https://github.com/jaandrle/deka-dom-el)
|
||||||
| [*mirrored* on Gitea](https://gitea.jaandrle.cz/jaandrle/deka-dom-el)
|
| [*mirrored* on Gitea](https://gitea.jaandrle.cz/jaandrle/deka-dom-el)
|
||||||
|
|
||||||
|
# Deka DOM Elements
|
||||||
|
|
||||||
***Vanilla for flavouring — a full-fledged feast for large projects***
|
***Vanilla for flavouring — a full-fledged feast for large projects***
|
||||||
|
|
||||||
*…use simple DOM API by default and library tools and logic when you need them*
|
*…use simple DOM API by default and library tools and logic when you need them*
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
|
// 🌟 Reactive component with clear separation of concerns
|
||||||
document.body.append(
|
document.body.append(
|
||||||
el(HelloWorldComponent, { initial: "🚀" })
|
el(EmojiCounter, { initial: "🚀" })
|
||||||
);
|
);
|
||||||
/** @typedef {"🎉" | "🚀"} Emoji */
|
|
||||||
/** @param {{ initial: Emoji }} attrs */
|
|
||||||
function HelloWorldComponent({ initial }){
|
|
||||||
const clicks= S(0);
|
|
||||||
const emoji= S(initial);
|
|
||||||
/** @param {HTMLOptionElement} el */
|
|
||||||
const isSelected= el=> (el.selected= el.value===initial);
|
|
||||||
// @ts-expect-error 2339: The <select> has only two options with {@link Emoji}
|
|
||||||
const onChange= on("change", event=> emoji.set(event.target.value));
|
|
||||||
|
|
||||||
return el().append(
|
function EmojiCounter({ initial }) {
|
||||||
el("p", {
|
// ✨ State - Define reactive data
|
||||||
textContent: S(() => `Hello World ${emoji.get().repeat(clicks.get())}`),
|
const count = S(0);
|
||||||
className: "example",
|
const emoji = S(initial);
|
||||||
ariaLive: "polite", //OR ariaset: { live: "polite" },
|
|
||||||
dataset: { example: "Example" }, //OR dataExample: "Example",
|
/** @param {HTMLOptionElement} el */
|
||||||
}),
|
const isSelected= el=> (el.selected= el.value===initial);
|
||||||
el("button",
|
|
||||||
{ textContent: "Fire", type: "button" },
|
// 🔄 View - UI updates automatically when signals change
|
||||||
on("click", ()=> clicks.set(clicks.get() + 1)),
|
return el().append(
|
||||||
on("keyup", ()=> clicks.set(clicks.get() - 2)),
|
el("p", {
|
||||||
),
|
className: "output",
|
||||||
el("select", null, onChange).append(
|
textContent: S(() =>
|
||||||
el(OptionComponent, "🎉", isSelected),//OR { textContent: "🎉" }
|
`Hello World ${emoji.get().repeat(clicks.get())}`),
|
||||||
el(OptionComponent, "🚀", isSelected),//OR { textContent: "🚀" }
|
}),
|
||||||
)
|
|
||||||
);
|
// 🎮 Controls - Update state on events
|
||||||
|
el("button", { textContent: "Add Emoji" },
|
||||||
|
on("click", () => count.set(count.get() + 1))
|
||||||
|
),
|
||||||
|
|
||||||
|
el("select", null, on("change", e => emoji.set(e.target.value)))
|
||||||
|
.append(
|
||||||
|
el(Option, "🎉", isSelected),
|
||||||
|
el(Option, "🚀", isSelected),
|
||||||
|
el(Option, "💖", isSelected),
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
function OptionComponent({ textContent }){
|
function Option({ textContent }){
|
||||||
return el("option", { value: textContent, textContent })
|
return Ol("option", { value: textContent, textContent });
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
# Deka DOM Elements
|
|
||||||
Creating reactive elements, components and Web components using [IDL](https://developer.mozilla.org/en-US/docs/
|
|
||||||
Glossary/IDL)/JavaScript DOM API and [**signals/observables**](#signals).
|
|
||||||
|
|
||||||
## Inspiration and suggested alternatives
|
Creating reactive elements, components, and Web Components using the native
|
||||||
- my previous library (mostly used internaly): [jaandrle/dollar_dom_component: Functional DOM components without
|
[IDL](https://developer.mozilla.org/en-US/docs/Glossary/IDL)/JavaScript DOM API enhanced with
|
||||||
JSX and virtual DOM.](https://github.com/jaandrle/dollar_dom_component)
|
[**signals/observables**](#understanding-signals).
|
||||||
- [vanjs-org/van: 🍦 VanJS: World's smallest reactive UI framework. Incredibly Powerful, Insanely Small -
|
|
||||||
Everyone can build a useful UI app in an hour.](https://github.com/vanjs-org/van)
|
|
||||||
- [hyperhype/hyperscript: Create HyperText with JavaScript.](https://github.com/hyperhype/hyperscript)
|
|
||||||
- [adamhaile/S: S.js - Simple, Clean, Fast Reactive Programming in Javascript](https://github.com/adamhaile/S)
|
|
||||||
([adamhaile/surplus: High performance JSX web views for S.js applications](https://github.com/adamhaile/surplus))
|
|
||||||
- [potch/signals: a small reactive signals library](https://github.com/potch/signals)
|
|
||||||
|
|
||||||
## Why an another one?
|
## Features at a Glance
|
||||||
This library falls somewhere between van/hyperscript and [solid-js](https://github.com/solidjs/solid) in terms of size,
|
|
||||||
complexity, and usability.
|
|
||||||
|
|
||||||
Another goal is to proceed in the best spirit of functional programming. This involves starting with
|
- ✅ **No build step required** — use directly in browsers or Node.js
|
||||||
pure JavaScript (DOM API) and gradually adding auxiliary functions, ranging from “minor” improvements
|
- ☑️ **Lightweight** — ~10-15kB minified (original goal 10kB) with zero/minimal dependencies
|
||||||
to the capability of writing complete declarative reactive UI templates.
|
- ✅ **Declarative & functional approach** for clean, maintainable code
|
||||||
|
- ✅ **Optional signals** with support for custom reactive implementations
|
||||||
|
- ✅ **Server-side rendering** support via [jsdom](https://github.com/jsdom/jsdom)
|
||||||
|
- 🔄 **TypeScript support** (work in progress)
|
||||||
|
- 🔄 **Enhanced Web Components** support (work in progress)
|
||||||
|
|
||||||
As a result, any “internal” function (`assign`, `classListDeclarative`, `on`, `dispatchEvent`, …, `S`, …)
|
## Why Another Library?
|
||||||
can be used independently, although they are primarily designed for use in combination. This can also,
|
|
||||||
hopefully, help in integrating the library into existing projects.
|
|
||||||
|
|
||||||
To balance these requirements, numerous compromises have been made. To summarize:
|
This library bridges the gap between minimal solutions like van/hyperscript and more comprehensive frameworks like [solid-js](https://github.com/solidjs/solid), offering a balanced trade-off between size, complexity, and usability.
|
||||||
- [ ] Library size: 10–15kB minified (the original goal was a maximum of 10kB)
|
|
||||||
- [x] Optional use of *signals* with the ability to register *your own signals/observables implementation*
|
|
||||||
- [x] *No build step required*
|
|
||||||
- [x] Preference for a *declarative/functional* approach
|
|
||||||
- [x] Focus on zero/minimal dependencies
|
|
||||||
- [ ] Support for/enhancement of custom elements (web components)
|
|
||||||
- [x] Support for SSR ([jsdom](https://github.com/jsdom/jsdom))
|
|
||||||
- [ ] WIP providing types
|
|
||||||
|
|
||||||
## First steps
|
Following functional programming principles, Deka DOM Elements starts with pure JavaScript (DOM API) and gradually adds auxiliary functions. These range from minor improvements to advanced features for building complete declarative reactive UI templates.
|
||||||
- [**Guide**](https://jaandrle.github.io/deka-dom-el)
|
|
||||||
- Documentation
|
|
||||||
- Installation
|
|
||||||
- npm
|
|
||||||
- [dist/](dist/) (`https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/`…)
|
|
||||||
|
|
||||||
## Signals
|
A key advantage: any internal function (`assign`, `classListDeclarative`, `on`, `dispatchEvent`, `S`, etc.) can be used independently while also working seamlessly together. This modular approach makes it easier to integrate the library into existing projects.
|
||||||
- [Signals — whats going on behind the scenes \| by Ryan Hoffnan \|
|
|
||||||
ITNEXT](https://itnext.io/signals-whats-going-on-behind-the-scenes-ec858589ea63)
|
## Getting Started
|
||||||
- [The Evolution of Signals in JavaScript - DEV
|
|
||||||
Community](https://dev.to/this-is-learning/the-evolution-of-signals-in-javascript-8ob)
|
### Installation
|
||||||
- there is also [tc39/proposal-signals:
|
|
||||||
A proposal to add signals to JavaScript.](https://github.com/tc39/proposal-signals)
|
#### npm
|
||||||
- [Observer pattern - Wikipedia](https://en.wikipedia.org/wiki/Observer_pattern)
|
```bash
|
||||||
|
# TBD
|
||||||
|
# npm install deka-dom-el
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Direct Script
|
||||||
|
```html
|
||||||
|
<script src="https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/dde-with-signals.min.js"></script>
|
||||||
|
<script type="module">
|
||||||
|
const { el, S } = dde;
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
|
||||||
|
- [**Interactive Guide**](https://jaandrle.github.io/deka-dom-el): WIP
|
||||||
|
- [Examples](./examples/): TBD/WIP
|
||||||
|
|
||||||
|
## Understanding Signals
|
||||||
|
|
||||||
|
Signals are the reactive backbone of Deka DOM Elements:
|
||||||
|
|
||||||
|
- [Signals — what's going on behind the scenes](https://itnext.io/signals-whats-going-on-behind-the-scenes-ec858589ea63)
|
||||||
|
- [The Evolution of Signals in JavaScript](https://dev.to/this-is-learning/the-evolution-of-signals-in-javascript-8ob)
|
||||||
|
- [TC39 Signals Proposal](https://github.com/tc39/proposal-signals) (future standard)
|
||||||
|
- [Observer pattern](https://en.wikipedia.org/wiki/Observer_pattern) (underlying concept)
|
||||||
|
|
||||||
|
## Inspiration and Alternatives
|
||||||
|
|
||||||
|
- [vanjs-org/van](https://github.com/vanjs-org/van) - World's smallest reactive UI framework
|
||||||
|
- [adamhaile/S](https://github.com/adamhaile/S) - Simple, clean, fast reactive programming
|
||||||
|
- [hyperhype/hyperscript](https://github.com/hyperhype/hyperscript) - Create HyperText with JavaScript
|
||||||
|
- [potch/signals](https://github.com/potch/signals) - A small reactive signals library
|
||||||
|
- [jaandrle/dollar_dom_component](https://github.com/jaandrle/dollar_dom_component) - Functional DOM components without JSX/virtual DOM
|
||||||
|
14
docs/components/examples/introducing/3ps-before.js
Normal file
14
docs/components/examples/introducing/3ps-before.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// pseudocode
|
||||||
|
// Mixed concerns make code hard to maintain
|
||||||
|
const button = document.querySelector('button');
|
||||||
|
let count = 0;
|
||||||
|
|
||||||
|
button.addEventListener('click', () => {
|
||||||
|
count++;
|
||||||
|
document.querySelector('p').textContent =
|
||||||
|
'Clicked ' + count + ' times';
|
||||||
|
|
||||||
|
if (count > 10) {
|
||||||
|
button.disabled = true;
|
||||||
|
}
|
||||||
|
});
|
@@ -1,6 +1,14 @@
|
|||||||
// pseudo code!
|
// pseudocode
|
||||||
const onchage=
|
// 1. Create state
|
||||||
event=>
|
const count = S(0);
|
||||||
console.log("Reacting to the:", event); // A
|
|
||||||
input.addEventListener("change", onchange); // B
|
// 2. React to state changes
|
||||||
input.dispatchEvent(new Event("change")); // C
|
S.on(count, value => {
|
||||||
|
updateUI(value);
|
||||||
|
if (value > 10) disableButton();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3. Update state on events
|
||||||
|
button.addEventListener('click', () => {
|
||||||
|
count.set(count.get() + 1);
|
||||||
|
});
|
||||||
|
@@ -1,19 +1,30 @@
|
|||||||
import { el } from "deka-dom-el";
|
import { el, on } from "deka-dom-el";
|
||||||
import { S } from "deka-dom-el/signals";
|
import { S } from "deka-dom-el/signals";
|
||||||
const threePS= ({ emoji= "🚀" })=> {
|
|
||||||
const clicks= S(0); // A
|
|
||||||
return el().append(
|
|
||||||
el("p", S(()=>
|
|
||||||
"Hello World "+emoji.repeat(clicks.get()) // B
|
|
||||||
)),
|
|
||||||
el("button", {
|
|
||||||
type: "button",
|
|
||||||
onclick: ()=> clicks.set(clicks.get()+1), // C
|
|
||||||
textContent: "Fire",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
};
|
|
||||||
document.body.append(
|
|
||||||
el(threePS, { emoji: "🎉" }),
|
|
||||||
);
|
|
||||||
|
|
||||||
|
// A HelloWorld component using the 3PS pattern
|
||||||
|
function HelloWorld({ emoji = "🚀" }) {
|
||||||
|
// PART 1: Create reactive state
|
||||||
|
const clicks = S(0);
|
||||||
|
|
||||||
|
return el().append(
|
||||||
|
// PART 2: Bind state to UI elements
|
||||||
|
el("p", {
|
||||||
|
className: "greeting",
|
||||||
|
// This paragraph automatically updates when clicks changes
|
||||||
|
textContent: S(() => `Hello World ${emoji.repeat(clicks.get())}`)
|
||||||
|
}),
|
||||||
|
|
||||||
|
// PART 3: Update state in response to events
|
||||||
|
el("button", {
|
||||||
|
type: "button",
|
||||||
|
textContent: "Add emoji",
|
||||||
|
// When clicked, update the state
|
||||||
|
onclick: () => clicks.set(clicks.get() + 1)
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the component in your app
|
||||||
|
document.body.append(
|
||||||
|
el(HelloWorld, { emoji: "🎉" })
|
||||||
|
);
|
@@ -2,7 +2,7 @@ import { t, T } from "./utils/index.js";
|
|||||||
export const info= {
|
export const info= {
|
||||||
href: "./",
|
href: "./",
|
||||||
title: t`Introduction`,
|
title: t`Introduction`,
|
||||||
description: t`Introducing a library.`,
|
description: t`A lightweight, reactive DOM library for creating dynamic UIs with a declarative syntax`,
|
||||||
};
|
};
|
||||||
|
|
||||||
import { el } from "deka-dom-el";
|
import { el } from "deka-dom-el";
|
||||||
@@ -26,37 +26,86 @@ const references= {
|
|||||||
export function page({ pkg, info }){
|
export function page({ pkg, info }){
|
||||||
const page_id= info.id;
|
const page_id= info.id;
|
||||||
return el(simplePage, { info, pkg }).append(
|
return el(simplePage, { info, pkg }).append(
|
||||||
el("p", t`The library tries to provide pure JavaScript tool(s) to create reactive interfaces using …`),
|
el("h2", t`Vanilla for flavouring — a full-fledged feast for large projects`),
|
||||||
|
|
||||||
el(h3, t`Event-driven programming (3 parts separation ≡ 3PS)`),
|
|
||||||
el("p").append(t`
|
|
||||||
Let's introduce the basic principle on which the library is built. We'll use the JavaScript listener as
|
|
||||||
a starting point.
|
|
||||||
`),
|
|
||||||
el(code, { src: fileURL("./components/examples/introducing/3ps.js"), page_id }),
|
|
||||||
el("p").append(...T`
|
el("p").append(...T`
|
||||||
As we can see, in the code at location “A” we define ${el("em", t`how to react`)} when the function
|
Welcome to Deka DOM Elements (DDE) — a lightweight library for building dynamic UIs with a
|
||||||
is called with any event as an argument. At that moment, we ${el("em", t`don’t care who/why/how`)}
|
declarative syntax that stays close to the native DOM API. DDE gives you powerful reactive
|
||||||
the function was called. Similarly, at point “B”, we reference to a function to be called on the event
|
tools without the complexity and overhead of larger frameworks.
|
||||||
${el("em", t`without caring`)} what the function will do at that time. Finally, at point “C”, we tell
|
|
||||||
the application that a change has occurred, in the input, and we ${el("em", t`don't care if/how someone`)}
|
|
||||||
is listening for the event.
|
|
||||||
`),
|
`),
|
||||||
|
el("div", { className: "callout" }).append(
|
||||||
|
el("h4", t`What Makes DDE Special`),
|
||||||
|
el("ul").append(
|
||||||
|
el("li", t`No build step required — use directly in the browser`),
|
||||||
|
el("li", t`Lightweight core (~10-15kB minified) with zero dependencies`),
|
||||||
|
el("li", t`Natural DOM API — work with real DOM nodes, not abstractions`),
|
||||||
|
el("li", t`Built-in reactivity with powerful signals system`),
|
||||||
|
el("li", t`Clean code organization with the 3PS pattern`)
|
||||||
|
)
|
||||||
|
),
|
||||||
el(example, { src: fileURL("./components/examples/introducing/helloWorld.js"), page_id }),
|
el(example, { src: fileURL("./components/examples/introducing/helloWorld.js"), page_id }),
|
||||||
|
|
||||||
|
el(h3, t`The 3PS Pattern: A Better Way to Build UIs`),
|
||||||
el("p").append(...T`
|
el("p").append(...T`
|
||||||
The library introduces a new “type” of variable/constant called ${el("em", t`signal`)} allowing us to
|
At the heart of DDE is the 3PS (3-Part Separation) pattern. This simple yet powerful approach helps you
|
||||||
to use introduced 3PS pattern in our applications. As you can see it in the example above.
|
organize your UI code into three distinct areas, making your applications more maintainable and easier to reason about.
|
||||||
`),
|
`),
|
||||||
|
el("div", { className: "illustration" }).append(
|
||||||
|
el("div", { className: "tabs" }).append(
|
||||||
|
el("div", { className: "tab" }).append(
|
||||||
|
el("h5", t`Traditional DOM Manipulation`),
|
||||||
|
el(code, { src: fileURL("./components/examples/introducing/3ps-before.js"), page_id }),
|
||||||
|
),
|
||||||
|
el("div", { className: "tab" }).append(
|
||||||
|
el("h5", t`DDE's 3PS Pattern`),
|
||||||
|
el(code, { src: fileURL("./components/examples/introducing/3ps.js"), page_id }),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
el("p").append(...T`
|
el("p").append(...T`
|
||||||
Also please notice that there is very similar 3PS pattern used for separate creation of UI and
|
The 3PS pattern separates your code into three clear parts:
|
||||||
business logic.
|
|
||||||
`),
|
`),
|
||||||
|
el("ol").append(
|
||||||
|
el("li").append(...T`
|
||||||
|
${el("strong", "Create State")}: Define your application's reactive data using signals
|
||||||
|
`),
|
||||||
|
el("li").append(...T`
|
||||||
|
${el("strong", "Bind to Elements")}: Define how UI elements react to state changes
|
||||||
|
`),
|
||||||
|
el("li").append(...T`
|
||||||
|
${el("strong", "Update State")}: Modify state in response to user events or other triggers
|
||||||
|
`)
|
||||||
|
),
|
||||||
|
|
||||||
el("p").append(...T`
|
el("p").append(...T`
|
||||||
The 3PS is very simplified definition of the pattern. There are more deep/academic definitions more precisely
|
By separating these concerns, your code becomes more modular, testable, and easier to maintain. This approach
|
||||||
describe usage in specific situations, see for example ${el("a", { textContent: t`MVVM`, ...references.w_mvv })}
|
shares principles with more formal patterns like ${el("a", { textContent: "MVVM", ...references.w_mvv })} and
|
||||||
or ${el("a", { textContent: t`MVC`, ...references.w_mvc })}.
|
${el("a", { textContent: "MVC", ...references.w_mvc })}, but with less overhead and complexity.
|
||||||
`),
|
`),
|
||||||
|
|
||||||
el(h3, t`Organization of the documentation`),
|
el("div", { className: "note" }).append(
|
||||||
|
el("p").append(...T`
|
||||||
|
The 3PS pattern becomes especially powerful when combined with components, allowing you to create
|
||||||
|
reusable pieces of UI with encapsulated state and behavior. You'll learn more about this in the
|
||||||
|
following sections.
|
||||||
|
`)
|
||||||
|
),
|
||||||
|
|
||||||
|
el(h3, t`How to Use This Documentation`),
|
||||||
|
el("p").append(...T`
|
||||||
|
This guide will take you through DDE's features step by step:
|
||||||
|
`),
|
||||||
|
el("ol").append(
|
||||||
|
el("li").append(...T`${el("strong", "Elements")} — Creating and manipulating DOM elements`),
|
||||||
|
el("li").append(...T`${el("strong", "Events")} — Handling user interactions and lifecycle events`),
|
||||||
|
el("li").append(...T`${el("strong", "Signals")} — Adding reactivity to your UI`),
|
||||||
|
el("li").append(...T`${el("strong", "Scopes")} — Managing component lifecycles`),
|
||||||
|
el("li").append(...T`${el("strong", "Custom Elements")} — Building web components`),
|
||||||
|
el("li").append(...T`${el("strong", "Debugging")} — Tools to help you build and fix your apps`),
|
||||||
|
el("li").append(...T`${el("strong", "SSR")} — Server-side rendering with DDE`)
|
||||||
|
),
|
||||||
|
el("p").append(...T`
|
||||||
|
Each section builds on the previous ones, so we recommend following them in order.
|
||||||
|
Let's get started with the basics of creating elements!
|
||||||
|
`),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
30
nohup.out
Normal file
30
nohup.out
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
Markserv boot: starting Markserv...
|
||||||
|
(node:130669) [DEP0128] DeprecationWarning: Invalid 'main' field in '/home/jaandrle/.npm/_npx/13a70f167aa91a98/node_modules/implant/package.json' of 'implant'. Please either fix that or report it to the module author
|
||||||
|
(Use `node --trace-deprecation ...` to show where the warning was created)
|
||||||
|
(node:130669) [DEP0128] DeprecationWarning: Invalid 'main' field in '/home/jaandrle/.npm/_npx/13a70f167aa91a98/node_modules/balanced-pairs/package.json' of 'balanced-pairs'. Please either fix that or report it to the module author
|
||||||
|
(node:130669) [DEP0128] DeprecationWarning: Invalid 'main' field in '/home/jaandrle/.npm/_npx/13a70f167aa91a98/node_modules/super-split/package.json' of 'super-split'. Please either fix that or report it to the module author
|
||||||
|
Markserv address: http://localhost:8642
|
||||||
|
Markserv path: /home/jaandrle/Vzdálené/GitHub/deka-dom-el
|
||||||
|
Markserv livereload: communicating on port: 35729
|
||||||
|
Markserv process: your pid is: 130669
|
||||||
|
Markserv stop: press [Ctrl + C] or type "sudo kill -9 130669"
|
||||||
|
GitHub Contribute on Github - github.com/markserv
|
||||||
|
Markserv upgrade: checking for upgrade...
|
||||||
|
Markserv upgrade: no upgrade available
|
||||||
|
Markserv dir: /home/jaandrle/Vzdálené/GitHub/deka-dom-el/
|
||||||
|
Markserv markdown: /home/jaandrle/Vzdálené/GitHub/deka-dom-el/README.md
|
||||||
|
Markserv markdown: /home/jaandrle/Vzdálené/GitHub/deka-dom-el/README.md
|
||||||
|
Markserv markdown: /home/jaandrle/Vzdálené/GitHub/deka-dom-el/README.md
|
||||||
|
Markserv markdown: /home/jaandrle/Vzdálené/GitHub/deka-dom-el/README.md
|
||||||
|
Markserv markdown: /home/jaandrle/Vzdálené/GitHub/deka-dom-el/README.md
|
||||||
|
Markserv markdown: /home/jaandrle/Vzdálené/GitHub/deka-dom-el/README.md
|
||||||
|
Markserv markdown: /home/jaandrle/Vzdálené/GitHub/deka-dom-el/README.md
|
||||||
|
Markserv markdown: /home/jaandrle/Vzdálené/GitHub/deka-dom-el/README.md
|
||||||
|
Markserv markdown: /home/jaandrle/Vzdálené/GitHub/deka-dom-el/README.md
|
||||||
|
Could not find the language '~', did you forget to load/include a language module?
|
||||||
|
Markserv markdown: /home/jaandrle/Vzdálené/GitHub/deka-dom-el/README.md
|
||||||
|
Markserv markdown: /home/jaandrle/Vzdálené/GitHub/deka-dom-el/README.md
|
||||||
|
Markserv markdown: /home/jaandrle/Vzdálené/GitHub/deka-dom-el/README.md
|
||||||
|
Markserv markdown: /home/jaandrle/Vzdálené/GitHub/deka-dom-el/README.md
|
||||||
|
Markserv markdown: /home/jaandrle/Vzdálené/GitHub/deka-dom-el/README.md
|
||||||
|
Markserv markdown: /home/jaandrle/Vzdálené/GitHub/deka-dom-el/README.md
|
Reference in New Issue
Block a user