phoenix_live_view 1.2.0-rc.2 → 1.2.0

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.
Files changed (27) hide show
  1. package/README.md +5 -5
  2. package/assets/js/phoenix_live_view/README.md +3 -0
  3. package/assets/js/phoenix_live_view/{aria.js → aria.ts} +18 -10
  4. package/assets/js/phoenix_live_view/{browser.js → browser.ts} +12 -8
  5. package/assets/js/phoenix_live_view/{dom.js → dom.ts} +107 -34
  6. package/assets/js/phoenix_live_view/{dom_patch.js → dom_patch.ts} +187 -124
  7. package/assets/js/phoenix_live_view/{dom_post_morph_restorer.js → dom_post_morph_restorer.ts} +17 -2
  8. package/assets/js/phoenix_live_view/{element_ref.js → element_ref.ts} +17 -11
  9. package/assets/js/phoenix_live_view/entry_uploader.js +4 -4
  10. package/assets/js/phoenix_live_view/{hooks.js → hooks.ts} +108 -91
  11. package/assets/js/phoenix_live_view/index.ts +14 -301
  12. package/assets/js/phoenix_live_view/js.js +2 -1
  13. package/assets/js/phoenix_live_view/js_commands.ts +12 -9
  14. package/assets/js/phoenix_live_view/{live_socket.js → live_socket.ts} +582 -114
  15. package/assets/js/phoenix_live_view/live_uploader.js +1 -1
  16. package/assets/js/phoenix_live_view/rendered.js +3 -0
  17. package/assets/js/phoenix_live_view/{utils.js → utils.ts} +35 -6
  18. package/assets/js/phoenix_live_view/{view.js → view.ts} +221 -110
  19. package/assets/js/phoenix_live_view/view_hook.ts +92 -32
  20. package/package.json +5 -2
  21. package/priv/static/phoenix_live_view.cjs.js +577 -314
  22. package/priv/static/phoenix_live_view.cjs.js.map +4 -4
  23. package/priv/static/phoenix_live_view.esm.js +577 -314
  24. package/priv/static/phoenix_live_view.esm.js.map +4 -4
  25. package/priv/static/phoenix_live_view.js +584 -314
  26. package/priv/static/phoenix_live_view.min.js +7 -7
  27. /package/assets/js/phoenix_live_view/{constants.js → constants.ts} +0 -0
@@ -91,7 +91,7 @@ export default class LiveUploader {
91
91
  DOM.updatePrivate(inputEl, "files", [], (existing) =>
92
92
  existing.concat(newFiles),
93
93
  );
94
- inputEl.value = null;
94
+ inputEl.value = "";
95
95
  } else {
96
96
  // Reset inputEl files to align output with programmatic changes (i.e. drag and drop)
97
97
  if (dataTransfer && dataTransfer.files.length > 0) {
@@ -119,6 +119,7 @@ export const modifyRoot = (html, attrs, clearInnerHTML) => {
119
119
  return [newHTML, beforeTag, afterTag];
120
120
  };
121
121
 
122
+ /** @internal */
122
123
  export default class Rendered {
123
124
  static extract(diff) {
124
125
  const { [REPLY]: reply, [EVENTS]: events, [TITLE]: title } = diff;
@@ -223,6 +224,8 @@ export default class Rendered {
223
224
  if (isCid(scid)) {
224
225
  let tdiff;
225
226
 
227
+ // @ts-expect-error: isCid also allows strings, but the diff always uses numbers
228
+ // TODO: revisit isCid and consider differentiating cid strings from DOM and cid numbers from diffs / internal usage
226
229
  if (scid > 0) {
227
230
  tdiff = this.cachedFindComponent(scid, newc[scid], oldc, newc, cache);
228
231
  } else {
@@ -2,9 +2,33 @@ import { PHX_VIEW_SELECTOR } from "./constants";
2
2
 
3
3
  import EntryUploader from "./entry_uploader";
4
4
 
5
- export const logError = (msg, obj) => console.error && console.error(msg, obj);
5
+ export const logError = (msg, obj?) => console.error && console.error(msg, obj);
6
6
 
7
- export const isCid = (cid) => {
7
+ // Live navigation can only stay within the current origin, as it joins the
8
+ // target over the existing socket. A full URL to a different origin (or a
9
+ // non-http(s) scheme, which resolves to an opaque "null" origin) is a
10
+ // programming error, so we fail loudly instead of attempting a broken join.
11
+ export const ensureSameOrigin = (
12
+ href: string,
13
+ kind: "patch" | "navigate",
14
+ ): void => {
15
+ let url: URL;
16
+ try {
17
+ url = new URL(href, window.location.href);
18
+ } catch {
19
+ throw new Error(
20
+ `expected ${kind} destination to be a valid URL, got: ${href}`,
21
+ );
22
+ }
23
+ if (url.origin !== window.location.origin) {
24
+ throw new Error(
25
+ `cannot ${kind} to "${href}" because its origin does not match the ` +
26
+ `current origin "${window.location.origin}". Use window.location directly for cross-origin navigation.`,
27
+ );
28
+ }
29
+ };
30
+
31
+ export const isCid = (cid): cid is number | string => {
8
32
  const type = typeof cid;
9
33
  return type === "number" || (type === "string" && /^(0|[1-9]\d*)$/.test(cid));
10
34
  };
@@ -47,7 +71,7 @@ export const debug = (view, kind, msg, obj) => {
47
71
  };
48
72
 
49
73
  // wraps value in closure or returns closure
50
- export const closure = (val) =>
74
+ export const closure = (val?) =>
51
75
  typeof val === "function"
52
76
  ? val
53
77
  : function () {
@@ -58,12 +82,17 @@ export const clone = (obj) => {
58
82
  return JSON.parse(JSON.stringify(obj));
59
83
  };
60
84
 
61
- export const closestPhxBinding = (el, binding, borderEl) => {
85
+ export const closestPhxBinding = (
86
+ startEl: Element,
87
+ binding: string,
88
+ borderEl?: Element,
89
+ ) => {
90
+ let el: Element | null = startEl;
62
91
  do {
63
- if (el.matches(`[${binding}]`) && !el.disabled) {
92
+ if (el.matches(`[${binding}]`) && !("disabled" in el && el.disabled)) {
64
93
  return el;
65
94
  }
66
- el = el.parentElement || el.parentNode;
95
+ el = el.parentElement;
67
96
  } while (
68
97
  el !== null &&
69
98
  el.nodeType === 1 &&