mirror of
https://github.com/JonnyBro/JaBa.git
synced 2024-11-25 14:44:58 +05:00
203 lines
7.7 KiB
Markdown
203 lines
7.7 KiB
Markdown
|
## Attributes And Helpers
|
||
|
|
||
|
### Element attributes
|
||
|
|
||
|
These are the published attributes that can be set on any instance of `<zero-md>`:
|
||
|
|
||
|
| Attribute | Type | Description |
|
||
|
|-------------------|------------|-------------|
|
||
|
| src | String | URL location to `GET` the markdown text file. If unset, reads markdown from inline `<script type="text/markdown">` instead. |
|
||
|
| manual-render | Boolean | If set, disables auto-rendering of this instance. Call the `render()` function on that instance manually to begin. |
|
||
|
| no-shadow | Boolean | If set, renders and stamps this instance into **light dom** instead. Please know what you are doing. |
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
1. Standard [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) rules apply; the `src` file -
|
||
|
if fetched from another origin - should be served with the corresponding `Access-Control-Allow-Origin` headers.
|
||
|
|
||
|
2. `no-shadow` is immutable; it must be declared on element creation time and should not be dynamically changed.
|
||
|
|
||
|
### Style template attributes
|
||
|
|
||
|
Style templates are `<template>` tags containing **styles** that are direct children of the its `<zero-md>` element,
|
||
|
and apply only to that parent instance.
|
||
|
|
||
|
The following attributes may be declared on a style template:
|
||
|
|
||
|
| Attribute | Type | Description |
|
||
|
|-------------------|------------|-------------|
|
||
|
| data-merge | String | Accepts either `append` or `prepend` and works as its name suggests. If unset, the style template **overrides** the default template. |
|
||
|
|
||
|
Style templates accept `<link rel="stylesheet">` and `<style>` tags as their direct children. For example:
|
||
|
|
||
|
```html
|
||
|
<zero-md>
|
||
|
<!-- Styles declared within will be appended AFTER the default template -->
|
||
|
<template data-merge="append">
|
||
|
<!-- Use `link` tags to load external stylesheets -->
|
||
|
<link rel="stylesheet" href="custom.css">
|
||
|
<!-- Use `style` tags to write CSS directly -->
|
||
|
<style>
|
||
|
h1 {
|
||
|
color: red;
|
||
|
}
|
||
|
</style>
|
||
|
</template>
|
||
|
</zero-md>
|
||
|
```
|
||
|
|
||
|
### Inline markdown attributes
|
||
|
|
||
|
To write markdown inline, wrap your markdown with a `<script type="text/markdown">` tag and place it as a direct
|
||
|
child of `<zero-md>`. Note that inline markdown works like a **fall-back**; so the element `src` should **not**
|
||
|
be set, or should resolve to be falsy.
|
||
|
|
||
|
The following attributes may be declared on the `<script>` tag:
|
||
|
|
||
|
| Attribute | Type | Description |
|
||
|
|-------------------|------------|-------------|
|
||
|
| data-dedent | Boolean | If set, applies a `dedent` function onto the text content that *tries* to remove leading whitespace (indentation) that will otherwise be incorrectly interpreted as code blocks. |
|
||
|
|
||
|
For example:
|
||
|
|
||
|
```html
|
||
|
<zero-md>
|
||
|
<!-- Set `data-dedent` to remove indentation -->
|
||
|
<script type="text/markdown" data-dedent>
|
||
|
# Opt in to apply dedent function
|
||
|
If **indentation** is important to you.
|
||
|
</script>
|
||
|
</zero-md>
|
||
|
```
|
||
|
|
||
|
### render([options])
|
||
|
|
||
|
The `render()` function renders the HTML, stamps it into DOM and returns a `Promise` that resolves when done.
|
||
|
It accepts an optional *options* `object` which may contain the following:
|
||
|
|
||
|
| Property | Type | Description |
|
||
|
|-------------------|------------|-------------|
|
||
|
| classes | Array | A class name string or array of class names to apply onto the rendered markdown container node. Useful for activating some Prism plugins. |
|
||
|
| ...markedOpts | ...Object | Any of these [Marked options](https://marked.js.org/using_advanced#options) can be passed in and will apply during markdown transformation. |
|
||
|
|
||
|
For example:
|
||
|
|
||
|
```js
|
||
|
const app = document.querySelector('zero-md')
|
||
|
const run = async () => {
|
||
|
app.src = 'dynamic.md'
|
||
|
await app.render({
|
||
|
// The class `line-numbers` will be added to the markdown-body container
|
||
|
classes: 'line-numbers',
|
||
|
// These are Marked options
|
||
|
gfm: false,
|
||
|
mangle: false
|
||
|
})
|
||
|
alert('Render complete!')
|
||
|
}
|
||
|
run()
|
||
|
```
|
||
|
|
||
|
### Helpers
|
||
|
|
||
|
Internally, the `render()` function may look something like this:
|
||
|
|
||
|
```js
|
||
|
async function render (opts = {}) {
|
||
|
// Ensure everything is initialised
|
||
|
await this.waitForReady()
|
||
|
const stamped = {}
|
||
|
// Start generating the CSS and Markdown HTML strings
|
||
|
const pending = this.buildMd(opts)
|
||
|
const css = this.buildStyles()
|
||
|
// Stamp styles if none exists; replace if there're changes
|
||
|
if (css !== this.cache.styles) {
|
||
|
this.cache.styles = css
|
||
|
// Ensure that external stylesheets are loaded, then queue next repaint to prevent FOUC
|
||
|
await this.stampStyles(css)
|
||
|
stamped.styles = true
|
||
|
await this.tick()
|
||
|
}
|
||
|
// Then stamp body if none exists; replace if there're changes
|
||
|
const md = await pending
|
||
|
if (md !== this.cache.body) {
|
||
|
this.cache.body = md
|
||
|
const node = this.stampBody(md)
|
||
|
stamped.body = true
|
||
|
// Begin asynchronous Prism highlight
|
||
|
await this.highlight(node)
|
||
|
}
|
||
|
// Finally, fire the rendered event
|
||
|
this.fire('zero-md-rendered', { stamped })
|
||
|
}
|
||
|
```
|
||
|
|
||
|
The helper functions shown above are public; you can re-create your own `render()` function using a mix
|
||
|
of these helpers to fit your specific use-case. Some helpers include:
|
||
|
|
||
|
| Method | Description |
|
||
|
|----------------------|--------------------------|
|
||
|
| waitForReady() | Returns a `Promise` that resolves when element is connected, and both Marked and Prism are loaded. |
|
||
|
| makeNode(html) | Converts a HTML string into a DOM node and returns it. |
|
||
|
| buildStyles() | Constructs the style HTML string and returns it. |
|
||
|
| buildMd({opts}) | Download the `src` file, if specified, transforms the markdown (with optional opts), and returns a `Promise` that resolves into a HTML string. |
|
||
|
| stampStyles(html) | Insert or replace a styles HTML string into DOM and returns a `Promise` that resolves eagerly when all `<link>` stylesheets are downloaded. |
|
||
|
| stampBody(html) | Insert or replace a markdown HTML string into DOM and returns the new node. |
|
||
|
| highlight(container) | Runs `Prism` highlight on a container node asynchronously (using Web Workers, or falls back to synchronous if it throws) and returns a `Promise` when done. |
|
||
|
| tick() | Wait for next repaint. |
|
||
|
| fire(name, {opts}) | Dispatches a new custom event. |
|
||
|
|
||
|
### Events
|
||
|
|
||
|
The following convenience events are dispatched:
|
||
|
|
||
|
| Event Name | Description |
|
||
|
|--------------------|--------------------------|
|
||
|
| zero-md-ready | Fires after element is connected, and both Marked and Prism are loaded. |
|
||
|
| zero-md-rendered | Fires after markdown is transformed, syntax highlighted, and contents stamped to DOM. |
|
||
|
| zero-md-error | Fires when a download error is encountered in `src` or any `<link rel="stylesheet">` tags. |
|
||
|
|
||
|
#### Rendered event
|
||
|
|
||
|
The `zero-md-rendered` event fires with the following details:
|
||
|
|
||
|
| Detail | Description |
|
||
|
|--------------------|--------------------------|
|
||
|
| node | The `zero-md` element that dispatched the event. |
|
||
|
| stamped.styles | `true` when styles are stamped into DOM. |
|
||
|
| stamped.body | `true` when markdown body is stamped into DOM. |
|
||
|
|
||
|
#### Error-handling
|
||
|
|
||
|
To catch `src` errors:
|
||
|
|
||
|
```html
|
||
|
<zero-md id="app" src="not-found.md"></zero-md>
|
||
|
<script>
|
||
|
app.addEventListener('zero-md-error', ev => {
|
||
|
// `src` download errors will return a response code
|
||
|
if (ev.detail.status) {
|
||
|
console.log('Error encountered while loading src', ev.detail.status)
|
||
|
}
|
||
|
})
|
||
|
</script>
|
||
|
```
|
||
|
|
||
|
To catch `<link rel="stylesheet">` errors:
|
||
|
|
||
|
```html
|
||
|
<zero-md id="app" src="foo.md">
|
||
|
<template>
|
||
|
<link rel="stylesheet" href="not-found.css">
|
||
|
</template>
|
||
|
</zero-md>
|
||
|
<script>
|
||
|
app.addEventListener('zero-md-error', ev => {
|
||
|
// External stylesheet download errors will NOT return status
|
||
|
if (!ev.detail.status) {
|
||
|
console.log('Error encountered while loading an external stylesheet')
|
||
|
}
|
||
|
})
|
||
|
</script>
|
||
|
```
|