phoenix_live_view 0.17.2 → 0.17.6

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/CHANGELOG.md CHANGED
@@ -1,23 +1,70 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.17.6 (2022-01-18)
4
+
5
+ ### Enhancements
6
+ - Add `JS.set_attribute` and `JS.remove_attribute`
7
+ - Add `sticky: true` option to `live_render` to maintain a nested child on across live redirects
8
+ - Dispatch `phx:show-start`, `phx:show-end`, `phx:hide-start` and `phx:hide-end` on `JS.show|hide|toggle`
9
+ - Add `get_connect_info/2` that also works on disconnected render
10
+ - Add `LiveSocket` constructor options for configuration failsafe behavior via new `maxReloads`, `reloadJitterMin`, `reloadJitterMax`, `failsafeJitter` options
11
+
12
+ ### Bug fixes
13
+ - Show form errors after submit even when no changes occur on server
14
+ - Fix `phx-disable-with` failing to disable elements outside of forms
15
+ - Fix phx ref tracking leaving elements in awaiting state when targeting an external LiveView
16
+ - Fix diff on response failing to await for active transitions in certain cases
17
+ - Fix `phx-click-away` not respecting `phx-target`
18
+ - Fix "disconnect" broadcast failing to failsafe refresh the page
19
+ - Fix `JS.push` with `:target` failing to send to correct component in certain cases
20
+
21
+ ### Deprecations
22
+ - Deprecate `Phoenix.LiveView.get_connect_info/1` in favor of `get_connect_info/2`
23
+ - Deprecate `Phoenix.LiveViewTest.put_connect_info/2` in favor of calling the relevant functions in `Plug.Conn`
24
+
25
+ ## 0.17.5 (2021-11-02)
26
+
27
+ ### Bug fixes
28
+ - Do not trigger `phx-click-away` if element is not visible
29
+ - Fix `phx-remove` failing to tear down nested live children
30
+
31
+ ## 0.17.4 (2021-11-01)
32
+
33
+ ### Bug fixes
34
+ - Fix variable scoping issues causing various content block or duplication rendering bugs
35
+
36
+ ## 0.17.3 (2021-10-28)
37
+
38
+ ### Enhancements
39
+ - Support 3-tuple for JS class transitions to support staged animations where a transition class is applied with a starting and ending class
40
+ - Allow JS commands to be executed on DOM nodes outside of the LiveView container
41
+
42
+ ### Optimization
43
+ - Avoid duplicate statics inside comprehension. In previous versions, comprehensions were able to avoid duplication only in the content of their root. Now we recursively traverse all comprehension nodes and send the static only once for the whole comprehension. This should massively reduce the cost of sending comprehensions over the wire
44
+
45
+ ### Bug fixes
46
+ - Fix HTML engine bug causing expressions to be duplicated or not rendered correctly
47
+ - Fix HTML engine bug causing slots to not be re-rendered when they should have
48
+ - Fix form recovery being sent to wrong target
49
+
3
50
  ## 0.17.2 (2021-10-22)
4
51
 
5
52
  ### Bug fixes
6
53
  - Fix HTML engine bug causing attribute expressions to be incorrectly evaluated in certain cases
7
- - Fix show/hide/toggle custom display not being restored.
54
+ - Fix show/hide/toggle custom display not being restored
8
55
  - Fix default `to` target for `JS.show|hide|dispatch`
9
- - Fix form input targetting
56
+ - Fix form input targeting
10
57
 
11
58
  ## 0.17.1 (2021-10-21)
12
59
 
13
60
  ### Bug fixes
14
- - Fix SVG element support for phx binding interactions
61
+ - Fix SVG element support for `phx` binding interactions
15
62
 
16
63
  ## 0.17.0 (2021-10-21)
17
64
 
18
65
  ### Breaking Changes
19
66
 
20
- #### on_mount changes
67
+ #### `on_mount` changes
21
68
 
22
69
  The hook API introduced in LiveView 0.16 has been improved based on feedback.
23
70
  LiveView 0.17 removes the custom module-function callbacks for the
@@ -63,17 +110,17 @@ atom `:default`.
63
110
  #### LEEx templates in stateful LiveComponents
64
111
 
65
112
  Stateful LiveComponents (where an `:id` is given) must now return HEEx templates
