unpoly-rails 3.10.2 → 3.11.0.rc12

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 37db81cf31bc9480ba80407d23344ca9e4bfad195071a655852da126d4f56097
4
- data.tar.gz: d4c8ee2ec83656a6e419002eca43f52f9eaa0656b02fa64087826e18cefcb299
3
+ metadata.gz: 551821fd3e2d1c7b3616920feefcf9b45bb9e0e2d6f01cd3217d6fdf6d9517e9
4
+ data.tar.gz: e195f3dc8af4ac112c332e46d6272a7ec163cae8f6c37b0d635b33e2c7d7a0e6
5
5
  SHA512:
6
- metadata.gz: b959922764b4dafdf7b1756effcd3673bc834f652383da79ee4cb90e34d987b27a15c79ca156e5ef0d0a59e664ef96639c8abbb3c6deb5951b7736eb4d484866
7
- data.tar.gz: 7209ed9ae1f2253689db9ce1aa4db9ee520c7f7794d1b4bce9e4305c945ba367f72e1d1800f4379a0dbeb78aeb7aba304cd739e73f0bf8b6d669c81509c62e1f
6
+ metadata.gz: 424952d386cf1db728343b020fab00f6b4c8da5d33c4f52586704c124a5c2e40b5b337a9d150c29e1830506d5d1f409a60bfe9b3400d8772e182323e36fd3af5
7
+ data.tar.gz: 0c875af0ac3c0d18784b1a3a99472338063992e3e54ee2ef244f66e36cb946e8caa7ecc36c222b071dcd014258681bf93a7fbdd23a9be65dbc40260166ce5d40
data/README.md CHANGED
@@ -25,9 +25,9 @@ Now run `bundle install` and restart your development server.
25
25
  Installing frontend assets
26
26
  --------------------------
27
27
 
28
- ### With esbuild or Webpacker
28
+ ### With npm
29
29
 
30
- If you're using [esbuild](https://esbuild.github.io/) or [Webpacker](https://edgeguides.rubyonrails.org/webpacker.html), install the [`unpoly` npm package](https://unpoly.com/install/npm) to get Unpoly's frontend files.
30
+ If you're using a build tool like [esbuild](https://esbuild.github.io/) or [Webpacker](https://edgeguides.rubyonrails.org/webpacker.html), install the [`unpoly` npm package](https://unpoly.com/install/npm) to get Unpoly's frontend files.
31
31
 
32
32
  Now `import` Unpoly from your `application.js` pack:
33
33
 
