@pacem/pacem-ui 2.0.0-kepler → 2.0.0-lyapunov

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 (54) hide show
  1. package/dist/browser/pacem-ui.js +116 -30
  2. package/dist/browser/pacem-ui.js.map +1 -1
  3. package/dist/browser/pacem-ui.min.js +2 -2
  4. package/dist/bundle/pacem-ui.min.mjs +42 -42
  5. package/dist/bundle/pacem-ui.mjs +109 -26
  6. package/dist/bundle/pacem-ui.mjs.map +2 -2
  7. package/dist/docs/pacem-ui.json +75 -0
  8. package/dist/esm/adapter.js +1 -1
  9. package/dist/esm/anchor.js +1 -1
  10. package/dist/esm/balloon.js +1 -1
  11. package/dist/esm/binder.js +1 -1
  12. package/dist/esm/blade.js +1 -1
  13. package/dist/esm/bottom-sheet.js +1 -1
  14. package/dist/esm/button.js +1 -1
  15. package/dist/esm/buttonset.js +1 -1
  16. package/dist/esm/calendar.js +1 -1
  17. package/dist/esm/collapse.js +1 -1
  18. package/dist/esm/dialog-abstractions.js +1 -1
  19. package/dist/esm/dialog.js +1 -1
  20. package/dist/esm/divider.js +1 -1
  21. package/dist/esm/icon.js +1 -1
  22. package/dist/esm/image.js +1 -1
  23. package/dist/esm/index-components-ui.js +1 -1
  24. package/dist/esm/index-components.js +1 -1
  25. package/dist/esm/index-iife.js +1 -1
  26. package/dist/esm/index.js +1 -1
  27. package/dist/esm/infinite-scroller.js +1 -1
  28. package/dist/esm/iterative.js +1 -1
  29. package/dist/esm/lightbox-abstractions.js +1 -1
  30. package/dist/esm/lightbox.js +1 -1
  31. package/dist/esm/loader.js +1 -1
  32. package/dist/esm/markdown-svc.js +1 -1
  33. package/dist/esm/markdown.js +1 -1
  34. package/dist/esm/marquee.js +1 -1
  35. package/dist/esm/media-query.js +1 -1
  36. package/dist/esm/menu.js +1 -1
  37. package/dist/esm/pager.js +1 -1
  38. package/dist/esm/picture.js +1 -1
  39. package/dist/esm/progressbar.js +1 -1
  40. package/dist/esm/sidebar.js +1 -1
  41. package/dist/esm/slideshow.js +1 -1
  42. package/dist/esm/social-twitter.js +1 -1
  43. package/dist/esm/sticky-header.js +1 -1
  44. package/dist/esm/tabs.js +1 -1
  45. package/dist/esm/ticker.js +1 -1
  46. package/dist/esm/toast.js +1 -1
  47. package/dist/esm/toc.js +1 -1
  48. package/dist/esm/tuner.js +1 -1
  49. package/dist/esm/types.js +1 -1
  50. package/dist/esm/vibration.js +1 -1
  51. package/dist/esm/view.js +116 -31
  52. package/dist/esm/window.js +1 -1
  53. package/package.json +1 -1
  54. package/typings/index.d.ts +33 -0
