Skip to content

Commit

Permalink
Update documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
tbranyen committed Mar 22, 2020
1 parent 46c475a commit 19ebb1a
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 52 deletions.
6 changes: 5 additions & 1 deletion docs/api.html
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,10 @@ <h2 id="a-hrefuseusea-middlewarefunction-or-middlewareobject"><a href="#use">use
<p>A function is useful when you want to follow the transactions (which are
started and run a series of tasks), and passing an object can be cleaner when
you want to modify the Virtual Tree or automatically add properties.</p>
<p>
<a href="/middleware.html#writing-middleware" title="null"><strong>Refer to the Middleware documentation for more in-depth
information.</strong></a>
</p>
<h3 id="arguments-3">Arguments</h3>
<table>
<thead>
Expand All @@ -325,7 +329,7 @@ <h3 id="arguments-3">Arguments</h3>
</tr>
<tr>
<td><strong>middlewareObject</strong></td>
<td>Use this when you don&#39;t care about the transaction start/stop, and want a cleaner way to monitor the VTree lifecycle. <p><b>- createTreeHook</b></p><p><b>- syncTreeHook</b></p> <p><b>- releaseHook</b></p></td>
<td>Use this when you don&#39;t care about the transaction start/stop, and want a cleaner way to monitor the VTree lifecycle. <p><b>- createTreeHook</b></p><p><b>- syncTreeHook</b></p> <p><b>- releaseHook</b></p><p><b>- subscribe</b></p><p><b>- unsubscribe</b></p></td>
</tr>
</tbody></table>
<h3 id="examples">Examples</h3>
Expand Down
49 changes: 32 additions & 17 deletions docs/middleware.html
Original file line number Diff line number Diff line change
Expand Up @@ -198,31 +198,50 @@ <h1>
<hr></hr>

<section id="content"><h1 id="middleware">Middleware</h1>
<p>This concept allows developers to write plugins that augments diffHTML to do
different things. You can use pre-made middleware or create your own easily.</p>
<p>This concept allows developers to write plugins that hooks into and possibly
augments diffHTML. You can find pre-made middleware or create your own easily
using this guide as a reference.</p>
<p><a name="writing-middleware"></a></p>
<hr></hr>
<h2 id="a-hrefwriting-middlewarewriting-middlewarea"><a href="#writing-middleware">Writing middleware</a></h2>
<p>You would write middleware when you need to extend diffHTML to do things that
that were not originally intended. For instance, you could write logic that
says whenever a specific attribute is present to execute some code on the
element when it enters and leaves the DOM. You could log whenever diffHTML has
a render operation scheduled, monitor transitions, and more.</p>
<p>A basic middleware looks as simple as:</p>
<p>Authoring middleware with diffHTML should not feel daunting; it was designed to
be straightforward for simple things like tracking when renders occur, what the
previous and next (X)HTML trees look like, and what the given set of DOM
updates were for the render.</p>
<p>While simple things are easy to access, the API allows for significantly more
complex operations, such as:</p>
<ul>
<li>Creating new elements</li>
<li>Changing the DOM synchronization logic</li>
<li>Adopt elements/components from other frameworks</li>
<li>XML transformations</li>
<li>React to DevTools changes</li>
</ul>
<p>Lastly, middleware can be loaded with the
<a href="https://diffhtml.org/tools.html#render-to-string" target="_blank" rel="noopener noreferrer" title="null">Render to
String</a>
module in NodeJS. So
if you are extra ambitious you can get your middleware to be fully
cross-platform even during Server-Side-Rendering.</p>
<p>The code for a basic middleware looks as simple as:</p>
<pre><code class="language-js">import { use } from &#39;diffhtml&#39;;