66
- (`~H` sigil or `.heex` extension). LEEx temlates (`~L` sigil or `.leex` extension)
113
+ (`~H` sigil or `.heex` extension). LEEx templates (`~L` sigil or `.leex` extension)
67
114
  are no longer supported. This addresses bugs and allows stateful components
68
115
  to be rendered more efficiently client-side.
69
116
 
70
- #### phx-disconnected class has been replaced with phx-loading
117
+ #### `phx-disconnected` class has been replaced with `phx-loading`
71
118
 
72
- Due to a bug in the newly released Safari 15, the previously used `.phx-disconnected` class has been replaced by a new `.phx-loading` class. The reason for the change is `phx.new` included a `.phx-disconnected` rule in the generated `app.css` which triggers the Safari bug. Renaming the class avoids applying the erronous rule for existing applications. Folks can upgrade by simply renaming their `.phx-disconnected` rules to `.phx-loading`.
119
+ Due to a bug in the newly released Safari 15, the previously used `.phx-disconnected` class has been replaced by a new `.phx-loading` class. The reason for the change is `phx.new` included a `.phx-disconnected` rule in the generated `app.css` which triggers the Safari bug. Renaming the class avoids applying the erroneous rule for existing applications. Folks can upgrade by simply renaming their `.phx-disconnected` rules to `.phx-loading`.
73
120
 
74
- #### phx-capture-click has been deprecated in favor of phx-click-away
121
+ #### `phx-capture-click` has been deprecated in favor of `phx-click-away`
75
122
 
76
- The new phx-click-away binding replaces phx-capture-click and is much more versatile because it can detect "click focus" being lost on containers.
123
+ The new `phx-click-away` binding replaces `phx-capture-click` and is much more versatile because it can detect "click focus" being lost on containers.
77
124
 
78
125
  #### Removal of previously deprecated functionality
79
126
 
@@ -84,23 +131,23 @@ Some functionality that was previously deprecated has been removed:
84
131
 
85
132
  ### Enhancements
86
133
  - Allow slots in function components: they are marked as `<:slot_name>` and can be rendered with `<%= render_slot @slot_name %>`
87
- - Add JS command for executing JavaScript utility operations on the client with an extended push API
134
+ - Add `JS` command for executing JavaScript utility operations on the client with an extended push API
88
135
  - Optimize string attributes:
89
136
  - If the attribute is a string interpolation, such as `<div class={"foo bar #{@baz}"}>`, only the interpolation part is marked as dynamic
90
137
  - If the attribute can be empty, such as "class" and "style", keep the attribute name as static
91
138
  - Add a function component for rendering `Phoenix.LiveComponent`. Instead of `<%= live_component FormComponent, id: "form" %>`, you must now do: `<.live_component module={FormComponent} id="form" />`
92
139
 
93
140
  ### Bug fixes
94
- - Fix LiveViews with form recovery failing to properly mount following a reconnect when preceeded by a live redirect
141
+ - Fix LiveViews with form recovery failing to properly mount following a reconnect when preceded by a live redirect
95
142
  - Fix stale session causing full redirect fallback when issuing a `push_redirect` from mount
96
- - Add workaround for Safari bug causing img tags with srcset and video with autoplay to fail to render
143
+ - Add workaround for Safari bug causing `<img>` tags with srcset and video with autoplay to fail to render
97
144
  - Support EEx interpolation inside HTML comments in HEEx templates
98
145
  - Support HTML tags inside script tags (as in regular HTML)
99
146
  - Raise if using quotes in attribute names
100
147
  - Include the filename in error messages when it is not possible to parse interpolated attributes
101
148
  - Make sure the test client always sends the full URL on `live_patch`/`live_redirect`. This mirrors the behaviour of the JavaScript client
102
149
  - Do not reload flash from session on `live_redirect`s
103
- - Fix select drop-down flashes in chrome when the DOM is patched during focus
150
+ - Fix select drop-down flashes in Chrome when the DOM is patched during focus
104
151
 
105
152
  ### Deprecations
106
153
  - `<%= live_component MyModule, id: @user.id, user: @user %>` is deprecated in favor of `<.live_component module={MyModule} id={@user.id} user={@user} />`. Notice the new API requires using HEEx templates. This change allows us to further improve LiveComponent and bring new features such as slots to them.
