Skip to content

Commit 01d0b08

Browse files
JohnMcLearclaude
andauthored
docs: migrate useful wiki content into the manual (#7990) (#7994)
* docs: migrate useful wiki content into the VitePress manual (#7990) The GitHub wiki is being retired; documentation should ship with the software. This migrates the still-accurate, non-duplicate wiki pages into the published VitePress site (doc/**/*.md + the sidebar in doc/.vitepress/config.mts) so they are versioned, searchable and portable: - deployment.md: reverse-proxy configs (Nginx/Apache/Caddy/Traefik/ HAProxy) with the WebSocket-upgrade rules, subdirectory hosting via X-Proxy-Path, native HTTPS via the ssl block, a systemd unit, and the Istio manifest (with the Redis-adapter multi-replica caveat). - accessibility.md: editor keyboard shortcuts (verified against ace2_inner.ts / broadcast_slider.ts / pad_editbar.ts), toolbar navigation, NVDA notes. - faq.md: install methods, URL-path reference, listing/deleting pads (API-first), backup/restore, and history pruning. - development.md: source-tree tour, the pad<->format conversion pipeline, the internal DB API, and the Fontello toolbar-icon workflow. - database.md: the key/value schema plus connecting MySQL/PostgreSQL/Redis backends and a pgloader MySQL->PostgreSQL migration (database docs were previously absent from the VitePress site). Every page was checked against the current source before inclusion: corrected the apt instructions to the live signed repo (stable/main, signed-by key), dropped the unpublished snap, fixed the Redis dbSettings (flat host/port/password or url, not the obsolete client_options), dropped charset from the PostgreSQL example, and removed a phantom getEtherpad API reference. The VitePress site builds cleanly (pnpm run docs:build) with the dead-link checker enabled. Closes #7990 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: add verified hands-on changeset/atext walkthrough (#7990) Migrate the practical Changeset-library tutorial from the wiki into changeset_library.md, rewritten against the current API: unpack(), deserializeOps() (replacing the deprecated opIterator) and new AttributePool() (replacing the removed AttributePoolFactory). Every example output was produced by running the code against the current Changeset.ts / AttributePool.ts, not copied from the wiki. Also fixes a stale ether/etherpad-lite source link. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 41dc87e commit 01d0b08

7 files changed

Lines changed: 1193 additions & 1 deletion

File tree

doc/.vitepress/config.mts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,18 @@ export default defineConfig({
2727
items: [
2828
{ text: 'Docker', link: '/docker.md' },
2929
{ text: 'Configuration', link: '/configuration.md' },
30+
{ text: 'Deployment', link: '/deployment.md' },
31+
{ text: 'Database', link: '/database.md' },
3032
{ text: 'Localization', link: '/localization.md' },
3133
{ text: 'Cookies', link: '/cookies.md' },
3234
{ text: 'Plugins', link: '/plugins.md' },
3335
{ text: 'Stats', link: '/stats.md' },
3436
{text: 'Skins', link: '/skins.md' },
37+
{ text: 'Accessibility', link: '/accessibility.md' },
3538
{text: 'Demo', link: '/demo.md' },
3639
{text: 'CLI', link: '/cli.md'},
40+
{ text: 'Development', link: '/development.md' },
41+
{ text: 'FAQ', link: '/faq.md' },
3742
]
3843
},
3944
{

doc/accessibility.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Accessibility
2+
3+
Etherpad aims to be usable by everyone, including people who rely on a
4+
keyboard, a screen reader, or other assistive technology. The editor follows
5+
common conventions so that selecting, formatting, and navigating text works the
6+
way you would expect in other applications, and the toolbar can be reached and
7+
operated without a mouse.
8+
9+
If you find a feature that is not accessible, please let us know by opening an
10+
issue so it can be improved.
11+
12+
## Keyboard shortcuts
13+
14+
The following shortcuts are built into the editor. On macOS use the Command
15+
(`Cmd`) key wherever `Ctrl` is listed.
16+
17+
::: tip
18+
Most shortcuts can be individually enabled or disabled through the
19+
`padShortcutEnabled` settings, so a deployment may have customised which of
20+
these are active.
21+
:::
22+
23+
### Editor
24+
25+
| Action | Shortcut |
26+
| --- | --- |
27+
| Bold | `Ctrl` + `B` |
28+
| Italic | `Ctrl` + `I` |
29+
| Underline | `Ctrl` + `U` |
30+
| Strikethrough | `Ctrl` + `5` |
31+
| Ordered (numbered) list | `Ctrl` + `Shift` + `N` or `Ctrl` + `Shift` + `1` |
32+
| Unordered (bulleted) list | `Ctrl` + `Shift` + `L` |
33+
| Indent line or selection | `Tab` |
34+
| Outdent line or selection | `Shift` + `Tab` |
35+
| Undo | `Ctrl` + `Z` |
36+
| Redo | `Ctrl` + `Y` or `Ctrl` + `Shift` + `Z` |
37+
| Save a named revision | `Ctrl` + `S` |
38+
| Duplicate the current line(s) | `Ctrl` + `Shift` + `D` |
39+
| Delete the current line(s) | `Ctrl` + `Shift` + `K` |
40+
| Clear authorship colors on the pad or selection | `Ctrl` + `Shift` + `C` |
41+
| Show the authors of the current line | `Ctrl` + `Shift` + `2` |
42+
| Focus the toolbar (see below) | `Alt` + `F9` |
43+
| Focus the chat input | `Alt` + `C` |
44+
45+
Text selection, cut (`Ctrl` + `X`), copy (`Ctrl` + `C`), paste
46+
(`Ctrl` + `V`), and the arrow keys behave as they do in any standard text
47+
editor.
48+
49+
### Timeslider
50+
51+
The timeslider (revision history) provides its own shortcuts:
52+
53+
| Action | Shortcut |
54+
| --- | --- |
55+
| Play / pause history playback | `Space` |
56+
| Step back one revision | `Left Arrow` |
57+
| Step forward one revision | `Right Arrow` |
58+
| Jump back to the previous starred revision | `Shift` + `Left Arrow` |
59+
| Jump forward to the next starred revision | `Shift` + `Right Arrow` |
60+
61+
## Toolbar navigation
62+
63+
The toolbar holds the formatting controls (bold, italic, lists, and so on) and
64+
can be reached and operated entirely from the keyboard:
65+
66+
* Press `Alt` + `F9` from the editor to move focus to the first button in the
67+
toolbar.
68+
* Use the `Left Arrow` and `Right Arrow` keys to move between buttons. `Tab`
69+
also moves to the next focusable control.
70+
* Press `Enter` to activate the focused button.
71+
* Press `Alt` + `F9` again, or `Escape`, to return focus to the pad.
72+
73+
Pressing `Escape` while a toolbar dropdown (such as the settings or color
74+
picker) is open closes that dropdown first.
75+
76+
## Screen readers
77+
78+
Etherpad provides as much screen reader support as possible. Support quality
79+
varies between platforms and browsers, so the following combinations are
80+
recommended:
81+
82+
* On Windows, Firefox with [NVDA](https://www.nvaccess.org/) currently gives the
83+
best experience.
84+
85+
To reduce verbose feedback while typing collaboratively in NVDA, open the
86+
keyboard settings (`NVDA` + `Ctrl` + `K`) and turn off **Speak typed characters**
87+
and **Speak typed words**.
88+
89+
Support in other screen readers and browsers (for example Orca on Linux, or
90+
Chrome) is more limited. Contributions to improve coverage on these platforms
91+
are very welcome.

doc/api/changeset_library.md

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Changeset Library
22

33
The [changeset
4-
library](https://github.com/ether/etherpad-lite/blob/develop/src/static/js/Changeset.ts)
4+
library](https://github.com/ether/etherpad/blob/develop/src/static/js/Changeset.ts)
55
provides tools to create, read, and apply changesets.
66

77
## Changeset
@@ -21,6 +21,42 @@ A transmitted changeset looks like this:
2121
'Z:z>1|2=m=b*0|1+1$\n'
2222
```
2323

24+
### Reading a changeset
25+
26+
`unpack()` splits a changeset string into its parts:
27+
28+
```javascript
29+
const unpacked = Changeset.unpack('Z:z>1|2=m=b*0|1+1$\n');
30+
// { oldLen: 35, newLen: 36, ops: '|2=m=b*0|1+1', charBank: '\n' }
31+
```
32+
33+
`oldLen` is the document length before the change and `newLen` the length after.
34+
`ops` is the list of operations, and `charBank` holds the characters inserted by
35+
those operations.
36+
37+
Iterate the operations with `deserializeOps()`, which yields one `Op` at a time:
38+
39+
```javascript
40+
for (const op of Changeset.deserializeOps(unpacked.ops)) {
41+
console.log(op);
42+
}
43+
// Op { opcode: '=', chars: 22, lines: 2, attribs: '' }
44+
// Op { opcode: '=', chars: 11, lines: 0, attribs: '' }
45+
// Op { opcode: '+', chars: 1, lines: 1, attribs: '*0' }
46+
```
47+
48+
There are three kinds of operation, each applied starting from the current
49+
position in the text:
50+
51+
- `=` keeps text (it may still change the text's attributes, e.g. make it bold).
52+
- `-` removes text.
53+
- `+` inserts text (taking the characters from the changeset's `charBank`).
54+
55+
`opcode` is the operation type; `chars` and `lines` are how much text it covers;
56+
and `attribs` are the attributes applied, written as `*` references into the
57+
pad's attribute pool. In the example above the final op inserts one character
58+
(the newline from `charBank`) carrying attribute `*0`.
59+
2460
## Attribute Pool
2561

2662
```javascript
@@ -36,6 +72,59 @@ are used many times.
3672
There is one attribute pool per pad, and it includes every current and
3773
historical attribute used in the pad.
3874

75+
A pool can be serialized to and from a plain object with `toJsonable()` and
76+
`fromJsonable()`:
77+
78+
```javascript
79+
const pool = new AttributePool();
80+
pool.fromJsonable({
81+
numToAttrib: {
82+
0: ['author', 'a.kVnWeomPADAT2pn9'],
83+
1: ['bold', 'true'],
84+
2: ['italic', 'true'],
85+
},
86+
nextNum: 3,
87+
});
88+
89+
pool.getAttrib(1); // [ 'bold', 'true' ]
90+
pool.getAttribKey(1); // 'bold'
91+
pool.getAttribValue(1); // 'true'
92+
```
93+
94+
Each attribute is a `[key, value]` pair — `['bold', 'true']`, or
95+
`['author', '<authorId>']`. A character can carry several attributes (bold *and*
96+
italic), but only one value per key (so it cannot belong to two authors).
97+
98+
## Attributed text (atext)
99+
100+
A pad's content is stored as *attributed text* (`atext`): the plain text plus an
101+
attribute string describing which attributes apply to each span.
102+
103+
```javascript
104+
const atext = {
105+
text: 'bold text\nitalic text\nnormal text\n\n',
106+
attribs: '*0*1+9*0|1+1*0*1*2+b|1+1*0+b|2+2',
107+
};
108+
```
109+
110+
The attribute string is a sequence of `+` operations — the same encoding used by
111+
changesets — which you can read with `deserializeOps()`:
112+
113+
```javascript
114+
for (const op of Changeset.deserializeOps(atext.attribs)) {
115+
console.log(op);
116+
}
117+
// Op { opcode: '+', chars: 9, lines: 0, attribs: '*0*1' }
118+
// Op { opcode: '+', chars: 1, lines: 1, attribs: '*0' }
119+
// Op { opcode: '+', chars: 11, lines: 0, attribs: '*0*1*2' }
120+
// Op { opcode: '+', chars: 1, lines: 1, attribs: '' }
121+
// Op { opcode: '+', chars: 11, lines: 0, attribs: '*0' }
122+
// Op { opcode: '+', chars: 2, lines: 2, attribs: '' }
123+
```
124+
125+
Read against the pool above, the first nine characters (`bold text`) carry
126+
attributes `*0*1` (author + bold), the following newline carries `*0`, and so on.
127+
39128
## Further Reading
40129

41130
Detailed information about the changesets & Easysync protocol:

0 commit comments

Comments
 (0)