litewire 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.MD +121 -9
- package/package.json +1 -1
package/README.MD
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
# Litewire 1.0.
|
|
1
|
+
# Litewire 1.0.5
|
|
2
2
|
|
|
3
3
|
Litewire is a small browser-side HTML-over-the-wire library. It binds HTTP
|
|
4
4
|
requests, reactive state, and event expressions to HTML attributes, swaps
|
|
5
5
|
server-rendered HTML into the page, and can load ES module components on
|
|
6
6
|
demand.
|
|
7
7
|
|
|
8
|
-
Version 1.0.
|
|
8
|
+
Version 1.0.5 adds reactive `lw:class` bindings, iterable lists with
|
|
9
9
|
`template[lw:for]`, and event-triggered component mounting. It also improves
|
|
10
10
|
radio model initialization and browser-history markup restoration.
|
|
11
11
|
|
|
12
12
|
## Contents
|
|
13
13
|
|
|
14
14
|
- [Install and start](#install-and-start)
|
|
15
|
+
- [End-to-end example](#end-to-end-example)
|
|
15
16
|
- [Configuration](#configuration)
|
|
16
17
|
- [AJAX requests](#ajax-requests)
|
|
17
18
|
- [Reactive state and bindings](#reactive-state-and-bindings)
|
|
@@ -21,6 +22,7 @@ radio model initialization and browser-history markup restoration.
|
|
|
21
22
|
- [Browser history](#browser-history)
|
|
22
23
|
- [Lifecycle events](#lifecycle-events)
|
|
23
24
|
- [CSRF](#csrf)
|
|
25
|
+
- [Troubleshooting](#troubleshooting)
|
|
24
26
|
- [Security considerations](#security-considerations)
|
|
25
27
|
- [API reference](#api-reference)
|
|
26
28
|
|
|
@@ -40,10 +42,10 @@ continues scanning elements added later.
|
|
|
40
42
|
|
|
41
43
|
### Use the npm package
|
|
42
44
|
|
|
43
|
-
Install version 1.0.
|
|
45
|
+
Install version 1.0.5 from your configured npm registry:
|
|
44
46
|
|
|
45
47
|
```sh
|
|
46
|
-
npm install litewire@1.0.
|
|
48
|
+
npm install litewire@1.0.5
|
|
47
49
|
```
|
|
48
50
|
|
|
49
51
|
Import the package from your application's JavaScript entry point:
|
|
@@ -72,6 +74,45 @@ and observers.
|
|
|
72
74
|
Litewire sends a GET request when the button is clicked and replaces the
|
|
73
75
|
contents of `#result` with the response HTML.
|
|
74
76
|
|
|
77
|
+
## End-to-end example
|
|
78
|
+
|
|
79
|
+
This example uses an HTML form to submit a search query and swaps the
|
|
80
|
+
server-rendered result into a separate element:
|
|
81
|
+
|
|
82
|
+
```html
|
|
83
|
+
<form
|
|
84
|
+
lw-get="/search"
|
|
85
|
+
lw-target="#search-results"
|
|
86
|
+
lw-indicator="#search-status"
|
|
87
|
+
>
|
|
88
|
+
<label>
|
|
89
|
+
Search
|
|
90
|
+
<input name="q" type="search" required>
|
|
91
|
+
</label>
|
|
92
|
+
<button type="submit">Search</button>
|
|
93
|
+
<span id="search-status" aria-live="polite">Ready</span>
|
|
94
|
+
</form>
|
|
95
|
+
|
|
96
|
+
<section id="search-results" aria-live="polite">
|
|
97
|
+
Enter a query to see results.
|
|
98
|
+
</section>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The browser sends a request like `GET /search?q=...`. The endpoint should
|
|
102
|
+
return an HTML fragment, for example:
|
|
103
|
+
|
|
104
|
+
```html
|
|
105
|
+
<h2>Results for “tea”</h2>
|
|
106
|
+
<ul>
|
|
107
|
+
<li>Green tea</li>
|
|
108
|
+
<li>Black tea</li>
|
|
109
|
+
</ul>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Litewire replaces the contents of `#search-results` with that fragment. The
|
|
113
|
+
new content is scanned for Litewire attributes and any `lw-component` modules
|
|
114
|
+
are loaded. No JSON decoding or client-side template rendering is performed.
|
|
115
|
+
|
|
75
116
|
## Configuration
|
|
76
117
|
|
|
77
118
|
Litewire resolves its base URL in this order:
|
|
@@ -166,6 +207,33 @@ the element is scanned:
|
|
|
166
207
|
<div id="account-summary"></div>
|
|
167
208
|
```
|
|
168
209
|
|
|
210
|
+
### Request and form behavior
|
|
211
|
+
|
|
212
|
+
- A form listens for `submit` by default. Other elements listen for `click`.
|
|
213
|
+
Set `lw-trigger` to a DOM event name to use another event; `load` runs the
|
|
214
|
+
request immediately when the element is discovered.
|
|
215
|
+
- A GET request serializes all successful controls in the nearest containing
|
|
216
|
+
form as URL query parameters. If there is no containing form, a control with
|
|
217
|
+
a `name` and `value` contributes that one parameter.
|
|
218
|
+
- POST, PUT, and DELETE requests send the nearest containing form as
|
|
219
|
+
`FormData`. If there is no form, Litewire sends no request body.
|
|
220
|
+
- Litewire checks `response.ok`; a non-success status is treated as a request
|
|
221
|
+
failure. Successful response bodies are read as text and inserted as HTML.
|
|
222
|
+
Set the response `Content-Type` appropriately on the server, even though
|
|
223
|
+
Litewire does not parse it.
|
|
224
|
+
- `lw-target` is resolved with `document.querySelector`. If omitted, the
|
|
225
|
+
triggering element is the target. Ensure the selector matches the intended
|
|
226
|
+
element when the response is applied.
|
|
227
|
+
- A trigger and each loading indicator receive the configured loading class
|
|
228
|
+
while the request is in flight. By default, indicators are descendants with
|
|
229
|
+
the `litewire-indicator` class; `lw-indicator` can select indicators
|
|
230
|
+
elsewhere in the document.
|
|
231
|
+
- Request failures are logged to the console and emit `litewire:error` from
|
|
232
|
+
the trigger. The loading class is removed on both success and failure.
|
|
233
|
+
|
|
234
|
+
`lw-trigger="load"` is useful for initial content, but avoid putting it on
|
|
235
|
+
large numbers of elements if they would all issue requests at once.
|
|
236
|
+
|
|
169
237
|
## Reactive state and bindings
|
|
170
238
|
|
|
171
239
|
Litewire provides a small reactive layer using `lw:state`, `lw:model`,
|
|
@@ -259,11 +327,36 @@ written with the instance methods `litewire.getModel(name)` and
|
|
|
259
327
|
`litewire.setModel(name, value)`. Global model changes dispatch a
|
|
260
328
|
`litewire:model` event on `document`, with `{ name, value }` in `event.detail`.
|
|
261
329
|
|
|
330
|
+
For example, a control outside a local state root can populate a global model,
|
|
331
|
+
and a matching text binding can display it:
|
|
332
|
+
|
|
333
|
+
```html
|
|
334
|
+
<input name="status" lw:model="status" aria-label="Status">
|
|
335
|
+
<p>Current status: <span lw:text="status"></span></p>
|
|
336
|
+
|
|
337
|
+
<script type="module">
|
|
338
|
+
import "litewire";
|
|
339
|
+
|
|
340
|
+
window.addEventListener("DOMContentLoaded", () => {
|
|
341
|
+
window.litewire.setModel("status", "Ready");
|
|
342
|
+
});
|
|
343
|
+
</script>
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
When setting global models from application code, set them on the initialized
|
|
347
|
+
`window.litewire` instance. `setModel()` updates a `lw:text` binding whose
|
|
348
|
+
expression is exactly that model name, reevaluates global `lw:class` and
|
|
349
|
+
`lw:for` bindings, and dispatches `litewire:model`.
|
|
350
|
+
|
|
262
351
|
A model name beginning with `#` or `.` is treated as a CSS selector instead of
|
|
263
352
|
a state key. Litewire copies the control's value to matching elements (to
|
|
264
353
|
`value` for form controls, otherwise to `textContent`) and dispatches
|
|
265
354
|
`litewire:model` on each target with `{ value }` in `event.detail`.
|
|
266
355
|
|
|
356
|
+
For example, `lw:model="#live-preview"` copies an input value to the
|
|
357
|
+
`textContent` of the element with that ID. Selector-based models update the
|
|
358
|
+
matching targets; they are not reactive state properties.
|
|
359
|
+
|
|
267
360
|
### Event expressions
|
|
268
361
|
|
|
269
362
|
Supported event attributes are:
|
|
@@ -316,9 +409,9 @@ level so it can observe events outside the element.
|
|
|
316
409
|
|
|
317
410
|
An element with `lw-component` dynamically imports a JavaScript module. The
|
|
318
411
|
path is joined to Litewire's base URL. Litewire selects the module's default
|
|
319
|
-
export first, then
|
|
320
|
-
|
|
321
|
-
|
|
412
|
+
export first, then its first export. If the selected export is a function, it
|
|
413
|
+
is called with the host element and its `data-*` attributes converted to an
|
|
414
|
+
object:
|
|
322
415
|
|
|
323
416
|
```html
|
|
324
417
|
<div
|
|
@@ -438,6 +531,19 @@ When this meta tag is present, Litewire adds its token as the
|
|
|
438
531
|
The server must still validate the token and enforce its own authorization and
|
|
439
532
|
request protections.
|
|
440
533
|
|
|
534
|
+
## Troubleshooting
|
|
535
|
+
|
|
536
|
+
| Symptom | Things to check |
|
|
537
|
+
|---|---|
|
|
538
|
+
| The global `window.litewire` is missing | Load Litewire in a browser as a module and check the console for module loading errors. Auto-initialization occurs after the document is ready. |
|
|
539
|
+
| A request does not run | Confirm the element has one of `lw-get`, `lw-post`, `lw-put`, or `lw-delete`. Check its default or configured `lw-trigger` event and whether another handler prevents the event from reaching it. |
|
|
540
|
+
| The server receives no form values | Make sure the trigger is inside the form, or is the form itself. Non-GET requests without a containing form have no body. For GET, a standalone control needs both `name` and `value`. |
|
|
541
|
+
| The request succeeds but the page does not change | Return an HTML fragment, verify `lw-target` matches an element, and check that the selected `lw-swap` behavior is suitable. |
|
|
542
|
+
| A request reports an error | Inspect the browser console and the `litewire:error` event. Litewire treats HTTP statuses outside the 2xx range as failures. |
|
|
543
|
+
| A state binding stays unchanged | Confirm the binding is under the intended `lw:state` root. Replace a top-level state property; nested mutations are not observed. |
|
|
544
|
+
| A component does not mount | Check the module URL, its default or first export, and that the export is a function. For deferred components, verify the triggering event and optional `lw-target` selector. |
|
|
545
|
+
| A directive in newly inserted HTML does not run | Ensure the HTML is inserted through a Litewire swap or added to the observed document body. The observer watches additions under `document.body`. |
|
|
546
|
+
|
|
441
547
|
## Security considerations
|
|
442
548
|
|
|
443
549
|
Litewire inserts response bodies as HTML. Only return trusted or appropriately
|
|
@@ -453,11 +559,11 @@ untrusted user input.
|
|
|
453
559
|
|---|---|
|
|
454
560
|
| `lw-get`, `lw-post`, `lw-put`, `lw-delete` | Request path and HTTP method |
|
|
455
561
|
| `lw-trigger` | Request event (defaults to `click` or form `submit`; `load` runs on scan); for components, event to defer mounting |
|
|
456
|
-
| `lw-target` | CSS selector for the response target |
|
|
562
|
+
| `lw-target` | CSS selector for the response target; for a triggered component, selects the element passed to the component |
|
|
457
563
|
| `lw-swap` | `innerHTML`, `outerHTML`, `prepend`, or `append` |
|
|
458
564
|
| `lw-indicator` | CSS selector for loading indicators |
|
|
459
565
|
| `lw-push-url` | `true`, `false`, or a custom history URL |
|
|
460
|
-
| `lw-component` | Path to a dynamically imported ES module |
|
|
566
|
+
| `lw-component` | Path to a dynamically imported ES module; its default export or first export is mounted |
|
|
461
567
|
| `lw:state` | JavaScript object expression that initializes local reactive state |
|
|
462
568
|
| `lw:model`, `.live`, `.change`, `.blur` | Bind a form control to a state or global model |
|
|
463
569
|
| `lw:text` | Render an expression as text |
|
|
@@ -467,5 +573,11 @@ untrusted user input.
|
|
|
467
573
|
| `lw:click`, `lw:input`, `lw:change`, `lw:submit`, `lw:keydown`, `lw:keyup`, `lw:focus`, `lw:blur` | Evaluate an expression in response to an event; supports the modifiers documented above |
|
|
468
574
|
| `litewire.getModel(name)` | Read a global model |
|
|
469
575
|
| `litewire.setModel(name, value)` | Set a global model and update matching bindings |
|
|
576
|
+
| `new Litewire({ baseUrl, loadingClass })` | Construct and initialize an instance with optional configuration |
|
|
577
|
+
|
|
578
|
+
The browser module exports the `Litewire` class as its default export and
|
|
579
|
+
auto-creates `window.litewire` if that global is not already set. When creating
|
|
580
|
+
a custom instance, set `window.litewire` to a placeholder before importing the
|
|
581
|
+
module if needed to prevent auto-initialization, then assign the instance.
|
|
470
582
|
|
|
471
583
|
**Buy my kids schoolbooks:** [https://paypal.me/justumg](https://paypal.me/justumg)
|