@@ -112,7 +159,7 @@ Some functionality that was previously deprecated has been removed:
112
159
  - Improve HEEx error messages
113
160
  - Relax HTML tag validation to support mixed case tags
114
161
  - Support self closing HTML tags
115
- - Remove requirement for handle_params to be defined for lifecycle hooks
162
+ - Remove requirement for `handle_params` to be defined for lifecycle hooks
116
163
 
117
164
  ### Bug fixes
118
165
  - Fix pushes failing to include channel `join_ref` on messages
@@ -126,10 +173,10 @@ Some functionality that was previously deprecated has been removed:
126
173
 
127
174
  ### Enhancements
128
175
  - Improve error messages on tokenization
129
- - Improve error message if inner_block is missing
176
+ - Improve error message if `@inner_block` is missing
130
177
 
131
178
  ### Bug fixes
132
- - Fix phx-change form recovery event being sent to wrong component on reconnect when component order changes
179
+ - Fix `phx-change` form recovery event being sent to wrong component on reconnect when component order changes
133
180
 
134
181
  ## 0.16.1 (2021-08-26)
135
182
 
@@ -140,7 +187,7 @@ Some functionality that was previously deprecated has been removed:
140
187
 
141
188
  ### Bug fixes
142
189
  - Do not generate CSRF tokens for non-POST forms
143
- - Do not add compile-time dependencies on on_mount declarations
190
+ - Do not add compile-time dependencies on `on_mount` declarations
144
191
 
145
192
  ## 0.16.0 (2021-08-10)
146
193
 
@@ -178,7 +225,7 @@ and example usage.
178
225
 
179
226
  ### New HTML Engine
180
227
 
181
- LiveView v0.16 introduces HEEx (HTML+EEx) templates and the concept of function
228
+ LiveView v0.16 introduces HEEx (HTML + EEx) templates and the concept of function
182
229
  components via `Phoenix.Component`. The new HEEx templates validate the markup in
183
230
  the template while also providing smarter change tracking as well as syntax
184
231
  conveniences to make it easier to build composable components.
@@ -302,6 +349,9 @@ Additionally on the client, the root LiveView element no longer exposes the
302
349
  LiveView module name, therefore the `phx-view` attribute is never set.
303
350
  Similarly, the `viewName` property of client hooks has been removed.
304
351
 
352
+ Codebases calling a custom function `component/3` should rename it or specify its module to avoid a conflict,
353
+ as LiveView introduces a macro with that name and it is special cased by the underlying engine.
354
+
305
355
  ### Enhancements
306
356
  - Introduce HEEx templates
307
357
  - Introduce `Phoenix.Component`
@@ -320,12 +370,12 @@ Similarly, the `viewName` property of client hooks has been removed.
320
370
 
321
371
  ### Bug fixes
322
372
  - Make sure components are loaded on `render_component` to ensure all relevant callbacks are invoked
323
- - Fix `Phoenix.LiveViewTest.page_title` returning nil in some cases
373
+ - Fix `Phoenix.LiveViewTest.page_title` returning `nil` in some cases
324
374
  - Fix buttons being re-enabled when explicitly set to disabled on server
325
375
  - Fix live patch failing to update URL when live patch link is patched again via `handle_params` within the same callback lifecycle
326
376
  - Fix `phx-no-feedback` class not applied when page is live-patched
327
- - Fix `DOMException, querySelector, not a valid selector` when performing DOM lookups on non-stanard IDs
328
- - Fix select dropdown flashing close/opened when assigns are updated on Chrome/MacOS
377
+ - Fix `DOMException, querySelector, not a valid selector` when performing DOM lookups on non-standard IDs
378
+ - Fix select dropdown flashing close/opened when assigns are updated on Chrome/macOS
329
379
  - Fix error with multiple `live_file_input` in one form
330
380
  - Fix race condition in `showError` causing null `querySelector`
331
381
  - Fix statics not resolving correctly across recursive diffs
@@ -350,7 +400,7 @@ Similarly, the `viewName` property of client hooks has been removed.
350
400
  - Fix live patch failing to update URL when live patch link is patched again from `handle_params`
