@preference-sl/pref-viewer 2.2.0 → 2.3.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.
- package/package.json +1 -1
- package/src/index.js +57 -37
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -71,6 +71,7 @@ class PrefViewer extends HTMLElement {
|
|
|
71
71
|
// modelUrl might be provided via attribute before connectedCallback
|
|
72
72
|
this.modelUrl = null;
|
|
73
73
|
this._hasInitialized = false;
|
|
74
|
+
this._pluginHookSetup = false; // Track if we've already set up the plugin hook
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
static get observedAttributes() {
|
|
@@ -91,6 +92,13 @@ class PrefViewer extends HTMLElement {
|
|
|
91
92
|
|
|
92
93
|
connectedCallback() {
|
|
93
94
|
console.log("PrefViewer: connectedCallback");
|
|
95
|
+
|
|
96
|
+
// Set up the plugin hook ONCE globally before any other initialization
|
|
97
|
+
if (!this._pluginHookSetup) {
|
|
98
|
+
this._setupUrlPreprocessing();
|
|
99
|
+
this._pluginHookSetup = true;
|
|
100
|
+
}
|
|
101
|
+
|
|
94
102
|
// 1) Determine modelUrl now that element is connected
|
|
95
103
|
if (!this.hasAttribute("model")) {
|
|
96
104
|
this.modelUrl = new URL("./models/window.gltf", import.meta.url).href;
|
|
@@ -113,7 +121,47 @@ class PrefViewer extends HTMLElement {
|
|
|
113
121
|
disconnectedCallback() {
|
|
114
122
|
console.log("PrefViewer: disconnectedCallback - disposing engine");
|
|
115
123
|
this._disposeEngine();
|
|
116
|
-
|
|
124
|
+
if (this._onWindowResize) {
|
|
125
|
+
window.removeEventListener("resize", this._onWindowResize);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ====== URL Preprocessing Setup ======
|
|
130
|
+
_setupUrlPreprocessing() {
|
|
131
|
+
console.log("PrefViewer: Setting up URL preprocessing hook");
|
|
132
|
+
|
|
133
|
+
const transformUrl = (url) => {
|
|
134
|
+
// a) If the loader already prepended "blob:…", strip it out.
|
|
135
|
+
const stripped = url.replace(
|
|
136
|
+
/^blob:(?:http|https|file):\/\/[^\/]+\/(.+)/i,
|
|
137
|
+
"$1"
|
|
138
|
+
);
|
|
139
|
+
// b) Normalize backslashes "\" → forward slashes "/"
|
|
140
|
+
const fixedSlashes = stripped.replace(/\\/g, "/");
|
|
141
|
+
console.log(
|
|
142
|
+
`PrefViewer: preprocessUrl received "${url}", stripped to "${stripped}", normalized to "${fixedSlashes}"`
|
|
143
|
+
);
|
|
144
|
+
// c) If it now starts with "http://" or "https://", return it as an absolute URL:
|
|
145
|
+
if (/^https?:\/\//i.test(fixedSlashes)) {
|
|
146
|
+
console.log(`PrefViewer: preprocessUrl returning absolute URL "${fixedSlashes}"`);
|
|
147
|
+
return fixedSlashes;
|
|
148
|
+
}
|
|
149
|
+
// d) Otherwise, return the relative path
|
|
150
|
+
console.log(`PrefViewer: preprocessUrl returning relative URL "${fixedSlashes}"`);
|
|
151
|
+
return fixedSlashes;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
SceneLoader.OnPluginActivatedObservable.add((plugin) => {
|
|
155
|
+
console.log(`PrefViewer: Plugin activated - ${plugin.name}`);
|
|
156
|
+
if (plugin.name === "gltf" || plugin.name === "gltf2") {
|
|
157
|
+
// Support both sync and async preprocessing
|
|
158
|
+
plugin.preprocessUrl = transformUrl;
|
|
159
|
+
if (typeof plugin.preprocessUrlAsync === 'function' || plugin.preprocessUrlAsync === undefined) {
|
|
160
|
+
plugin.preprocessUrlAsync = (url) => Promise.resolve(transformUrl(url));
|
|
161
|
+
}
|
|
162
|
+
console.log("PrefViewer: URL preprocessing hooks set up for GLTF plugin");
|
|
163
|
+
}
|
|
164
|
+
});
|
|
117
165
|
}
|
|
118
166
|
|
|
119
167
|
// ====== Private setup methods ======
|
|
@@ -147,56 +195,28 @@ class PrefViewer extends HTMLElement {
|
|
|
147
195
|
this.scene = new Scene(this.engine);
|
|
148
196
|
this.scene.clearColor = new Color4(1, 1, 1, 1);
|
|
149
197
|
|
|
150
|
-
// 2)
|
|
151
|
-
// get stripped off before we check for an absolute "https://".
|
|
152
|
-
console.log("PrefViewer: Adding preprocessUrl hook");
|
|
153
|
-
SceneLoader.OnPluginActivatedObservable.add((plugin) => {
|
|
154
|
-
console.log(`PrefViewer: Plugin activated - ${plugin.name}`);
|
|
155
|
-
if (plugin.name === "gltf" || plugin.name === "gltf2") {
|
|
156
|
-
plugin.preprocessUrl = (url) => {
|
|
157
|
-
// a) If the loader already prepended "blob:…", strip it out.
|
|
158
|
-
// Regex explanation: ^blob:(?:file|https?|ftp):\/\/[^\/]+\/(.*)
|
|
159
|
-
// basically removes the entire "blob:http://localhost:3000/" prefix.
|
|
160
|
-
const stripped = url.replace(
|
|
161
|
-
/^blob:(?:http|https|file):\/\/[^\/]+\/(.+)/i,
|
|
162
|
-
"$1"
|
|
163
|
-
);
|
|
164
|
-
// b) Normalize backslashes "\" → forward slashes "/"
|
|
165
|
-
const fixedSlashes = stripped.replace(/\\/g, "/");
|
|
166
|
-
console.log(
|
|
167
|
-
`PrefViewer: preprocessUrl received "${url}", stripped to "${stripped}", normalized to "${fixedSlashes}"`
|
|
168
|
-
);
|
|
169
|
-
// c) If it now starts with "http://" or "https://", return it as an absolute URL:
|
|
170
|
-
if (/^https?:\/\//i.test(fixedSlashes)) {
|
|
171
|
-
console.log(`PrefViewer: preprocessUrl returning absolute URL "${fixedSlashes}"`);
|
|
172
|
-
return fixedSlashes;
|
|
173
|
-
}
|
|
174
|
-
// d) Otherwise, return the relative path (Babylon will resolve it relative to the blob if needed)
|
|
175
|
-
console.log(`PrefViewer: preprocessUrl returning relative URL "${fixedSlashes}"`);
|
|
176
|
-
return fixedSlashes;
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
// 3) Create camera and lights
|
|
198
|
+
// 2) Create camera and lights
|
|
182
199
|
console.log("PrefViewer: _createCamera and _createLights");
|
|
183
200
|
this._createCamera();
|
|
184
201
|
this._createLights();
|
|
185
202
|
|
|
186
|
-
//
|
|
203
|
+
// 3) Hook up input/event handlers (e.g. wheel-to-zoom)
|
|
187
204
|
console.log("PrefViewer: _setupEventListeners");
|
|
188
205
|
this._setupEventListeners();
|
|
189
206
|
|
|
190
|
-
//
|
|
207
|
+
// 4) Start Babylon's render loop
|
|
191
208
|
console.log("PrefViewer: Starting render loop");
|
|
192
209
|
this.engine.runRenderLoop(() => {
|
|
193
210
|
if (this.scene) {
|
|
194
211
|
this.scene.render();
|
|
195
212
|
}
|
|
196
213
|
});
|
|
214
|
+
|
|
197
215
|
this._onWindowResize = () => {
|
|
198
216
|
console.log("PrefViewer: Window resized - calling engine.resize()");
|
|
199
|
-
this.engine
|
|
217
|
+
if (this.engine) {
|
|
218
|
+
this.engine.resize();
|
|
219
|
+
}
|
|
200
220
|
};
|
|
201
221
|
window.addEventListener("resize", this._onWindowResize);
|
|
202
222
|
}
|
|
@@ -260,7 +280,7 @@ class PrefViewer extends HTMLElement {
|
|
|
260
280
|
return;
|
|
261
281
|
}
|
|
262
282
|
|
|
263
|
-
// Dispose previous meshes so we don
|
|
283
|
+
// Dispose previous meshes so we don't accumulate them
|
|
264
284
|
this._disposePreviousMeshes();
|
|
265
285
|
|
|
266
286
|
try {
|