@@ -41,7 +41,7 @@ You may need to import [additional files](https://unpoly.com/install), e.g. when
41
41
 
42
42
  ### With the Asset Pipeline
43
43
 
44
- If you're using the [Asset Pipeline](https://guides.rubyonrails.org/asset_pipeline.html), this `unpoly-rails` gem also contains Unpoly's frontend files. The files are automatically added to the Asset Pipeline's <a href="https://guides.rubyonrails.org/asset_pipeline.html#search-paths">search path</a>.
44
+ If you're using the [Asset Pipeline](https://guides.rubyonrails.org/asset_pipeline.html), this `unpoly-rails` gem also contains Unpoly's frontend files. The files are automatically added to the Asset Pipeline's <a href="https://guides.rubyonrails.org/asset_pipeline.html#search-paths">search path</a>.
45
45
 
46
46
  Add the following line to your `application.js` manifest:
47
47
 
@@ -270,51 +270,6 @@ For this to work you must also include the `<meta name="csp-nonce">` tag in the
270
270
  > Prefixing nonces only works for `[up-on...]` attributes. You cannot use it for native HTML attributes like `[onclick]`.
271
271
 
272
272
 
273
- ### Working with context
274
-
275
- Calling `up.context` will return the [context](https://unpoly.com/up.context) object of the targeted layer.
276
-
277
- The context is a JSON object shared between the frontend and the server.
278
- It persists for a series of Unpoly navigation, but is cleared when the user makes a full page load.
279
- Different Unpoly [layers](https://unpoly.com/up.layer) will usually have separate context objects,
280
- although layers may choose to share their context scope.
281
-
282
- You may read and change the context object. Changes will be sent to the frontend with your response.
283
-
284
- ```ruby
285
- class GamesController < ApplicationController
286
-
287
- def restart
288
- up.context[:lives] = 3
289
- render 'stage1'
290
- end
291
-
292
- end
293
- ```
294
-
295
- Keys can be accessed as either strings or symbols:
296
-
297
- ```ruby
298
- puts "You have " + up.layer.context[:lives] + " lives left"
299
- puts "You have " + up.layer.context['lives'] + " lives left"
300
- ````
301
-
302
- You may delete a key from the frontend by calling `up.context.delete`:
303
-
304
- ```ruby
305
- up.context.delete(:foo)
306
- ````
307
-
308
- You may replace the entire context by calling `up.context.replace`:
309
-
310
- ```ruby
311
- context_from_file = JSON.parse(File.read('context.json))
312
- up.context.replace(context_from_file)
313
- ```
314
-
315
- `up.context` is an alias for `up.layer.context`.
316
-
317
-
318
273
  ### Accessing the targeted layer
319
274
 
320
275
  Use the methods below to interact with the [layer](/up.layer) of the fragment being targeted.
@@ -376,49 +331,61 @@ Returns whether the layer targeted for a failed response is an overlay.
376
331
 
377
332
  Returns the [context](https://unpoly.com/up.context) object of the layer targeted for a failed response.
378
333
 
334
+ #### `up.origin_layer.mode`
379
335
 
380
- ### Expiring the client-side cache
336
+ Returns the [mode](https://unpoly.com/up.layer.mode) of the layer that caused the request.
381
337
 
382
- The Unpoly frontend [caches server responses](https://unpoly.com/caching) for a few minutes, making requests to these URLs return instantly.
383
- Only `GET` requests are cached. The entire cache is expired after every non-`GET` request (like `POST` or `PUT`).
338
+ #### `up.origin_layer.root?`
384
339
 
385
- The server may override these defaults. For instance, the server can expire Unpoly's client-side response cache, even for `GET` requests:
340
+ Returns whether the layer that caused the request is the root layer.
341
+
342
+ #### `up.origin_layer.overlay?`
343
+
344
+ Returns whether the layer that caused the request is an overlay.
345
+
346
+
347
+ ### Opening a new overlay
348
+
349
+ You can request the frontend to [render your response in a new overlay](https://unpoly.com/X-Up-Open-Layer):
386
350
 
387
351
  ```ruby
388
- up.cache.expire
352
+ up.layer.open
389
353
  ```
390
354
 
391
- You may also expire a single URL or [URL pattern](https://unpoly.com/url-patterns):
355
+ This will discard the [initial request target](#detecting-a-fragment-update)
356
+ and render your response into [`:main`](https://unpoly.com/main). You can pass an explicit
357
+ target as a `:target` option:
392
358
 
393
359
  ```ruby
394
- up.cache.expire('/notes/*')
360
+ up.layer.open(target: '#overlay')
395
361
  ```
396
362
 
397
- You may also prevent cache expiration for an unsafe request:
363
+ Any [visual layer options](https://unpoly.com/customizing-overlays) can be also be passed as keyword arguments:
364
+
398
365
 
399
366
  ```ruby
400
- up.cache.expire(false)
367
+ up.layer.open(mode: 'drawer', position: 'right')
401
368
  ```
402
369
 
403
- Here is an longer example where the server uses careful cache management to avoid expiring too much of the client-side cache:
370
+
371
+ ### Expiring the client-side cache
372
+
373
+ The Unpoly frontend [caches server responses](https://unpoly.com/caching) for a few minutes, making requests to these URLs return instantly.
374
+ Only `GET` requests are cached. The entire cache is expired after every non-`GET` request (like `POST` or `PUT`).
375
+
376
+ The server may override these defaults. For instance, the server can expire Unpoly's client-side response cache, even for `GET` requests:
404
377
 
405
378
  ```ruby
406
- def NotesController < ApplicationController
379
+ up.cache.expire
380
+ ```
407
381
 
408
- def create
409
- @note = Note.create!(params[:note].permit(...))
410
- if @note.save
411
- up.cache.expire('/notes/*') # Only expire affected entries
412
- redirect_to(@note)
413
- else
414
- up.cache.expire(false) # Keep the cache fresh because we haven't saved
415
- render 'new'
416
- end
417
- end
418
- ...
419
- end
382
+ You may also expire a single URL or [URL pattern](https://unpoly.com/url-patterns):
383
+
384
+ ```ruby
385
+ up.cache.expire('/notes/*')
420
386
  ```
421
387
 
388
+
422
389
  ### Evicting pages from the client-side cache
423
390
 
424
391
  Instead of *expiring* pages from the cache you may also *evict*. The difference is that expired pages can still be rendered instantly and are then [revalidated](/caching#revalidation) with the server. Evicted pages are erased from the cache.
@@ -498,6 +465,52 @@ If the initial page was loaded with a non-`GET` HTTP method, Unpoly will fall ba
498
465
  The reason for this is that some browsers remember the method of the initial page load and don't let the application change it, even with `pushState`. Thus, when the user reloads the page much later, an affected browser might request a `POST`, `PUT`, etc. instead of the correct method.
499
466
 
500
467
 
468
+ ### Working with context
469
+
470
+ Calling `up.context` will return the [context](https://unpoly.com/up.context) object of the targeted layer.
471
+
472
+ The context is a JSON object shared between the frontend and the server.
473
+ It persists for a series of Unpoly navigation, but is cleared when the user makes a full page load.
474
+ Different Unpoly [layers](https://unpoly.com/up.layer) will usually have separate context objects,
475
+ although layers may choose to share their context scope.
476
+
477
+ You may read and change the context object. Changes will be sent to the frontend with your response.
478
+
479
+ ```ruby
480
+ class GamesController < ApplicationController
481
+
482
+ def restart
483
+ up.context[:lives] = 3
484
+ render 'stage1'
485
+ end
486
+
487
+ end
488
+ ```
489
+
490
+ Keys can be accessed as either strings or symbols:
491
+
492
+ ```ruby
493
+ puts "You have " + up.layer.context[:lives] + " lives left"
494
+ puts "You have " + up.layer.context['lives'] + " lives left"
495
+ ````
496
+
497
+ You may delete a key from the frontend by calling `up.context.delete`:
498
+
499
+ ```ruby
500
+ up.context.delete(:foo)
501
+ ````
502
+
503
+ You may replace the entire context by calling `up.context.replace`:
504
+
505
+ ```ruby
506
+ context_from_file = JSON.parse(File.read('context.json))
507
+ up.context.replace(context_from_file)
508
+ ```
509
+
510
+ `up.context` is an alias for `up.layer.context`.
511
+
512
+
513
+
501
514
  What you still need to do manually
502
515
  ----------------------------------
503
516
 
@@ -50,7 +50,7 @@ __webpack_require__.r(__webpack_exports__);
50
50
  /******/
51
51
  /************************************************************************/
52
52
  var __webpack_exports__ = {};
53
- // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
53
+ // This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
54
54
  (() => {
55
55
  up.status.config.currentClasses.push('active');
56
56
  up.status.config.activeClasses.push('active');
@@ -1 +1 @@
1
- (()=>{var o={303:(o,p,u)=>{"use strict";u.r(p)}},p={};function u(e){var a=p[e];if(void 0!==a)return a.exports;var t=p[e]={exports:{}};return o[e](t,t.exports,u),t.exports}u.r=o=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(o,"o",{value:!0})},up.status.config.currentClasses.push("active"),up.status.config.activeClasses.push("active"),up.status.config.navSelectors.push(".nav",".navbar"),up.form.config.groupSelectors.unshift(".form-group"),up.viewport.config.fixedTopSelectors.push(".navbar-fixed-top"),up.viewport.config.fixedBottomSelectors.push(".navbar-fixed-bottom"),up.viewport.config.anchoredRightSelectors.push(".navbar-fixed-top",".navbar-fixed-bottom"),up.fragment.config.badTargetClasses.push("row",/^col(-xs|-sm|-md|-lg)?(-\d+)?$/),up.layer.config.foreignOverlaySelectors.push(".modal:not(up-modal)",".popover:not(up-popup)",".dropdown-menu:not(up-popup)"),u(303)})();
1
+ (()=>{var o={215:(o,p,u)=>{"use strict";u.r(p)}},p={};function u(e){var a=p[e];if(void 0!==a)return a.exports;var t=p[e]={exports:{}};return o[e](t,t.exports,u),t.exports}u.r=o=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(o,"o",{value:!0})},up.status.config.currentClasses.push("active"),up.status.config.activeClasses.push("active"),up.status.config.navSelectors.push(".nav",".navbar"),up.form.config.groupSelectors.unshift(".form-group"),up.viewport.config.fixedTopSelectors.push(".navbar-fixed-top"),up.viewport.config.fixedBottomSelectors.push(".navbar-fixed-bottom"),up.viewport.config.anchoredRightSelectors.push(".navbar-fixed-top",".navbar-fixed-bottom"),up.fragment.config.badTargetClasses.push("row",/^col(-xs|-sm|-md|-lg)?(-\d+)?$/),up.layer.config.foreignOverlaySelectors.push(".modal:not(up-modal)",".popover:not(up-popup)",".dropdown-menu:not(up-popup)"),u(215)})();
@@ -50,7 +50,7 @@ __webpack_require__.r(__webpack_exports__);
50
50
  /******/
51
51
  /************************************************************************/
52
52
  var __webpack_exports__ = {};
53
- // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
53
+ // This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
54
54
  (() => {
55
55
  up.status.config.currentClasses.push('active');
56
56
  up.status.config.activeClasses.push('active');
@@ -1 +1 @@
1
- (()=>{var o={79:(o,p,u)=>{"use strict";u.r(p)}},p={};function u(e){var t=p[e];if(void 0!==t)return t.exports;var a=p[e]={exports:{}};return o[e](a,a.exports,u),a.exports}u.r=o=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(o,"o",{value:!0})},up.status.config.currentClasses.push("active"),up.status.config.activeClasses.push("active"),up.status.config.navSelectors.push(".nav",".navbar"),up.form.config.groupSelectors.unshift(".form-group"),up.viewport.config.fixedTopSelectors.push(".navbar.fixed-top"),up.viewport.config.fixedBottomSelectors.push(".navbar.fixed-bottom"),up.viewport.config.anchoredRightSelectors.push(".navbar.fixed-top",".navbar.fixed-bottom"),up.fragment.config.badTargetClasses.push("row",/^col(-xs|-sm|-md|-lg|-xl)?(-\d+)?$/,/^[mp][tblrxy]?-\d+$/),up.layer.config.foreignOverlaySelectors.push(".modal:not(up-modal)",".popover:not(up-popup)",".dropdown-menu:not(up-popup)"),u(79)})();
1
+ (()=>{var o={566:(o,p,u)=>{"use strict";u.r(p)}},p={};function u(e){var t=p[e];if(void 0!==t)return t.exports;var a=p[e]={exports:{}};return o[e](a,a.exports,u),a.exports}u.r=o=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(o,"o",{value:!0})},up.status.config.currentClasses.push("active"),up.status.config.activeClasses.push("active"),up.status.config.navSelectors.push(".nav",".navbar"),up.form.config.groupSelectors.unshift(".form-group"),up.viewport.config.fixedTopSelectors.push(".navbar.fixed-top"),up.viewport.config.fixedBottomSelectors.push(".navbar.fixed-bottom"),up.viewport.config.anchoredRightSelectors.push(".navbar.fixed-top",".navbar.fixed-bottom"),up.fragment.config.badTargetClasses.push("row",/^col(-xs|-sm|-md|-lg|-xl)?(-\d+)?$/,/^[mp][tblrxy]?-\d+$/),up.layer.config.foreignOverlaySelectors.push(".modal:not(up-modal)",".popover:not(up-popup)",".dropdown-menu:not(up-popup)"),u(566)})();
@@ -50,7 +50,7 @@ __webpack_require__.r(__webpack_exports__);
50
50
  /******/
51
51
  /************************************************************************/
52
52
  var __webpack_exports__ = {};
53
- // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
53
+ // This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
54
54
  (() => {
55
55
  up.status.config.currentClasses.push('active');
56
56
  up.status.config.activeClasses.push('active');
@@ -1 +1 @@
1
- (()=>{var o={313:(o,p,e)=>{"use strict";e.r(p)}},p={};function e(u){var t=p[u];if(void 0!==t)return t.exports;var a=p[u]={exports:{}};return o[u](a,a.exports,e),a.exports}e.r=o=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(o,"o",{value:!0})},up.status.config.currentClasses.push("active"),up.status.config.activeClasses.push("active"),up.status.config.navSelectors.push(".nav",".navbar"),up.viewport.config.fixedTopSelectors.push(".navbar.fixed-top"),up.viewport.config.fixedBottomSelectors.push(".navbar.fixed-bottom"),up.viewport.config.anchoredRightSelectors.push(".navbar.fixed-top",".navbar.fixed-bottom"),up.fragment.config.badTargetClasses.push("row",/^col(-xs|-sm|-md|-lg|-xl|-xxl)?(-\d+)?$/,/^[mp][tbsexy]?-\d+$/),up.layer.config.foreignOverlaySelectors.push(".modal:not(up-modal)",".popover:not(up-popup)",".dropdown-menu:not(up-popup)"),e(313)})();
1
+ (()=>{var o={633:(o,p,e)=>{"use strict";e.r(p)}},p={};function e(u){var t=p[u];if(void 0!==t)return t.exports;var a=p[u]={exports:{}};return o[u](a,a.exports,e),a.exports}e.r=o=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(o,"o",{value:!0})},up.status.config.currentClasses.push("active"),up.status.config.activeClasses.push("active"),up.status.config.navSelectors.push(".nav",".navbar"),up.viewport.config.fixedTopSelectors.push(".navbar.fixed-top"),up.viewport.config.fixedBottomSelectors.push(".navbar.fixed-bottom"),up.viewport.config.anchoredRightSelectors.push(".navbar.fixed-top",".navbar.fixed-bottom"),up.fragment.config.badTargetClasses.push("row",/^col(-xs|-sm|-md|-lg|-xl|-xxl)?(-\d+)?$/,/^[mp][tbsexy]?-\d+$/),up.layer.config.foreignOverlaySelectors.push(".modal:not(up-modal)",".popover:not(up-popup)",".dropdown-menu:not(up-popup)"),e(633)})();