@webqit/webflo 0.20.39 → 0.20.41

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/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "vanila-javascript"
13
13
  ],
14
14
  "homepage": "https://webqit.io/tooling/webflo",
15
- "version": "0.20.39",
15
+ "version": "0.20.41",
16
16
  "license": "MIT",
17
17
  "repository": {
18
18
  "type": "git",
@@ -69,11 +69,14 @@ export class DeviceViewport {
69
69
  #render() {
70
70
  const state = this.peek();
71
71
  const viewportDirectives = [];
72
- const activeKeys = new Set(Object.keys(state).filter(k => !k.startsWith('_')));
72
+ const activeKeys = new Set(Object.keys(state).filter(k => k !== 'id' && !k.startsWith('_')));
73
73
 
74
74
  // 1. Handle Title
75
75
  if ('title' in state) {
76
- document.title = state.title || '';
76
+ const val = state.title || '';
77
+ if (document.title !== val) {
78
+ document.title = val;
79
+ }
77
80
  activeKeys.delete('title');
78
81
  }
79
82
 
@@ -118,31 +121,27 @@ export class DeviceViewport {
118
121
  });
119
122
 
120
123
  const vContent = viewportDirectives.join(', ');
121
- const vEl = this.#elements.viewport || (vContent ? this.#getOrCreate('viewport') : null);
122
- if (vEl) {
123
- vEl.setAttribute('content', vContent);
124
- if (!vContent && this.#ownedElements.has(vEl)) {
125
- vEl.remove();
126
- delete this.#elements.viewport;
127
- }
128
- }
124
+ this.#setAttr('viewport', vContent);
129
125
  }
130
126
 
131
- #setAttr(jsKey, val, media = null) {
132
- const cacheKey = media ? `${jsKey}-${media}` : jsKey;
127
+ #setAttr(jsKey, val, media = '') {
133
128
  const config = this.#specials[jsKey];
129
+ const attrName = config?.type === 'link' ? 'href' : 'content';
134
130
 
135
131
  if (val !== undefined && val !== null) {
136
132
  const el = this.#getOrCreate(jsKey, media);
137
- el.setAttribute(config.type === 'link' ? 'href' : 'content', val);
133
+ if (el.getAttribute(attrName) !== val) {
134
+ el.setAttribute(attrName, val);
135
+ }
138
136
  } else {
137
+ const cacheKey = media ? `${jsKey}-${media}` : jsKey;
139
138
  const el = this.#elements[cacheKey];
140
139
  if (el) {
141
140
  if (this.#ownedElements.has(el)) {
142
141
  el.remove();
143
142
  delete this.#elements[cacheKey];
144
- } else {
145
- el.setAttribute(config.type === 'link' ? 'href' : 'content', '');
143
+ } else if (el.getAttribute(attrName) !== '') {
144
+ el.setAttribute(attrName, '');
146
145
  }
147
146
  }
148
147
  }
@@ -150,7 +149,7 @@ export class DeviceViewport {
150
149
 
151
150
  #parseViewport = (c) => Object.fromEntries(c.split(',').filter(Boolean).map(s => {
152
151
  const [k, v] = s.split('=').map(p => p.trim());
153
- return [k.replace(/-([a-z])/g, g => g.toUpperCase()), v || true];
152
+ return [k.replace(/-([a-z])/g, g => g[1].toUpperCase()), v || true];
154
153
  }));
155
154
 
156
155
  push(id, config) {
@@ -160,13 +159,15 @@ export class DeviceViewport {
160
159
  this.#scheduleRender();
161
160
  }
162
161
 
163
- pop(id) {
164
- if (!id) throw new Error("pop() requires a target ID");
165
- const idx = this.#stack.findIndex(e => e.id === id);
166
- if (idx > 0) { // Never pop the initial state at index 0
167
- this.#stack.splice(idx, 1);
168
- this.#scheduleRender();
169
- }
162
+ pop(...ids) {
163
+ if (!ids.length) throw new Error("pop() requires a target ID");
164
+ ids.forEach((id) => {
165
+ const idx = this.#stack.findIndex(e => e.id === id);
166
+ if (idx > 0) { // Never pop the initial state at index 0
167
+ this.#stack.splice(idx, 1);
168
+ }
169
+ });
170
+ this.#scheduleRender();
170
171
  }
171
172
 
172
173
  peek() { return this.#stack[this.#stack.length - 1]; }