351
401
  - Fix regression in `LiveViewTest.render_upload/3` when using channel uploads and progress callback
352
402
  - Fix component uploads not being cleaned up on remove
353
- - Fix KeyError on LiveView reconnect when an active upload was previously in progress
403
+ - Fix `KeyError` on LiveView reconnect when an active upload was previously in progress
354
404
 
355
405
  ### Enhancements
356
406
  - Support function components via `component/3`
@@ -376,8 +426,8 @@ Similarly, the `viewName` property of client hooks has been removed.
376
426
  - Fix nested `live_render`'s causing remound of child LiveView even when ID does not change
377
427
  - Do not attempt push hook events unless connected
378
428
  - Fix preflighted refs causing `auto_upload: true` to fail to submit form
379
- - Replace single upload entry when max_entires is 1 instead of accumulating multiple file selections
380
- - Fix static_path in open_browser failing to load stylesheets
429
+ - Replace single upload entry when `max_entries` is 1 instead of accumulating multiple file selections
430
+ - Fix `static_path` in `open_browser` failing to load stylesheets
381
431
 
382
432
  ## 0.15.3 (2021-01-02)
383
433
 
@@ -387,11 +437,11 @@ Similarly, the `viewName` property of client hooks has been removed.
387
437
  ## 0.15.2 (2021-01-01)
388
438
 
389
439
  ### Backwards incompatible changes
390
- - Remove `beforeDestroy` from phx-hook callbacks
440
+ - Remove `beforeDestroy` from `phx-hook` callbacks
391
441
 
392
442
  ### Bug fixes
393
443
  - Fix form recovery failing to send input on first connection failure
394
- - Fix hooks not getting remounted after liveview reconnect
444
+ - Fix hooks not getting remounted after LiveView reconnect
395
445
  - Fix hooks `reconnected` callback being fired with no prior disconnect
396
446
 
397
447
  ## 0.15.1 (2020-12-20)
@@ -401,12 +451,12 @@ Similarly, the `viewName` property of client hooks has been removed.
401
451
  - Run `consume_uploaded_entries` in LiveView caller process
402
452
 
403
453
  ### Bug fixes
404
- - Fix hooks not getting remounted after liveview recovery
454
+ - Fix hooks not getting remounted after LiveView recovery
405
455
  - Fix bug causing reload with jitter on timeout from previously closed channel
406
456
  - Fix component child nodes being lost when component patch goes from single root node to multiple child siblings
407
457
  - Fix `phx-capture-click` triggering on mouseup during text selection
408
458
  - Fix LiveView `push_event`'s not clearing up in components
409
- - Fix textarea being patched by LV while focused
459
+ - Fix `<textarea>` being patched by LiveView while focused
410
460
 
411
461
  ## 0.15.0 (2020-11-20)
412
462
 
@@ -437,7 +487,7 @@ Similarly, the `viewName` property of client hooks has been removed.
437
487
  ### Bug fixes
438
488
  - Fix `redirect(socket, external: ...)` when returned from an event
439
489
  - Properly follow location hashes on live patch/redirect
440
- - Fix failure in `Phoenix.LiveViewTest` when phx-update has non-HTML nodes as children
490
+ - Fix failure in `Phoenix.LiveViewTest` when `phx-update` has non-HTML nodes as children
441
491
  - Fix `phx_trigger_action` submitting the form before the DOM updates are complete
442
492
 
443
493
  ## 0.14.6 (2020-09-21)
@@ -480,16 +530,16 @@ Similarly, the `viewName` property of client hooks has been removed.
480
530
  - Fix `LiveViewTest` failing to patch children properly for append/prepend based phx-update's
481
531
  - Fix argument error when providing `:as` option to a `live` route
482
532
  - Fix page becoming unresponsive when the server crashes while handling a live patch
483
- - Fix empty diff causing pending data-ref based updates, such as classes and disable-with content to not be updated
533
+ - Fix empty diff causing pending data-ref based updates, such as classes and `phx-disable-with` content to not be updated
484
534
  - Fix bug where throttling keydown events would eat key presses
485
- - Fix textarea's failing to be disabled on form submit
486
- - Fix text node DOM memory leak when using phx-update append/prepend
535
+ - Fix `<textarea>`'s failing to be disabled on form submit
536
+ - Fix text node DOM memory leak when using `phx-update` append/prepend
487
537
 