package/dist/esm/view.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @pacem/pacem-ui v2.0.0-kepler (https://js.pacem.it)
2
+ * @pacem/pacem-ui v2.0.0-lyapunov (https://js.pacem.it)
3
3
  * Pacem (https://pacem.it)
4
4
  * Licensed under Apache-2.0
5
5
  */
@@ -67,9 +67,95 @@ let PacemViewElement = class PacemViewElement extends PacemEventTarget {
67
67
  this._manageRef();
68
68
  }
69
69
  }
70
+ disconnectedCallback() {
71
+ this._dispose(this.url);
72
+ super.disconnectedCallback();
73
+ }
70
74
  _isReference(url) {
71
75
  return url instanceof HTMLElement || (typeof url === 'string' && url.trim().startsWith('#'));
72
76
  }
77
+ /**
78
+ * Resolves a reference source to its element, as {@link _manageRef} does: the element itself, or the
79
+ * `<template>` a `#id` string points to; `null` for anything else.
80
+ */
81
+ _resolveRef(source) {
82
+ if (source instanceof HTMLElement) {
83
+ return source;
84
+ }
85
+ if (typeof source !== 'string' || !this._isReference(source)) {
86
+ return null;
87
+ }
88
+ return document.querySelector('template' + source);
89
+ }
90
+ /**
91
+ * Whether `url` is the source of the initial content ({@link initialContentUrl}): urls match by their string,
92
+ * references by the element they resolve to. Any other source consumes it.
93
+ */
94
+ _isInitialContent(url) {
95
+ const initial = this.initialContentUrl;
96
+ if (Utils.isNull(initial)) {
97
+ return false;
98
+ }
99
+ let matches = false;
100
+ if (!this._isReference(url)) {
101
+ matches = typeof url === 'string' && url === initial;
102
+ }
103
+ else if (this._isReference(initial)) {
104
+ const target = this._resolveRef(url);
105
+ matches = !Utils.isNull(target) && target === this._resolveRef(initial);
106
+ }
107
+ if (!matches) {
108
+ this.initialContentUrl = null;
109
+ }
110
+ return matches;
111
+ }
112
+ /**
113
+ * Keeps the initial content: announced once, as a fresh content would be (a reference may be managed twice on
114
+ * activation: the second time, it was announced already).
115
+ */
116
+ _adoptInitialContent() {
117
+ clearTimeout(this._fetchHandle);
118
+ if (this.#renderVersion > 0) {
119
+ return;
120
+ }
121
+ this._render(null);
122
+ }
123
+ /**
124
+ * The rendering pipeline of every content: a new version, `prerender`, the content on the next frame, `render`
125
+ * (dropped when newer content came meanwhile).
126
+ * @param fill Writes the new content (the former one is cleared first); `null` keeps the content already there
127
+ * (the initial content), which also leaves {@link initialContentUrl} in place.
128
+ * @param waitForAnimation Whether `render` waits for the view's css transition (see `fetching`) instead of
129
+ * following the content right away.
130
+ */
131
+ _render(fill, waitForAnimation = false) {
132
+ cancelAnimationFrame(this._renderHandle);
133
+ const version = ++this.#renderVersion;
134
+ const replacing = !Utils.isNull(fill);
135
+ if (replacing) {
136
+ this.initialContentUrl = null;
137
+ // this way, `this._container.innerHTML = ''` instruction will eventually let the page "scroll up"...
138
+ this.innerHTML = '';
139
+ }
140
+ this._dispatchPrerender();
141
+ this._renderHandle = requestAnimationFrame(() => {
142
+ if (replacing) {
143
+ fill();
144
+ }
145
+ if (!waitForAnimation) {
146
+ this._dispatchRenderOf(version);
147
+ return;
148
+ }
149
+ Utils.addAnimationEndCallback(this, () => this._dispatchRenderOf(version), ANIM_TIMEOUT);
150
+ });
151
+ }
152
+ /** Dispatches `render` for the content of `version`, unless newer content superseded it. */
153
+ _dispatchRenderOf(version) {
154
+ if (version !== this.#renderVersion) {
155
+ return;
156
+ }
157
+ this._dispatchRender();
158
+ }
73
159
  _dispose(url) {
74
160
  if (url instanceof Components.PacemTemplateProxyElement) {
75
161
  url.removeEventListener('templatechange', this._templateChangeHandler);
@@ -80,26 +166,37 @@ let PacemViewElement = class PacemViewElement extends PacemEventTarget {
80
166
  return;
81
167
  }
82
168
  const debounce = this.debounce || 0, url = this.url;
83
- ;
84
169
  if (this._isReference(url)) {
85
170
  // <template>-based
86
171
  clearTimeout(this._fetchHandle);
87
172
  this._fetchHandle = setTimeout((() => this._manageRef()), debounce);
88
173
  }
89
174
  else if (typeof url === 'string' && !Utils.isNullOrEmpty(url)) {
90
- // url-based
175
+ // url-based (but the initial content: already there)
176
+ if (this._isInitialContent(url)) {
177
+ this._adoptInitialContent();
178
+ return;
179
+ }
91
180
  this.fetching = true;
92
181
  clearTimeout(this._fetchHandle);
93
182
  this._fetchHandle = setTimeout((() => this._manageUrl(url)), debounce);
94
183
  }
95
184
  else /* might be a reset */ {
96
185
  this.innerHTML = '';
186
+ this.initialContentUrl = null;
97
187
  }
98
188
  }
99
189
  _manageRef() {
100
- const url = this.url, tmpl = url instanceof HTMLElement ? url : document.querySelector('template' + url);
190
+ const url = this.url, tmpl = this._resolveRef(url);
191
+ // (a proxy keeps notifying its template changes, the initial content too: listening twice is a no-op)
101
192
  if (tmpl instanceof Components.PacemTemplateProxyElement) {
102
193
  tmpl.addEventListener('templatechange', this._templateChangeHandler, false);
194
+ }
195
+ if (this._isInitialContent(url)) {
196
+ this._adoptInitialContent();
197
+ return;
198
+ }
199
+ if (tmpl instanceof Components.PacemTemplateProxyElement) {
103
200
  this._setTmpl(tmpl.target);
104
201
  }
105
202
  else if (tmpl instanceof HTMLTemplateElement) {
@@ -113,18 +210,13 @@ let PacemViewElement = class PacemViewElement extends PacemEventTarget {
113
210
  }
114
211
  }
115
212
  _setTmpl(tmpl) {
116
- cancelAnimationFrame(this._renderHandle);
117
- this.#renderVersion++;
118
- // this way, `this._container.innerHTML = ''` instruction will eventually let the page "scroll up"...
119
- this.innerHTML = '';
120
- this._dispatchPrerender();
121
- this._renderHandle = requestAnimationFrame(() => {
122
- if (Utils.isNull(tmpl)) {
123
- this.log(Logging.LogLevel.Error, `Template element not found.`);
124
- return;
125
- }
126
- this.appendChild(tmpl.cloneNode(true).content);
127
- this._dispatchRender();
213
+ if (Utils.isNull(tmpl)) {
214
+ this.log(Logging.LogLevel.Error, `Template element not found.`);
215
+ return;
216
+ }
217
+ this._render(() => {
218
+ const clone = tmpl.cloneNode(true);
219
+ this.appendChild(clone.content);
128
220
  });
129
221
  }
130
222
  #aborter;
@@ -185,25 +277,15 @@ let PacemViewElement = class PacemViewElement extends PacemEventTarget {
185
277
  });
186
278
  }
187
279
  _manageResult(result) {
188
- // this way, `this._container.innerHTML = ''` instruction will eventually let the page "scroll up"...
189
- cancelAnimationFrame(this._renderHandle);
190
- const version = ++this.#renderVersion;
191
280
  this.scrollTo({ top: 0, left: 0, behavior: 'instant' });
192
- this.innerHTML = '';
193
- this._dispatchPrerender();
194
- this._renderHandle = requestAnimationFrame(() => {
281
+ // setting fetching to `false` triggers a css class change that could/should cause a css transition to happen:
282
+ // `render` waits for it
283
+ // TODO: manage to switch to native in a near future (https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API or https://youtu.be/oDcb3fvtETs)
284
+ this._render(() => {
195
285
  this.innerHTML = result;
196
286
  this.fetching = false;
197
287
  this.progress = Number.NaN;
198
- // setting fetching to `false` triggers a css class change that could/should cause a css transition to happen
199
- // TODO: manage to switch to native in a near future (https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API or https://youtu.be/oDcb3fvtETs)
200
- Utils.addAnimationEndCallback(this, () => {
201
- if (version !== this.#renderVersion) {
202
- return;
203
- }
204
- this._dispatchRender();
205
- }, ANIM_TIMEOUT);
206
- });
288
+ }, true);
207
289
  }
208
290
  #resizeHandle;
209
291
  _dispatchRender() {
@@ -240,6 +322,9 @@ __decorate([
240
322
  __decorate([
241
323
  Watch({ emit: false, converter: PropertyConverters.Number })
242
324
  ], PacemViewElement.prototype, "debounce", void 0);
325
+ __decorate([
326
+ Watch({ emit: false, converter: ElementOrStringPropertyConverter })
327
+ ], PacemViewElement.prototype, "initialContentUrl", void 0);
243
328
  PacemViewElement = __decorate([
244
329
  CustomElement({
245
330
  tagName: P + '-view'
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @pacem/pacem-ui v2.0.0-kepler (https://js.pacem.it)
2
+ * @pacem/pacem-ui v2.0.0-lyapunov (https://js.pacem.it)
3
3
  * Pacem (https://pacem.it)
4
4
  * Licensed under Apache-2.0
5
5
  */
package/package.json CHANGED
@@ -25,7 +25,7 @@
25
25
  "types": "./typings/index.d.ts"
26
26
  }
27
27
  },
28
- "version": "2.0.0-kepler",
28
+ "version": "2.0.0-lyapunov",
29
29
  "author": {
30
30
  "name": "Pacem",
31
31
  "url": "https://pacem.it"
@@ -1279,11 +1279,44 @@ declare class PacemViewElement extends PacemEventTarget {
1279
1279
  followRedirects: boolean;
1280
1280
  /** use it to ensure animation */
1281
1281
  debounce: number;
1282
+ /**
1283
+ * Gets or sets the source (same shapes as {@link url}) of the content the view starts with, i.e. already in its
1284
+ * markup (e.g. server-rendered): the first `url` matching it is not loaded, the content is kept and announced with
1285
+ * the usual `prerender`/`render` events. One-shot: consumed by any other source or by any rendering.
1286
+ */
1287
+ initialContentUrl: string | HTMLTemplateElement | Components_2.PacemTemplateProxyElement;
1282
1288
  private _fetchHandle;
1283
1289
  private _renderHandle;
1284
1290
  propertyChangedCallback(name: string, old: any, val: any, first?: boolean): void;
1285
1291
  viewActivatedCallback(): void;
1292
+ disconnectedCallback(): void;
1286
1293
  private _isReference;
1294
+ /**
1295
+ * Resolves a reference source to its element, as {@link _manageRef} does: the element itself, or the
1296
+ * `<template>` a `#id` string points to; `null` for anything else.
1297
+ */
1298
+ private _resolveRef;
1299
+ /**
1300
+ * Whether `url` is the source of the initial content ({@link initialContentUrl}): urls match by their string,
1301
+ * references by the element they resolve to. Any other source consumes it.
1302
+ */
1303
+ private _isInitialContent;
1304
+ /**
1305
+ * Keeps the initial content: announced once, as a fresh content would be (a reference may be managed twice on
1306
+ * activation: the second time, it was announced already).
1307
+ */
1308
+ private _adoptInitialContent;
1309
+ /**
1310
+ * The rendering pipeline of every content: a new version, `prerender`, the content on the next frame, `render`
1311
+ * (dropped when newer content came meanwhile).
1312
+ * @param fill Writes the new content (the former one is cleared first); `null` keeps the content already there
1313
+ * (the initial content), which also leaves {@link initialContentUrl} in place.
1314
+ * @param waitForAnimation Whether `render` waits for the view's css transition (see `fetching`) instead of
1315
+ * following the content right away.
1316
+ */
1317
+ private _render;
1318
+ /** Dispatches `render` for the content of `version`, unless newer content superseded it. */
1319
+ private _dispatchRenderOf;
1287
1320
  private _templateChangeHandler;
1288
1321
  private _dispose;
1289
1322
  private _manage;