mirror of
https://github.com/larvit/adf-codec.git
synced 2026-11-12 11:48:29 +01:00
Answer prose round 1: 0 🔴, 10 🟡 (0 misread); say the HTML is read as a browser spells it, wherever it said exactly
This commit is contained in:
+4
-4
@@ -15,10 +15,10 @@
|
||||
content, links included. Every URL is written as the ADF holds it,
|
||||
`javascript:` included: sanitize HTML from an author you do not trust before showing it.
|
||||
- `htmlToAdf` reads `adfToHtml`'s HTML back to the document it came from, a carry element from its
|
||||
`data-adf`, also as a browser's `innerHTML` writes it (a raw `"` in text, ` `, a raw `<` or
|
||||
`>` in an attribute value) and as a form post sends it (`\r\n` for each line feed). It refuses
|
||||
any other HTML, including an edit to what a carry element shows, with the codes README §The calls
|
||||
lists.
|
||||
`data-adf`. It reads that HTML as a browser's `innerHTML` writes it too (a raw `"` in text,
|
||||
` `, a raw `<` or `>` in an attribute value) and as a form post sends it (`\r\n` for each
|
||||
line feed). It refuses any other HTML, including an edit to what a carry element shows, with the
|
||||
codes README §The calls lists.
|
||||
- **Breaking:** `losslessMarkdownToAdf` gives a `date`, `emoji`, `inlineCard`, `mention`, `status`
|
||||
or `mediaInline` only the marks Atlassian's schema lets it hold: `**!adf:mention[@A]{id=…}**` now
|
||||
reads as a plain mention. A link or directive mark around only nodes that cannot take it is
|
||||
|
||||
@@ -324,7 +324,7 @@ Each call's name says which format it reads or writes:
|
||||
| `adfToLosslessMarkdown` | writes the lossless flavour: CommonMark plus GFM's pipe tables and `~~`, with `!adf:` directives and `adf:` fences for everything else | `engine-limit`, `not-an-adf-document`, `unsupported-document-version`, `unsupported-nesting-depth`, `unsupported-node-shape` |
|
||||
| `adfToPortableMarkdown` | writes markdown GitHub, GitLab and Obsidian render; drops what they cannot show, and writes no directive | `engine-limit`, `not-an-adf-document`, `unsupported-document-version`, `unsupported-nesting-depth`, `unsupported-node-shape` |
|
||||
| `commonMarkToAdf` | reads strict CommonMark as its spec says: a directive, a pipe table, `~~`, `==` and an `adf:` fence read as text and code | `engine-limit`, `not-a-string`, `unmappable-html`, `unsupported-nesting-depth`, `unsupported-node-shape` |
|
||||
| `htmlToAdf` | reads the HTML `adfToHtml` writes, a carry element from its `data-adf`; refuses any other HTML, an edit to what a carry element shows included | `engine-limit`, `not-a-string`, `unmappable-html`, `unsupported-nesting-depth`, `unsupported-node-shape` |
|
||||
| `htmlToAdf` | reads the HTML `adfToHtml` writes, also as a browser's `innerHTML` or a form post spells it, a carry element from its `data-adf`; refuses any other HTML, an edit to what a carry element shows included | `engine-limit`, `not-a-string`, `unmappable-html`, `unsupported-nesting-depth`, `unsupported-node-shape` |
|
||||
| `losslessMarkdownToAdf` | reads the lossless flavour, markdown `adfToLosslessMarkdown` wrote, edited or not | every code in [The errors](#the-errors) except `not-an-adf-document` and `unsupported-document-version` |
|
||||
| `portableMarkdownToAdf` | reads CommonMark, GFM's pipe tables and `~~`, alerts and task markers, Obsidian's callouts and `==`; a directive and an `adf:` fence read as text and code | `engine-limit`, `malformed-pipe-table`, `not-a-string`, `unmappable-html`, `unsupported-nesting-depth`, `unsupported-node-shape` |
|
||||
|
||||
@@ -538,10 +538,9 @@ content. No stylesheet ships. The complete dialect:
|
||||
target shows that link, then `(image)` linking to the image. A node it cannot show leaves a note
|
||||
instead, such as `<em>(image)</em>`; a link marking the node goes around the note.
|
||||
|
||||
`htmlToAdf` reads exactly that HTML back. It reads a carry element's node from its `data-adf`, and
|
||||
what the element shows must be what `adfToHtml` shows for that node: an edit there would be lost, so
|
||||
it is refused. It also reads the HTML as a browser's `innerHTML` writes it back and as a form post
|
||||
sends it: a raw `"` in text, ` ` for a no-break space, a raw `<` or `>` in an attribute value,
|
||||
`htmlToAdf` reads that HTML back. It reads a carry element's node from its `data-adf`, and what the
|
||||
element shows must be what `adfToHtml` shows for that node: an edit there would be lost, so it is
|
||||
refused. It reads the HTML as a browser's `innerHTML` writes it too, and as a form post sends it: a raw `"` in text, ` ` for a no-break space, a raw `<` or `>` in an attribute value,
|
||||
and `\r\n` for a line feed. Other HTML is refused as `unmappable-html`: another element, attribute or
|
||||
escape, such as `<b>`, `<br/>` or `'`, a lone `\r`, and HTML missing its final line feed.
|
||||
A few causes, such as a `data-*` attribute its element does not take, are `unsupported-node-shape`
|
||||
@@ -595,7 +594,7 @@ Which reader raises which code: [The calls](#the-calls). Codes every direction r
|
||||
| `malformed-pipe-table` | a pipe row that is no pipe table — a missing `---` delimiter row, or a delimiter or body row whose cell count differs from the header's; in `losslessMarkdownToAdf` also an alignment colon, and a header or delimiter row not opening with a pipe | add a `---` row under the header and give every row the header's cell count; for `losslessMarkdownToAdf`, also open every row with a pipe and drop the colons. To keep the lines literal text, escape the leading pipe of every one — escaping a single row leaves the next to open a fresh table and fail the same way — or, for a table without leading pipes, write one `\|` of its delimiter row as `\\|` |
|
||||
| `not-a-string` | the value handed in is not a string, such as `null`, a number or a `String` object | pass the input as a string, `String(value)` for a `String` object; the message names the value's type |
|
||||
| `unknown-directive-name` | a directive whose name is no node or mark this version spells | check the name in [`spec/flavour.md`](https://github.com/larvit/adf-codec/blob/main/spec/flavour.md), or escape the prefix as `\!adf:`; the spelling itself is well formed, so a later minor may give the name meaning |
|
||||
| `unmappable-html` | the markdown holds raw HTML, a comment and a processing instruction among them; the HTML handed to `htmlToAdf` holds HTML `adfToHtml` does not write, such as an edit to what a carry element shows, unless a code under [Either direction](#either-direction) names the cause | remove the construct, or write what it holds as markdown; for `htmlToAdf`, write the HTML as [`spec/html.md`](https://github.com/larvit/adf-codec/blob/main/spec/html.md) spells it |
|
||||
| `unmappable-html` | the markdown holds raw HTML, a comment and a processing instruction among them; the HTML handed to `htmlToAdf` holds HTML `adfToHtml` does not write, in a browser's spelling or its own, such as an edit to what a carry element shows, unless a code under [Either direction](#either-direction) names the cause | remove the construct, or write what it holds as markdown; for `htmlToAdf`, write the HTML as [`spec/html.md`](https://github.com/larvit/adf-codec/blob/main/spec/html.md) spells it |
|
||||
|
||||
### Emitting
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ try {
|
||||
const { adfToHtml, adfToLosslessMarkdown, htmlToAdf, isAdfDocument, losslessMarkdownToAdf } = await import('/dist/index.js')
|
||||
// WebDriver's JSON reads -0 back as 0, so a document crosses as JSON text with -0 tagged; run.js revives it.
|
||||
const spelled = (result) => (result.ok ? { ok: true, value: JSON.stringify(result.value, (_, value) => (Object.is(value, -0) ? '\u0000-0' : value)) } : result)
|
||||
// The page's own innerHTML is what a viewer/editor app posts back, so htmlToAdf reads what the browser writes.
|
||||
// A viewer/editor app posts the page's innerHTML back, so htmlToAdf must read what the browser writes.
|
||||
const throughInnerHtml = (adf) => {
|
||||
const html = adfToHtml(adf)
|
||||
if (!html.ok) return { parsed: html }
|
||||
|
||||
@@ -70,7 +70,7 @@ async function whenDriverAnswers() {
|
||||
}
|
||||
}
|
||||
|
||||
// Text the browser's innerHTML spells other than adfToHtml does (WHATWG HTML §13.3): a raw ", , and in an attribute < and > escaped or not by version.
|
||||
// Documents holding what a browser's innerHTML spells other than adfToHtml does (WHATWG HTML §13.3): a raw ", , and in an attribute value < and > escaped or not, by version.
|
||||
const text = (value, ...marks) => (marks.length === 0 ? { text: value, type: 'text' } : { marks, text: value, type: 'text' })
|
||||
const browserDocuments = [
|
||||
{
|
||||
@@ -175,5 +175,5 @@ for (const [index, { name }] of corpus.errors.entries()) {
|
||||
}
|
||||
|
||||
console.log(
|
||||
`Firefox ${session.capabilities.browserVersion} converted ${corpus.roundTrip.length} round-trip, ${corpus.normalization.length} normalization and ${corpus.errors.length} error fixtures, ${corpus.realPayloads.length} real payloads and ${corpus.browserDocuments.length} documents through innerHTML`,
|
||||
`Firefox ${session.capabilities.browserVersion} converted ${corpus.roundTrip.length} round-trip, ${corpus.normalization.length} normalization and ${corpus.errors.length} error fixtures, ${corpus.realPayloads.length} real payloads, and read the real payloads and ${corpus.browserDocuments.length} hand-built document(s) back through innerHTML`,
|
||||
)
|
||||
|
||||
+11
-10
@@ -450,13 +450,13 @@ browser and post the page back.
|
||||
|
||||
A browser does not write the dialect back as `adfToHtml` wrote it. `htmlToAdf` reads both spellings:
|
||||
a page's `innerHTML`, as WHATWG HTML §Serializing HTML fragments spells it, and a form post, which
|
||||
ends each line in `\r\n`. So text's raw `"` reads as `"` does, ` ` as a no-break space and
|
||||
`\r\n` as a line feed, in what a carry element shows too. An attribute value's raw `<` and `>` read as
|
||||
`<` and `>` do: the serialization algorithm escapes them now, and a browser from before that
|
||||
writes them raw. These are every difference §Serializing HTML fragments leaves between a browser's
|
||||
text and `adfToHtml`'s, checked against Firefox's own `innerHTML` in the browser leg. Every element
|
||||
the dialect writes reads this way, those later items add included. HTML no browser writes from the
|
||||
dialect stays refused, a lone `\r` among it. A refusal's position counts the HTML as handed in.
|
||||
ends each line in `\r\n`. In text, a raw `"` reads as `"` does; in an attribute value, a raw `<`
|
||||
or `>` reads as `<` or `>` (a browser from before the algorithm escaped them writes them raw);
|
||||
in both, ` ` reads as a no-break space; and `\r\n` reads as a line feed. All of it holds in what
|
||||
a carry element shows too. These are every difference the algorithm leaves between a browser's HTML
|
||||
and `adfToHtml`'s, checked against Firefox's own `innerHTML` in the browser leg, and they hold for
|
||||
every element the dialect writes, later ones included. Other HTML stays refused, a lone `\r` among
|
||||
it. A refusal's position counts the HTML as handed in.
|
||||
|
||||
## No runtime dependencies
|
||||
|
||||
@@ -744,10 +744,11 @@ resolver maps them, under `NodeNext` alone; a `.d.ts` reader that is not `tsc` s
|
||||
SpiderMonkey.
|
||||
|
||||
A headless Firefox loads `dist/index.js` over HTTP and converts the round-trip, normalization and
|
||||
error fixtures and the real payloads, and reads the HTML its own `innerHTML` writes back from
|
||||
`adfToHtml`'s — the `commonmark-spec` sort is the Node suite's to check —
|
||||
error fixtures and the real payloads — the `commonmark-spec` sort is the Node suite's to check —
|
||||
which is the browser half of §Any ES2022 engine and the only SpiderMonkey there is — the gate's
|
||||
other engines are two V8s and a JavaScriptCore that is not Safari's. A WebDriver session is what
|
||||
other engines are two V8s and a JavaScriptCore that is not Safari's. It also sets `adfToHtml`'s HTML
|
||||
into the page and reads the page's own `innerHTML` back through `htmlToAdf` (§`htmlToAdf` also
|
||||
reads the dialect as a browser serializes it). A WebDriver session is what
|
||||
carries a verdict back out, the driver and the page's server sharing one network namespace so each
|
||||
is the other's `127.0.0.1`; `--headless --screenshot` has no such channel, and loading
|
||||
`dist/index.js` in a globals-stripped realm buys one by not running a browser. The leg re-checks
|
||||
|
||||
+8
-7
@@ -119,20 +119,21 @@ later release writes it as its own element.
|
||||
|
||||
## Reading
|
||||
|
||||
`htmlToAdf` reads exactly the HTML above, so `htmlToAdf(adfToHtml(doc))` deep-equals `doc`. It also
|
||||
reads the HTML above as a browser serializes it (WHATWG HTML §13.3) and as a form post sends it,
|
||||
anywhere the HTML above has the character, a carry element's `data-adf` and what it shows included:
|
||||
`htmlToAdf` reads the HTML above, so `htmlToAdf(adfToHtml(doc))` deep-equals `doc`. Wherever the HTML
|
||||
above holds a spelling in the table's left column, `htmlToAdf` also reads the right one, as a browser
|
||||
serializes HTML (WHATWG HTML §13.3) or a form post sends it, in a carry element's `data-adf` and in
|
||||
what it shows too:
|
||||
|
||||
| The HTML above writes | Also read |
|
||||
| --- | --- |
|
||||
| `"` in text | a raw `"` |
|
||||
| a no-break space | ` ` |
|
||||
| `<` and `>` in an attribute value | a raw `<` and `>`, as older browsers write them |
|
||||
| a line feed | `\r\n`; a refusal's position counts the HTML as handed in |
|
||||
| a line feed | `\r\n` |
|
||||
|
||||
It reads a carry element's node from its `data-adf`, and what the element shows, through its
|
||||
closing tag, must be what `adfToHtml` shows for that node: an edit there would be lost, so it is
|
||||
`unmappable-html`.
|
||||
A refusal's position counts the HTML as handed in. `htmlToAdf` reads a carry element's node from its
|
||||
`data-adf`, and what the element shows, through its closing tag, must be what `adfToHtml` shows for
|
||||
that node in either spelling: an edit there would be lost, so it is `unmappable-html`.
|
||||
|
||||
- Any other HTML is `unmappable-html`: another element, attribute or escape, attributes in another
|
||||
order, a block on the line of another, a carriage return not followed by a line feed, or
|
||||
|
||||
Reference in New Issue
Block a user