488
538
  ### Enhancements
489
539
  - Allow `:router` to be given to `render_component`
490
540
  - Display file on compile warning for `~L`
491
541
  - Log error on client when using a hook without a DOM ID
492
- - Optimize phx-update append/prepend based DOM updates
542
+ - Optimize `phx-update` append/prepend based DOM updates
493
543
 
494
544
  ## 0.14.1 (2020-07-09)
495
545
 
@@ -502,7 +552,7 @@ Similarly, the `viewName` property of client hooks has been removed.
502
552
  ### Bug fixes
503
553
  - Fix IE11 issue where `document.activeElement` creates a null reference
504
554
  - Fix setup and teardown of root views when explicitly calling `liveSocket.disconnect()` followed by `liveSocket.connect()`
505
- - Fix `error_tag` failing to be displayed for non-text based inputs such as selects and checkboxes as the phx-no-feedback class was always applied
555
+ - Fix `error_tag` failing to be displayed for non-text based inputs such as selects and checkboxes as the `phx-no-feedback` class was always applied
506
556
  - Fix `phx-error` class being applied on `live_redirect`
507
557
  - Properly handle Elixir's special variables, such as `__MODULE__`
508
558
  - No longer set disconnected class during patch
@@ -528,7 +578,7 @@ Similarly, the `viewName` property of client hooks has been removed.
528
578
 
529
579
  ### Bug fixes
530
580
  - Fix duplicate debounced events from being triggered on blur with timed debounce
531
- - Fix client error when live_redirected'd route results in a redirect to a non-live route on the server
581
+ - Fix client error when `live_redirect`ed route results in a redirect to a non-live route on the server
532
582
  - Fix DOM siblings being removed when a rootless component is updated
533
583
  - Fix debounced input failing to send last change when blurred via Tab, Meta, or other non-printable keys
534
584
 
@@ -543,7 +593,7 @@ Similarly, the `viewName` property of client hooks has been removed.
543
593
  ## 0.13.1 (2020-05-26)
544
594
 
545
595
  ### Bug fixes
546
- - Fix forced page refresh when push_redirect from a live_redirect
596
+ - Fix forced page refresh when `push_redirect` from a `live_redirect`
547
597
 
548
598
  ### Enhancements
549
599
  - Optimize component diffs to avoid sending empty diffs
package/README.md CHANGED
@@ -17,9 +17,14 @@ steps:
17
17
  * Use a declarative model to render HTML on the server
18
18
  over WebSockets with optional LongPolling fallback
19
19
 
20
- * Smart templating and change tracking - after connected,
21
- LiveView sends only what changed to the client, skipping
22
- the template markup and reducing the payload
20
+ * A rich templating language, called HEEx, with support
21
+ for function components, slots, HTML validation, and more
22
+
23
+ * Smart change tracking - after connected, LiveView sends
24
+ only what changed to the client, skipping the template
25
+ markup and reducing the payload. This makes LiveView
26
+ payloads much smaller than server-rendered HTML and on
27
+ par with fine-tuned SPA applications
23
28
 
24
29
  * Live form validation with file upload support
25
30
 
@@ -27,9 +32,12 @@ steps:
27
32
  `phx-focus`, `phx-blur`, `phx-submit`, etc. `phx-hook` is
28
33
  included for the cases where you have to write JavaScript
29
34
 
30
- * Code reuse via components, which break templates, state, and
31
- event handling into reusable bits, which is essential in large
32
- applications
35
+ * Perform optimistic updates and transitions via JavaScript
36
+ commands (`Phoenix.LiveView.JS`)
37
+
38
+ * Code reuse via stateful components, which break templates,
39
+ state, and event handling into reusable bits, which is essential
40
+ in large applications
33
41
 
34
42
  * Live navigation to enrich links and redirects to only load the
35
43
  minimum amount of content as users navigate between pages
@@ -106,14 +114,6 @@ anywhere else:
106
114
  sent over the wire. This is achievable thanks to Elixir's
107
115
  immutability and its ability to treat code as data.
108
116
 