use(() =&gt; {
console.log(&#39;diffHTML render transaction is starting&#39;);
use(transaction =&gt; {
console.log(&#39;Render transaction is starting&#39;);

return () =&gt; {
console.log(&#39;diffHTML render transaction is ending&#39;);
console.log(&#39;Render transaction is ending&#39;);

transaction.onceEnded(() =&gt; {
console.log(&#39;Render transaction has completed&#39;);
});
};
});</code></pre>
<p>There are several core middleware modules already written that you could use as
a reference. A good starting one to look at is the
<a href="/middleware#logger" title="null">Logger</a>

if you&#39;re interested in tracking the render transaction flow.</p>
if you&#39;re interested in logging the render transaction flow.</p>
<p>If you wanted to track when an element enters and leaves the DOM you could use
the
<a href="/transitions.html#available-states" title="null">attached and detached transition
Expand All @@ -231,11 +250,7 @@ <h2 id="a-hrefwriting-middlewarewriting-middlewarea"><a href="#writing-middlewar
transaction when rendering is complete to see what is being attached and
removed.</p>
<pre><code class="language-js">use(() =&gt; ({ patches }) =&gt; {
patches.TREE_OPS.forEach(({ INSERT_BEFORE, REMOVE_CHILD, REPLACE_CHILD }) =&gt; {
if (INSERT_BEFORE) {

}
});
console.log(patches);
});</code></pre>
<p><a name="inline-transitions"></a></p>
<hr></hr>
Expand Down
5 changes: 2 additions & 3 deletions packages/diffhtml-middleware-linter/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ const { NODE_ENV = 'umd' } = process.env;

export const input = entries[NODE_ENV];
export const context = 'this';

export const globals = { diffhtml: 'diff' };
export const external = ['diffhtml'];

export const output = [{
Expand All @@ -27,11 +25,12 @@ export const output = [{
exports: 'default',
name: 'linter',
sourcemap: false,
globals: { diffhtml: 'diff' },
}];

export const plugins = [
NODE_ENV === 'min' && replace({ 'process.env.NODE_ENV': JSON.stringify('production') }),
babel(),
nodeResolve({ jsnext: true }),
nodeResolve({ mainFields: ['module'] }),
NODE_ENV === 'umd' && Visualizer({ filename: './dist/build-size.html' }),
];
12 changes: 8 additions & 4 deletions packages/diffhtml-middleware-logger/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ const log = (message, method, color, date, transaction, completed) => {
}

if (patches) {
console.log('%cpatches %O', 'font-weight: bold; color: #333', patches);
console.log('%cpatches %O', 'font-weight: bold; color: #333', format(patches));
}

// Don't clutter the output if there aren't any promises.
Expand All @@ -180,7 +180,7 @@ const logger = ({ minimize = false }) => function loggerTask(transaction) {

log(
'%cdiffHTML...render transaction started',
minimize ? 'groupCollapsed' : 'group',
'groupCollapsed',
'color: #FF0066',
start,
transaction
Expand Down Expand Up @@ -208,7 +208,7 @@ const logger = ({ minimize = false }) => function loggerTask(transaction) {
* Transaction is effectively done, but we need to listen for it to actually
* be finished.
*/
return () => {
return assign(() => {
// Transaction has fully completed.
transaction.onceEnded(() => {
console.groupEnd();
Expand All @@ -224,7 +224,11 @@ const logger = ({ minimize = false }) => function loggerTask(transaction) {

console.groupEnd();
});
};
}, {
subscribe(args) {
console.log('Logger initialized with', args);
}
});
};

export default (opts = {}) => logger(opts);
5 changes: 2 additions & 3 deletions packages/diffhtml-middleware-logger/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ const { NODE_ENV = 'umd' } = process.env;

export const input = entries[NODE_ENV];
export const context = 'this';

export const globals = { diffhtml: 'diff' };
export const external = ['diffhtml'];

export const output = [{
Expand All @@ -27,11 +25,12 @@ export const output = [{
exports: 'default',
name: 'logger',
sourcemap: false,
globals: { diffhtml: 'diff' },
}];

export const plugins = [
NODE_ENV === 'min' && replace({ 'process.env.NODE_ENV': JSON.stringify('production') }),
babel(),
nodeResolve({ jsnext: true }),
nodeResolve({ mainFields: ['module'] }),
NODE_ENV === 'umd' && Visualizer({ filename: './dist/build-size.html' }),
];
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ export const output = [{
export const plugins = [
NODE_ENV === 'min' && replace({ 'process.env.NODE_ENV': JSON.stringify('production') }),
babel(),
nodeResolve({ jsnext: true }),
nodeResolve({ mainFields: ['module'] }),
NODE_ENV === 'umd' && Visualizer({ filename: './dist/build-size.html' }),
];
5 changes: 4 additions & 1 deletion packages/diffhtml-website/pages/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,15 @@ A function is useful when you want to follow the transactions (which are
started and run a series of tasks), and passing an object can be cleaner when
you want to modify the Virtual Tree or automatically add properties.

[**Refer to the Middleware documentation for more in-depth
information.**](/middleware.html#writing-middleware)

### Arguments

| Name | Description
| ----------- | -----------
| **middlewareFunction** | Use this when you want total control over the task flow. Return inner functions to delve deeper into the flow. Any of the middleware object properties may be attached the function and used together.
| **middlewareObject** | Use this when you don't care about the transaction start/stop, and want a cleaner way to monitor the VTree lifecycle. <p><b>- createTreeHook</b></p><p><b>- syncTreeHook</b></p> <p><b>- releaseHook</b></p>
| **middlewareObject** | Use this when you don't care about the transaction start/stop, and want a cleaner way to monitor the VTree lifecycle. <p><b>- createTreeHook</b></p><p><b>- syncTreeHook</b></p> <p><b>- releaseHook</b></p><p><b>- subscribe</b></p><p><b>- unsubscribe</b></p>

### Examples

Expand Down
48 changes: 31 additions & 17 deletions packages/diffhtml-website/pages/middleware.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,55 @@
# Middleware

This concept allows developers to write plugins that augments diffHTML to do
different things. You can use pre-made middleware or create your own easily.
This concept allows developers to write plugins that hooks into and possibly
augments diffHTML. You can find pre-made middleware or create your own easily
using this guide as a reference.

<a name="writing-middleware"></a>

---

## <a href="#writing-middleware">Writing middleware</a>

You would write middleware when you need to extend diffHTML to do things that
that were not originally intended. For instance, you could write logic that
says whenever a specific attribute is present to execute some code on the
element when it enters and leaves the DOM. You could log whenever diffHTML has
a render operation scheduled, monitor transitions, and more.
Authoring middleware with diffHTML should not feel daunting; it was designed to
be straightforward for simple things like tracking when renders occur, what the
previous and next (X)HTML trees look like, and what the given set of DOM
updates were for the render.

A basic middleware looks as simple as:
While simple things are easy to access, the API allows for significantly more
complex operations, such as:

- Creating new elements
- Changing the DOM synchronization logic
- Adopt elements/components from other frameworks
- XML transformations
- React to DevTools changes

Lastly, middleware can be loaded with the [Render to
String](https://diffhtml.org/tools.html#render-to-string) module in NodeJS. So
if you are extra ambitious you can get your middleware to be fully
cross-platform even during Server-Side-Rendering.

The code for a basic middleware looks as simple as:

``` js
import { use } from 'diffhtml';

use(() => {
console.log('diffHTML render transaction is starting');
use(transaction => {
console.log('Render transaction is starting');

return () => {
console.log('diffHTML render transaction is ending');
console.log('Render transaction is ending');

transaction.onceEnded(() => {
console.log('Render transaction has completed');
});
};
});
```

There are several core middleware modules already written that you could use as
a reference. A good starting one to look at is the [Logger](/middleware#logger)
if you're interested in tracking the render transaction flow.
if you're interested in logging the render transaction flow.

If you wanted to track when an element enters and leaves the DOM you could use
the [attached and detached transition
Expand All @@ -41,11 +59,7 @@ removed.

``` js
use(() => ({ patches }) => {
patches.TREE_OPS.forEach(({ INSERT_BEFORE, REMOVE_CHILD, REPLACE_CHILD }) => {
if (INSERT_BEFORE) {

}
});
console.log(patches);
});
```

Expand Down
2 changes: 1 addition & 1 deletion packages/diffhtml/lib/node/patch.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ export default function patchNode(patches, state = {}) {
i += 4;

const domNode = /** @type {HTMLElement} */ (
NodeCache.get(vTree)
createNode(vTree)
);
const refNode = NodeCache.get(refTree);
const newNode = createNode(newTree, ownerDocument, isSVG);
Expand Down
8 changes: 4 additions & 4 deletions packages/diffhtml/lib/tree/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export default function createTree(input, attributes, childNodes, ...rest) {
attributes = {};
childNodes = [];

const inputAttributes = inputAsHTMLEl.attributes;
const inputAttrs = inputAsHTMLEl.attributes;

// When working with a text node, simply save the nodeValue as the
// initial value.
Expand All @@ -80,11 +80,11 @@ export default function createTree(input, attributes, childNodes, ...rest) {
// Element types are the only kind of DOM node we care about attributes
// from. Shadow DOM, Document Fragments, Text, Comment nodes, etc. can
// ignore this.
else if (input.nodeType === 1 && inputAttributes && inputAttributes.length) {
else if (input.nodeType === 1 && inputAttrs && inputAttrs.length) {
attributes = {};

for (let i = 0; i < inputAttributes.length; i++) {
const { name, value } = inputAttributes[i];
for (let i = 0; i < inputAttrs.length; i++) {
const { name, value } = inputAttrs[i];

// If the attribute's value is empty, seek out the property instead.
if (value === '' && name in input) {
Expand Down

0 comments on commit 19ebb1a

Please sign in to comment.