109
- * LiveView separates the static and dynamic parts of your templates.
110
- When you first render a page, Phoenix LiveView renders and sends
111
- the whole template to the browser. Then, for any new update, only
112
- the modified dynamic content is resent. This alongside diff tracking
113
- makes it so LiveView only sends a few bytes on every update, instead
114
- of sending kilobytes on every other user interaction - which would
115
- be detrimental to the user experience.
116
-
117
117
  ## Browser Support
118
118
 
119
119
  All current Chrome, Safari, Firefox, and MS Edge are supported.
@@ -148,7 +148,7 @@ import "core-js/features/set"
148
148
  import "core-js/features/url"
149
149
 
150
150
  import {Socket} from "phoenix"
151
- import LiveSocket from "phoenix_live_view"
151
+ import {LiveSocket} from "phoenix_live_view"
152
152
  ...
153
153
  ```
154
154
 
@@ -1,7 +1,8 @@
1
1
 
2
2
  export const CONSECUTIVE_RELOADS = "consecutive-reloads"
3
3
  export const MAX_RELOADS = 10
4
- export const RELOAD_JITTER = [1000, 3000]
4
+ export const RELOAD_JITTER_MIN = 1000
5
+ export const RELOAD_JITTER_MAX = 3000
5
6
  export const FAILSAFE_JITTER = 30000
6
7
  export const PHX_EVENT_CLASSES = [
7
8
  "phx-click-loading", "phx-change-loading", "phx-submit-loading",
@@ -12,6 +13,7 @@ export const PHX_LIVE_LINK = "data-phx-link"
12
13
  export const PHX_TRACK_STATIC = "track-static"
13
14
  export const PHX_LINK_STATE = "data-phx-link-state"
14
15
  export const PHX_REF = "data-phx-ref"
16
+ export const PHX_REF_SRC = "data-phx-ref-src"
15
17
  export const PHX_TRACK_UPLOADS = "track-uploads"
16
18
  export const PHX_UPLOAD_REF = "data-phx-upload-ref"
17
19
  export const PHX_PREFLIGHTED_REFS = "data-phx-preflighted-refs"
@@ -32,11 +34,12 @@ export const PHX_ROOT_ID = "data-phx-root-id"
32
34
  export const PHX_TRIGGER_ACTION = "trigger-action"
33
35
  export const PHX_FEEDBACK_FOR = "feedback-for"
34
36
  export const PHX_HAS_FOCUSED = "phx-has-focused"
35
- export const FOCUSABLE_INPUTS = ["text", "textarea", "number", "email", "password", "search", "tel", "url", "date", "time"]
37
+ export const FOCUSABLE_INPUTS = ["text", "textarea", "number", "email", "password", "search", "tel", "url", "date", "time", "datetime-local", "color", "range"]
36
38
  export const CHECKABLE_INPUTS = ["checkbox", "radio"]
37
39
  export const PHX_HAS_SUBMITTED = "phx-has-submitted"
38
40
  export const PHX_SESSION = "data-phx-session"
39
41
  export const PHX_VIEW_SELECTOR = `[${PHX_SESSION}]`
42
+ export const PHX_STICKY = "data-phx-sticky"
40
43
  export const PHX_STATIC = "data-phx-static"
41
44
  export const PHX_READONLY = "data-phx-readonly"
42
45
  export const PHX_DISABLED = "data-phx-disabled"
@@ -74,3 +77,4 @@ export const COMPONENTS = "c"
74
77
  export const EVENTS = "e"
75
78
  export const REPLY = "r"
76
79
  export const TITLE = "t"
80
+ export const TEMPLATES = "p"
@@ -12,11 +12,13 @@ import {
12
12
  PHX_PARENT_ID,
13
13
  PHX_PRIVATE,
14
14
  PHX_REF,
15
+ PHX_REF_SRC,
15
16
  PHX_ROOT_ID,
16
17
  PHX_SESSION,
17
18
  PHX_STATIC,
18
19
  PHX_UPLOAD_REF,
19
20
  PHX_VIEW_SELECTOR,
21
+ PHX_STICKY,
20
22
  THROTTLED
21
23
  } from "./constants"
22
24
 
@@ -75,6 +77,8 @@ let DOM = {
75
77
  return el.getAttribute && updateTypes.indexOf(el.getAttribute(phxUpdate)) >= 0
76
78
  },
77
79
 
80
+ findPhxSticky(el){ return this.all(el, `[${PHX_STICKY}]`) },
81
+
78
82
  findPhxChildren(el, parentId){
79
83
  return this.all(el, `${PHX_VIEW_SELECTOR}[${PHX_PARENT_ID}="${parentId}"]`)
80
84
  },
@@ -238,6 +242,14 @@ let DOM = {
238
242
  return node.getAttribute && node.getAttribute(PHX_PARENT_ID)
239
243
  },
240
244
 
245
+ isPhxSticky(node){
246
+ return node.getAttribute && node.getAttribute(PHX_STICKY) !== null
247
+ },
248
+
249
+ firstPhxChild(el){
250
+ return this.isPhxChild(el) ? el : this.all(el, `[${PHX_PARENT_ID}]`)[0]
251
+ },
252
+
241
253
  dispatchEvent(target, eventString, detail = {}){
242
254
  let event = new CustomEvent(eventString, {bubbles: true, cancelable: true, detail: detail})
243
255
  target.dispatchEvent(event)
@@ -314,6 +326,7 @@ let DOM = {
314
326
  syncPendingRef(fromEl, toEl, disableWith){
315
327
  let ref = fromEl.getAttribute(PHX_REF)
316
328
  if(ref === null){ return true }
329
+ let refSrc = fromEl.getAttribute(PHX_REF_SRC)
317
330
 
318
331
  if(DOM.isFormInput(fromEl) || fromEl.getAttribute(disableWith) !== null){
319
332
  if(DOM.isUploadInput(fromEl)){ DOM.mergeAttrs(fromEl, toEl, {isIgnored: true}) }
@@ -324,6 +337,7 @@ let DOM = {
324
337
  fromEl.classList.contains(className) && toEl.classList.add(className)
325
338
  })
326
339
  toEl.setAttribute(PHX_REF, ref)
340
+ toEl.setAttribute(PHX_REF_SRC, refSrc)
327
341
  return true
328
342
  }
329
343
  },
@@ -114,14 +114,14 @@ export default class DOMPatch {
114
114
  //input handling
115
115
  DOM.discardError(targetContainer, el, phxFeedbackFor)
116
116
  // nested view handling
117
- if(DOM.isPhxChild(el) && view.ownsElement(el)){
117
+ if((DOM.isPhxChild(el) && view.ownsElement(el)) || DOM.isPhxSticky(el) && view.ownsElement(el.parentNode)){
118
118
  this.trackAfter("phxChildAdded", el)
119
119
  }
120
120
  added.push(el)
121
121
  },
122
122
  onNodeDiscarded: (el) => {
123
123
  // nested view handling
124
- if(DOM.isPhxChild(el)){ liveSocket.destroyViewByEl(el) }
124
+ if(DOM.isPhxChild(el) || DOM.isPhxSticky(el)){ liveSocket.destroyViewByEl(el) }
125
125
  this.trackAfter("discarded", el)
126
126
  },
127
127
  onBeforeNodeDiscarded: (el) => {
@@ -143,6 +143,7 @@ export default class DOMPatch {
143
143
  onBeforeElUpdated: (fromEl, toEl) => {
144
144
  DOM.cleanChildNodes(toEl, phxUpdate)
145
145
  if(this.skipCIDSibling(toEl)){ return false }
146
+ if(DOM.isPhxSticky(fromEl)){ return false }
146
147
  if(DOM.isIgnored(fromEl, phxUpdate)){
147
148
  this.trackBefore("updated", fromEl, toEl)
148
149
  DOM.mergeAttrs(fromEl, toEl, {isIgnored: true})
@@ -211,7 +212,11 @@ export default class DOMPatch {
211
212
  if(pendingRemoves.length > 0){
212
213
  liveSocket.transitionRemoves(pendingRemoves)
213
214
  liveSocket.requestDOMUpdate(() => {
214
- pendingRemoves.forEach(el => el.remove())
215
+ pendingRemoves.forEach(el => {
216
+ let child = DOM.firstPhxChild(el)
217
+ if(child){ liveSocket.destroyViewByEl(child) }
218
+ el.remove()
219
+ })
215
220
  this.trackAfter("transitionsDiscarded", pendingRemoves)
216
221
  })
217
222
  }