@roomle/embedding-lib 1.0.0-alpha.1
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/.releaserc.json +60 -0
- package/README.md +13 -0
- package/docs/md/web/embedding/CHANGELOG.md +2121 -0
- package/index.d.ts +72 -0
- package/package.json +35 -0
- package/roomle-embedding-lib.es.js +431 -0
- package/roomle-embedding-lib.es.min.js +8 -0
- package/roomle-embedding-lib.umd.js +8 -0
- package/roomle-embedding-lib.umd.min.js +8 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { default as default_2 } from '@roomle/web-sdk/lib/definitions/planner-core/src/roomle-planner';
|
|
2
|
+
import { default as default_3 } from '@roomle/web-sdk/lib/definitions/configurator-core/src/services/configurator-ui-callback';
|
|
3
|
+
import { default as default_4 } from '@roomle/web-sdk/lib/definitions/configurator-core/src/roomle-configurator';
|
|
4
|
+
import { default as default_5 } from '@roomle/web-sdk/lib/definitions/glb-viewer-core/src/roomle-glb-viewer';
|
|
5
|
+
import { ExposedAnalyticsCallbacks } from '../../../src/configurator/embedding/exposed-analytics-callbacks';
|
|
6
|
+
import { ExposedApi } from '../../../src/configurator/embedding/exposed-api';
|
|
7
|
+
import { GlobalCallback } from '@roomle/web-sdk/lib/definitions/common-core/src/services/global-callback';
|
|
8
|
+
import { UiInitData } from '../../../src/configurator/embedding/types';
|
|
9
|
+
|
|
10
|
+
declare type RoomleConfiguratorApi = RoomleEmbeddingApi<default_4, default_3>;
|
|
11
|
+
|
|
12
|
+
declare class RoomleEmbeddingApi<SdkType, SdkCallbacks> implements RoomleEmbeddingApiKeys {
|
|
13
|
+
static createPlanner(configuratorId: string, container: HTMLElement, initData: UiInitData): Promise<RoomlePlannerApi>;
|
|
14
|
+
/**
|
|
15
|
+
* Method to create a new instance of a Roomle Configurator
|
|
16
|
+
* @param configuratorId the id which identifies your configurator, you will get this ID from your Roomle Contact Person
|
|
17
|
+
* @param container DOM container in which the configurator should be placed
|
|
18
|
+
* @param initData settings with which the configurator should be started
|
|
19
|
+
*/
|
|
20
|
+
static createConfigurator(configuratorId: string, container: HTMLElement, initData: UiInitData): Promise<RoomleConfiguratorApi>;
|
|
21
|
+
/**
|
|
22
|
+
* Method to create a new instance of a Roomle Configurator
|
|
23
|
+
* @deprecated please use "createConfigurator"
|
|
24
|
+
* @param configuratorId the id which identifies your configurator, you will get this ID from your Roomle Contact Person
|
|
25
|
+
* @param container DOM container in which the configurator should be placed
|
|
26
|
+
* @param initData settings with which the configurator should be started
|
|
27
|
+
*/
|
|
28
|
+
static create(configuratorId: string, container: HTMLElement, initData: UiInitData): Promise<RoomleConfiguratorApi>;
|
|
29
|
+
/**
|
|
30
|
+
* Method to create a new instance of a Roomle Viewer
|
|
31
|
+
* @param configuratorId the id which identifies your configurator, you will get this ID from your Roomle Contact Person
|
|
32
|
+
* @param container DOM container in which the configurator should be placed
|
|
33
|
+
* @param initData settings with which the configurator should be started
|
|
34
|
+
*/
|
|
35
|
+
static createViewer(configuratorId: string, container: HTMLElement, initData: UiInitData): Promise<RoomleViewerApi>;
|
|
36
|
+
private static _create;
|
|
37
|
+
ui: ExposedApi;
|
|
38
|
+
extended: SdkType;
|
|
39
|
+
analytics: {
|
|
40
|
+
callbacks: ExposedAnalyticsCallbacks;
|
|
41
|
+
};
|
|
42
|
+
global: {
|
|
43
|
+
callbacks: GlobalCallback;
|
|
44
|
+
};
|
|
45
|
+
private _waitForIframe;
|
|
46
|
+
private _container;
|
|
47
|
+
private _messageHandler;
|
|
48
|
+
private _configuratorSettings;
|
|
49
|
+
private _initData;
|
|
50
|
+
private _iframe;
|
|
51
|
+
private constructor();
|
|
52
|
+
teardown(): void;
|
|
53
|
+
private _createIframe;
|
|
54
|
+
private _onResize;
|
|
55
|
+
private _onUseFullPage;
|
|
56
|
+
private _onBackToWebsite;
|
|
57
|
+
private _executeMessage;
|
|
58
|
+
}
|
|
59
|
+
export default RoomleEmbeddingApi;
|
|
60
|
+
|
|
61
|
+
declare interface RoomleEmbeddingApiKeys {
|
|
62
|
+
extended: any;
|
|
63
|
+
ui: any;
|
|
64
|
+
analytics: any;
|
|
65
|
+
global: any;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
declare type RoomlePlannerApi = RoomleEmbeddingApi<default_2, default_3>;
|
|
69
|
+
|
|
70
|
+
declare type RoomleViewerApi = RoomleEmbeddingApi<default_5, default_3>;
|
|
71
|
+
|
|
72
|
+
export { }
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@roomle/embedding-lib",
|
|
3
|
+
"version": "1.0.0-alpha.1",
|
|
4
|
+
"description": "This is a small library which can be used to communicate with the Roomle Configurator",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./roomle-embedding-lib.umd.js",
|
|
7
|
+
"module": "./roomle-embedding-lib.es.js",
|
|
8
|
+
"browser": "./roomle-embedding-lib.es.js",
|
|
9
|
+
"types": "./index.d.ts",
|
|
10
|
+
"files": [
|
|
11
|
+
"./"
|
|
12
|
+
],
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"import": "./roomle-embedding-lib.es.js",
|
|
16
|
+
"require": "./roomle-embedding-lib.umd.js",
|
|
17
|
+
"types": "./index.d.ts"
|
|
18
|
+
},
|
|
19
|
+
"./min": {
|
|
20
|
+
"import": "./roomle-embedding-lib.es.min.js",
|
|
21
|
+
"require": "./roomle-embedding-lib.umd.min.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@roomle/web-sdk": "2.83.0-alpha.4"
|
|
26
|
+
},
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "git+https://github.com/roomle-build/npm-packages.git"
|
|
30
|
+
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"license": "MIT"
|
|
35
|
+
}
|
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
var M = Object.defineProperty;
|
|
2
|
+
var v = (t, e, s) => e in t ? M(t, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : t[e] = s;
|
|
3
|
+
var u = (t, e, s) => v(t, typeof e != "symbol" ? e + "" : e, s);
|
|
4
|
+
class P {
|
|
5
|
+
constructor(e, s, r, o) {
|
|
6
|
+
u(this, "_side");
|
|
7
|
+
// for better debugging (who handles message? iframe or website?)
|
|
8
|
+
u(this, "_incomingMessageBus");
|
|
9
|
+
u(this, "_outgoingMessageBus", null);
|
|
10
|
+
u(this, "_execMessage", null);
|
|
11
|
+
this._side = e, this._incomingMessageBus = s, this._outgoingMessageBus = r, this._execMessage = o, this._incomingMessageBus.addEventListener(
|
|
12
|
+
"message",
|
|
13
|
+
this._handleMessage.bind(this)
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
setOutgoingMessageBus(e) {
|
|
17
|
+
this._outgoingMessageBus = e;
|
|
18
|
+
}
|
|
19
|
+
setMessageExecution(e) {
|
|
20
|
+
this._execMessage = e;
|
|
21
|
+
}
|
|
22
|
+
sendMessage(e, s = []) {
|
|
23
|
+
return new Promise((r, o) => {
|
|
24
|
+
const n = new MessageChannel();
|
|
25
|
+
n.port1.onmessage = (a) => {
|
|
26
|
+
if (!a || !a.data)
|
|
27
|
+
return n.port1.close(), n.port2.close(), o(
|
|
28
|
+
new Error(
|
|
29
|
+
this._side + " received message but response can not be interpreted"
|
|
30
|
+
)
|
|
31
|
+
);
|
|
32
|
+
let l;
|
|
33
|
+
try {
|
|
34
|
+
l = JSON.parse(a.data);
|
|
35
|
+
} catch (d) {
|
|
36
|
+
return n.port1.close(), n.port2.close(), this._prepareError(d), o(d);
|
|
37
|
+
}
|
|
38
|
+
l.error ? o(l.error) : l.result !== void 0 ? r(l.result) : r(void 0), n.port1.close(), n.port2.close();
|
|
39
|
+
};
|
|
40
|
+
let i = "";
|
|
41
|
+
try {
|
|
42
|
+
i = JSON.stringify({ message: e, args: s });
|
|
43
|
+
} catch {
|
|
44
|
+
return o(
|
|
45
|
+
new Error(
|
|
46
|
+
this._side + ": can not create command because it is not JSON.stringify able"
|
|
47
|
+
)
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
if (!this._outgoingMessageBus)
|
|
51
|
+
return o(new Error(this._side + ": outgoing bus not set yet"));
|
|
52
|
+
this._outgoingMessageBus.postMessage(i, "*", [
|
|
53
|
+
n.port2
|
|
54
|
+
]);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
_handleMessage(e) {
|
|
58
|
+
const s = e.ports && Array.isArray(e.ports) && e.ports.length > 0 ? e.ports[0] : null;
|
|
59
|
+
if (e.data && s)
|
|
60
|
+
try {
|
|
61
|
+
const r = JSON.parse(e.data);
|
|
62
|
+
if (!this._execMessage)
|
|
63
|
+
return s.postMessage(
|
|
64
|
+
JSON.stringify({
|
|
65
|
+
error: this._side + " is not ready to handle messages"
|
|
66
|
+
})
|
|
67
|
+
);
|
|
68
|
+
Array.isArray(r.args) || (r.args = [r.args]);
|
|
69
|
+
const o = this._execMessage(r, e);
|
|
70
|
+
if (o === void 0)
|
|
71
|
+
return;
|
|
72
|
+
o.then(
|
|
73
|
+
(n = {}) => {
|
|
74
|
+
let i, a;
|
|
75
|
+
typeof n == "object" && n !== null && (i = n.error, a = n.result), i ? s.postMessage(
|
|
76
|
+
JSON.stringify({ error: i })
|
|
77
|
+
) : a !== void 0 ? s.postMessage(
|
|
78
|
+
JSON.stringify({ result: a })
|
|
79
|
+
) : s.postMessage(
|
|
80
|
+
JSON.stringify({ result: n })
|
|
81
|
+
);
|
|
82
|
+
},
|
|
83
|
+
(n) => {
|
|
84
|
+
s.postMessage(
|
|
85
|
+
JSON.stringify({
|
|
86
|
+
error: this._prepareError(n)
|
|
87
|
+
})
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
} catch (r) {
|
|
92
|
+
s.postMessage(
|
|
93
|
+
JSON.stringify({
|
|
94
|
+
error: this._prepareError(r)
|
|
95
|
+
})
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
_prepareError(e) {
|
|
100
|
+
if (typeof e == "string") {
|
|
101
|
+
const s = this._side + ": " + e;
|
|
102
|
+
return console.error(s), s;
|
|
103
|
+
}
|
|
104
|
+
return e.message = this._side + ": " + e.message, console.error(e), e.message;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const p = ".", E = {
|
|
108
|
+
REQUEST_BOOT: "requestBoot",
|
|
109
|
+
SETUP: "setup",
|
|
110
|
+
WEBSITE_READY: "websiteReady"
|
|
111
|
+
}, H = async (t, e) => {
|
|
112
|
+
if (typeof t != "string")
|
|
113
|
+
throw new Error(
|
|
114
|
+
'Configurator ID is not a string type: "' + typeof t + '"'
|
|
115
|
+
);
|
|
116
|
+
const s = e.customApiUrl ? e.customApiUrl : "https://api.roomle.com/v2", r = e.overrideTenant || 9, o = s + "/configurators/" + t, n = "roomle_portal_v2", i = "03-" + window.btoa((/* @__PURE__ */ new Date()).toISOString() + ";anonymous;" + n), a = () => {
|
|
117
|
+
const h = {
|
|
118
|
+
apiKey: n,
|
|
119
|
+
currentTenant: r,
|
|
120
|
+
locale: "en",
|
|
121
|
+
language: "en",
|
|
122
|
+
device: 1,
|
|
123
|
+
token: i,
|
|
124
|
+
platform: "web"
|
|
125
|
+
};
|
|
126
|
+
return new Headers(h);
|
|
127
|
+
}, l = new Request(o, {
|
|
128
|
+
method: "GET",
|
|
129
|
+
headers: a(),
|
|
130
|
+
mode: "cors",
|
|
131
|
+
cache: "default"
|
|
132
|
+
}), d = await fetch(l), { configurator: m } = await d.json();
|
|
133
|
+
return m;
|
|
134
|
+
}, F = () => {
|
|
135
|
+
try {
|
|
136
|
+
return window.self !== window.top;
|
|
137
|
+
} catch {
|
|
138
|
+
return !0;
|
|
139
|
+
}
|
|
140
|
+
}, D = ["127.0.0.1", "localhost", "0.0.0.0"], C = () => {
|
|
141
|
+
const t = F();
|
|
142
|
+
let e = window.location.href;
|
|
143
|
+
if (t) {
|
|
144
|
+
if (!document.referrer)
|
|
145
|
+
return null;
|
|
146
|
+
e = document.referrer;
|
|
147
|
+
}
|
|
148
|
+
const { hostname: s } = new URL(e);
|
|
149
|
+
return s;
|
|
150
|
+
}, B = (t) => !!(D.includes(t) || t.endsWith("roomle.com") || t.endsWith("gitlab.io") || t.endsWith("gitlab.com")), I = [
|
|
151
|
+
"language",
|
|
152
|
+
"browserLanguage",
|
|
153
|
+
"userLanguage",
|
|
154
|
+
"systemLanguage"
|
|
155
|
+
], k = (t = null) => {
|
|
156
|
+
const e = window.navigator;
|
|
157
|
+
if (t)
|
|
158
|
+
return t.substr(0, 2);
|
|
159
|
+
if (Array.isArray(e.languages) && e.languages.length > 0)
|
|
160
|
+
return e.languages[0].substr(0, 2);
|
|
161
|
+
for (let s = 0, r = I.length; s < r; s++) {
|
|
162
|
+
const o = e[I[s]];
|
|
163
|
+
if (o)
|
|
164
|
+
return o.substr(0, 2);
|
|
165
|
+
}
|
|
166
|
+
return "en";
|
|
167
|
+
}, U = (t, e) => {
|
|
168
|
+
const s = JSON.parse(JSON.stringify(t));
|
|
169
|
+
return A(s, e);
|
|
170
|
+
}, A = (t, e) => {
|
|
171
|
+
for (const s in e)
|
|
172
|
+
try {
|
|
173
|
+
e[s].constructor === Object ? t[s] = A(t[s], e[s]) : t[s] = e[s];
|
|
174
|
+
} catch {
|
|
175
|
+
t[s] = e[s];
|
|
176
|
+
}
|
|
177
|
+
return t;
|
|
178
|
+
}, x = {
|
|
179
|
+
mobileLandscape: !0,
|
|
180
|
+
floorMaterialRootTag: "materials_root",
|
|
181
|
+
buttons: {
|
|
182
|
+
renderimage: !0,
|
|
183
|
+
requestproduct: !0,
|
|
184
|
+
requestplan: !0,
|
|
185
|
+
load_product: !0,
|
|
186
|
+
partlist_print: !0
|
|
187
|
+
},
|
|
188
|
+
helpcenter: {
|
|
189
|
+
roomdesigner: !0,
|
|
190
|
+
configurator: !1,
|
|
191
|
+
disable: !1
|
|
192
|
+
},
|
|
193
|
+
firstPersonView: !0,
|
|
194
|
+
saveToIdb: !0,
|
|
195
|
+
featureFlags: {
|
|
196
|
+
mocAr: !0
|
|
197
|
+
}
|
|
198
|
+
}, W = "(idle)", G = (t) => (O(t), t != null && t.customApiUrl && (t.customApiUrl = decodeURIComponent(t.customApiUrl)), t.shareUrl && (t.deeplink = t.shareUrl.replace(
|
|
199
|
+
z,
|
|
200
|
+
V
|
|
201
|
+
)), t), O = (t) => {
|
|
202
|
+
if (!t)
|
|
203
|
+
return;
|
|
204
|
+
const e = Object.keys(t);
|
|
205
|
+
for (const s of e) {
|
|
206
|
+
const r = t[s];
|
|
207
|
+
if (!Array.isArray(r) && typeof r == "object" && r !== null && O(r), Array.isArray(r))
|
|
208
|
+
for (const o of r)
|
|
209
|
+
O(o);
|
|
210
|
+
(r === "true" || r === "false") && (t[s] = r === "true");
|
|
211
|
+
}
|
|
212
|
+
}, J = (t, e) => {
|
|
213
|
+
e.configuratorId = t.id;
|
|
214
|
+
const s = t.settings || {};
|
|
215
|
+
return !e.overrideTenant && t.tenant && (e.overrideTenant = t.tenant), U(s, e);
|
|
216
|
+
}, $ = () => {
|
|
217
|
+
const t = {
|
|
218
|
+
...x
|
|
219
|
+
};
|
|
220
|
+
t.locale || (t.locale = k()), t.id === W && delete t.id;
|
|
221
|
+
const e = C();
|
|
222
|
+
return e && B(e) && (t.configuratorId = "demoConfigurator"), t.customApiUrl = "https://www.roomle.com/api/v2", t.emails = !1, t;
|
|
223
|
+
}, z = "<CONF_ID>", V = "#CONFIGURATIONID#", b = () => /(android)/i.test(navigator.userAgent), R = (t, e, s) => {
|
|
224
|
+
let r = null;
|
|
225
|
+
Object.defineProperty(t, e, {
|
|
226
|
+
get() {
|
|
227
|
+
return r || s;
|
|
228
|
+
},
|
|
229
|
+
set(o) {
|
|
230
|
+
o != null && o.mute ? r = o.value : (console.warn(
|
|
231
|
+
"You override Roomle defined behaviour. To disalbe this warning pass in an object with the following properties"
|
|
232
|
+
), console.warn("{ mute: true, value: () => void }"), r = o);
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
}, N = () => window.innerHeight * 0.01 + "px", T = (t) => {
|
|
236
|
+
t && setTimeout(
|
|
237
|
+
() => t.style.setProperty(y, N()),
|
|
238
|
+
0
|
|
239
|
+
);
|
|
240
|
+
}, L = "rml-styles", Y = 450, y = "--rml-full-height", c = {
|
|
241
|
+
CONTAINER: "rml-container",
|
|
242
|
+
FILL: "rml-fill",
|
|
243
|
+
POSITION: "rml-pos",
|
|
244
|
+
TRANSITION: "rml-transition",
|
|
245
|
+
ANDROID_HEIGHT: "rml-android-height",
|
|
246
|
+
OVERFLOW_HIDDEN: "rml-overflow-hidden"
|
|
247
|
+
}, w = /* @__PURE__ */ new Map();
|
|
248
|
+
class K {
|
|
249
|
+
constructor(e, s, r, o) {
|
|
250
|
+
u(this, "ui", {
|
|
251
|
+
callbacks: null
|
|
252
|
+
});
|
|
253
|
+
u(this, "extended", {
|
|
254
|
+
callbacks: null
|
|
255
|
+
});
|
|
256
|
+
u(this, "analytics", {
|
|
257
|
+
callbacks: {}
|
|
258
|
+
});
|
|
259
|
+
u(this, "global", {
|
|
260
|
+
callbacks: {}
|
|
261
|
+
});
|
|
262
|
+
u(this, "_waitForIframe");
|
|
263
|
+
u(this, "_container");
|
|
264
|
+
u(this, "_messageHandler");
|
|
265
|
+
u(this, "_configuratorSettings");
|
|
266
|
+
u(this, "_initData", {});
|
|
267
|
+
u(this, "_iframe");
|
|
268
|
+
if (!e || typeof e.id != "string")
|
|
269
|
+
throw new Error(
|
|
270
|
+
"Please provide a correct configuratorId, you get the correct ID from your Roomle Contact Person"
|
|
271
|
+
);
|
|
272
|
+
if (w.has(s))
|
|
273
|
+
throw new Error("There is already an instance on this DOM element");
|
|
274
|
+
if (!!!document.getElementById(L)) {
|
|
275
|
+
const a = r.zIndex || 9999999, l = document.createElement("style");
|
|
276
|
+
l.type = "text/css", l.id = L;
|
|
277
|
+
const d = "transition:all ease-in-out " + Y + "ms;", m = ["-webkit-", "-o-"].reduce(
|
|
278
|
+
(f, g) => f += g + d,
|
|
279
|
+
""
|
|
280
|
+
) + d, h = N();
|
|
281
|
+
l.innerHTML = `
|
|
282
|
+
.${c.CONTAINER}{${y}:${h};}
|
|
283
|
+
.${c.POSITION}{position:fixed;top:0;left:0;z-index:${a};opacity:0}
|
|
284
|
+
.${c.TRANSITION}{${m}}
|
|
285
|
+
.${c.FILL}{width:100%;height:100%;opacity:1}
|
|
286
|
+
.${c.ANDROID_HEIGHT}{height:calc(var(${y},1vh)*100)}
|
|
287
|
+
.${c.OVERFLOW_HIDDEN}{overflow:hidden}
|
|
288
|
+
`, document.head.appendChild(l);
|
|
289
|
+
}
|
|
290
|
+
this._onResize = this._onResize.bind(this), b() && window.addEventListener("resize", this._onResize), this._container = s, this._initData = r, this._configuratorSettings = e;
|
|
291
|
+
const i = this._createIframe();
|
|
292
|
+
this._onUseFullPage = this._onUseFullPage.bind(this), this._executeMessage = this._executeMessage.bind(this), this._onBackToWebsite = this._onBackToWebsite.bind(this), this._messageHandler = new P(
|
|
293
|
+
"website",
|
|
294
|
+
window,
|
|
295
|
+
null,
|
|
296
|
+
this._executeMessage
|
|
297
|
+
), this._waitForIframe = o, this._container.appendChild(i), this._iframe = i, w.set(s, !0);
|
|
298
|
+
}
|
|
299
|
+
static createPlanner(e, s, r) {
|
|
300
|
+
return this._create(
|
|
301
|
+
e,
|
|
302
|
+
s,
|
|
303
|
+
r
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Method to create a new instance of a Roomle Configurator
|
|
308
|
+
* @param configuratorId the id which identifies your configurator, you will get this ID from your Roomle Contact Person
|
|
309
|
+
* @param container DOM container in which the configurator should be placed
|
|
310
|
+
* @param initData settings with which the configurator should be started
|
|
311
|
+
*/
|
|
312
|
+
static createConfigurator(e, s, r) {
|
|
313
|
+
return this._create(
|
|
314
|
+
e,
|
|
315
|
+
s,
|
|
316
|
+
r
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Method to create a new instance of a Roomle Configurator
|
|
321
|
+
* @deprecated please use "createConfigurator"
|
|
322
|
+
* @param configuratorId the id which identifies your configurator, you will get this ID from your Roomle Contact Person
|
|
323
|
+
* @param container DOM container in which the configurator should be placed
|
|
324
|
+
* @param initData settings with which the configurator should be started
|
|
325
|
+
*/
|
|
326
|
+
static create(e, s, r) {
|
|
327
|
+
return this._create(
|
|
328
|
+
e,
|
|
329
|
+
s,
|
|
330
|
+
r
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Method to create a new instance of a Roomle Viewer
|
|
335
|
+
* @param configuratorId the id which identifies your configurator, you will get this ID from your Roomle Contact Person
|
|
336
|
+
* @param container DOM container in which the configurator should be placed
|
|
337
|
+
* @param initData settings with which the configurator should be started
|
|
338
|
+
*/
|
|
339
|
+
static createViewer(e, s, r) {
|
|
340
|
+
return this._create(
|
|
341
|
+
e,
|
|
342
|
+
s,
|
|
343
|
+
r
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
static _create(e, s, r) {
|
|
347
|
+
return new Promise(async (o, n) => {
|
|
348
|
+
try {
|
|
349
|
+
const i = A(
|
|
350
|
+
$(),
|
|
351
|
+
G(r)
|
|
352
|
+
);
|
|
353
|
+
i.featureFlags || (i.featureFlags = {}), typeof i.featureFlags.realPartList != "boolean" && (i.featureFlags.realPartList = !0), typeof i.featureFlags.globalCallbacks != "boolean" && (i.featureFlags.globalCallbacks = !0), typeof i.featureFlags.mocAr != "boolean" && (i.featureFlags.mocAr = !1);
|
|
354
|
+
const a = await H(
|
|
355
|
+
e,
|
|
356
|
+
i
|
|
357
|
+
);
|
|
358
|
+
return r = J(a, i), new this(
|
|
359
|
+
a,
|
|
360
|
+
s,
|
|
361
|
+
r,
|
|
362
|
+
o
|
|
363
|
+
);
|
|
364
|
+
} catch (i) {
|
|
365
|
+
return n(i);
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
teardown() {
|
|
370
|
+
this._container && w.delete(this._container);
|
|
371
|
+
const e = this._container.querySelector("iframe");
|
|
372
|
+
e && this._container.removeChild(e), window.removeEventListener("resize", this._onResize);
|
|
373
|
+
}
|
|
374
|
+
_createIframe() {
|
|
375
|
+
var r;
|
|
376
|
+
const e = document.createElement("iframe");
|
|
377
|
+
let s = ((r = this._configuratorSettings) == null ? void 0 : r.url) || "https://www.roomle.com/t/cp/";
|
|
378
|
+
return this._initData.useLocalRoomle && (s = location.href.replace("embedding.html", "")), location.href.includes("roomle.gitlab.io") && (s = location.href.replace("embedding.html", "index.html")), this._initData.overrideServerUrl && (s = this._initData.overrideServerUrl), e.src = s, e.classList.add(c.CONTAINER), e.classList.add(c.FILL), e;
|
|
379
|
+
}
|
|
380
|
+
_onResize() {
|
|
381
|
+
T(this._iframe);
|
|
382
|
+
}
|
|
383
|
+
_onUseFullPage() {
|
|
384
|
+
this._iframe.classList.add(c.POSITION), document.documentElement.classList.add(c.OVERFLOW_HIDDEN), window.document.body.classList.add(c.OVERFLOW_HIDDEN), b() && (T(this._iframe), this._iframe.classList.add(c.ANDROID_HEIGHT));
|
|
385
|
+
}
|
|
386
|
+
_onBackToWebsite() {
|
|
387
|
+
this._iframe.classList.remove(c.POSITION), this._iframe.classList.remove(c.ANDROID_HEIGHT), document.documentElement.classList.remove(c.OVERFLOW_HIDDEN), window.document.body.classList.remove(c.OVERFLOW_HIDDEN);
|
|
388
|
+
}
|
|
389
|
+
_executeMessage({ message: e, args: s }, r) {
|
|
390
|
+
var l;
|
|
391
|
+
if (!r.source || r.source !== ((l = this._iframe) == null ? void 0 : l.contentWindow))
|
|
392
|
+
return;
|
|
393
|
+
if (e === E.REQUEST_BOOT)
|
|
394
|
+
return this._messageHandler.setOutgoingMessageBus(r.source), Promise.resolve({ result: this._initData });
|
|
395
|
+
if (e === E.SETUP) {
|
|
396
|
+
const { methods: d, callbacks: m } = s[0];
|
|
397
|
+
return d.forEach((h) => {
|
|
398
|
+
const f = h.split(p), g = f[0], _ = f[1];
|
|
399
|
+
this[g] || (this[g] = {}), this[g][_] = (function() {
|
|
400
|
+
return this._messageHandler.sendMessage(h, [...arguments]);
|
|
401
|
+
}).bind(this);
|
|
402
|
+
}), m.forEach((h) => {
|
|
403
|
+
const f = h.split(p), g = f[0], _ = f[1], S = f[2];
|
|
404
|
+
this[g] || (this[g] = {}), this[g][_] || (this[g][_] = {}), this[g][_][S] = () => {
|
|
405
|
+
};
|
|
406
|
+
}), R(
|
|
407
|
+
this.ui.callbacks,
|
|
408
|
+
"onUseFullPage",
|
|
409
|
+
this._onUseFullPage
|
|
410
|
+
), R(
|
|
411
|
+
this.ui.callbacks,
|
|
412
|
+
"onBackToWebsite",
|
|
413
|
+
this._onBackToWebsite
|
|
414
|
+
), this._waitForIframe(this), setTimeout(
|
|
415
|
+
() => this._messageHandler.sendMessage(E.WEBSITE_READY),
|
|
416
|
+
0
|
|
417
|
+
), Promise.resolve({ result: null });
|
|
418
|
+
}
|
|
419
|
+
const o = e.split(p), n = o[0], i = o[1], a = o.length === 3 ? o[2] : null;
|
|
420
|
+
if (a && this[n][i][a]) {
|
|
421
|
+
const d = this[n][i][a](
|
|
422
|
+
...s
|
|
423
|
+
);
|
|
424
|
+
return d instanceof Promise ? d.then((m) => ({ result: m })) : d !== void 0 ? Promise.resolve({ result: d }) : Promise.resolve({ result: null });
|
|
425
|
+
}
|
|
426
|
+
return Promise.reject('Message "' + e + '" is unkown');
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
export {
|
|
430
|
+
K as default
|
|
431
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
var R=Object.defineProperty,A=(s,e,t)=>e in s?R(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t,u=(s,e,t)=>A(s,typeof e!="symbol"?e+"":e,t);class S{constructor(e,t,r,i){u(this,"_side"),u(this,"_incomingMessageBus"),u(this,"_outgoingMessageBus",null),u(this,"_execMessage",null),this._side=e,this._incomingMessageBus=t,this._outgoingMessageBus=r,this._execMessage=i,this._incomingMessageBus.addEventListener("message",this._handleMessage.bind(this))}setOutgoingMessageBus(e){this._outgoingMessageBus=e}setMessageExecution(e){this._execMessage=e}sendMessage(e,t=[]){return new Promise((r,i)=>{const o=new MessageChannel;o.port1.onmessage=n=>{if(!n||!n.data)return o.port1.close(),o.port2.close(),i(new Error(this._side+" received message but response can not be interpreted"));let c;try{c=JSON.parse(n.data)}catch(h){return o.port1.close(),o.port2.close(),this._prepareError(h),i(h)}c.error?i(c.error):c.result!==void 0?r(c.result):r(void 0),o.port1.close(),o.port2.close()};let a="";try{a=JSON.stringify({message:e,args:t})}catch{return i(new Error(this._side+": can not create command because it is not JSON.stringify able"))}if(!this._outgoingMessageBus)return i(new Error(this._side+": outgoing bus not set yet"));this._outgoingMessageBus.postMessage(a,"*",[o.port2])})}_handleMessage(e){const t=e.ports&&Array.isArray(e.ports)&&e.ports.length>0?e.ports[0]:null;if(e.data&&t)try{const r=JSON.parse(e.data);if(!this._execMessage)return t.postMessage(JSON.stringify({error:this._side+" is not ready to handle messages"}));Array.isArray(r.args)||(r.args=[r.args]);const i=this._execMessage(r,e);if(i===void 0)return;i.then((o={})=>{let a,n;typeof o=="object"&&o!==null&&(a=o.error,n=o.result),a?t.postMessage(JSON.stringify({error:a})):n!==void 0?t.postMessage(JSON.stringify({result:n})):t.postMessage(JSON.stringify({result:o}))},o=>{t.postMessage(JSON.stringify({error:this._prepareError(o)}))})}catch(r){t.postMessage(JSON.stringify({error:this._prepareError(r)}))}}_prepareError(e){if(typeof e=="string"){const t=this._side+": "+e;return console.error(t),t}return e.message=this._side+": "+e.message,console.error(e),e.message}}const p=".",w={REQUEST_BOOT:"requestBoot",SETUP:"setup",WEBSITE_READY:"websiteReady"},F=async(s,e)=>{if(typeof s!="string")throw new Error('Configurator ID is not a string type: "'+typeof s+'"');const t=e.customApiUrl?e.customApiUrl:"https://api.roomle.com/v2",r=e.overrideTenant||9,i=t+"/configurators/"+s,o="roomle_portal_v2",a="03-"+window.btoa(new Date().toISOString()+";anonymous;"+o),n=()=>{const g={apiKey:o,currentTenant:r,locale:"en",language:"en",device:1,token:a,platform:"web"};return new Headers(g)},c=new Request(i,{method:"GET",headers:n(),mode:"cors",cache:"default"}),h=await fetch(c),{configurator:f}=await h.json();return f},P=()=>{try{return window.self!==window.top}catch{return!0}},H=["127.0.0.1","localhost","0.0.0.0"],U=()=>{const s=P();let e=window.location.href;if(s){if(!document.referrer)return null;e=document.referrer}const{hostname:t}=new URL(e);return t},B=s=>!!(H.includes(s)||s.endsWith("roomle.com")||s.endsWith("gitlab.io")||s.endsWith("gitlab.com")),I=["language","browserLanguage","userLanguage","systemLanguage"],k=(s=null)=>{const e=window.navigator;if(s)return s.substr(0,2);if(Array.isArray(e.languages)&&e.languages.length>0)return e.languages[0].substr(0,2);for(let t=0,r=I.length;t<r;t++){const i=e[I[t]];if(i)return i.substr(0,2)}return"en"},x=(s,e)=>{const t=JSON.parse(JSON.stringify(s));return b(t,e)},b=(s,e)=>{for(const t in e)try{e[t].constructor===Object?s[t]=b(s[t],e[t]):s[t]=e[t]}catch{s[t]=e[t]}return s},W={mobileLandscape:!0,floorMaterialRootTag:"materials_root",buttons:{renderimage:!0,requestproduct:!0,requestplan:!0,load_product:!0,partlist_print:!0},helpcenter:{roomdesigner:!0,configurator:!1,disable:!1},firstPersonView:!0,saveToIdb:!0,featureFlags:{mocAr:!0}},C="(idle)",J=s=>(y(s),s!=null&&s.customApiUrl&&(s.customApiUrl=decodeURIComponent(s.customApiUrl)),s.shareUrl&&(s.deeplink=s.shareUrl.replace(j,V)),s),y=s=>{if(!s)return;const e=Object.keys(s);for(const t of e){const r=s[t];if(!Array.isArray(r)&&typeof r=="object"&&r!==null&&y(r),Array.isArray(r))for(const i of r)y(i);(r==="true"||r==="false")&&(s[t]=r==="true")}},$=(s,e)=>{e.configuratorId=s.id;const t=s.settings||{};return!e.overrideTenant&&s.tenant&&(e.overrideTenant=s.tenant),x(t,e)},z=()=>{const s={...W};s.locale||(s.locale=k()),s.id===C&&delete s.id;const e=U();return e&&B(e)&&(s.configuratorId="demoConfigurator"),s.customApiUrl="https://www.roomle.com/api/v2",s.emails=!1,s},j="<CONF_ID>",V="#CONFIGURATIONID#",v=()=>/(android)/i.test(navigator.userAgent),T=(s,e,t)=>{let r=null;Object.defineProperty(s,e,{get(){return r||t},set(i){i!=null&&i.mute?r=i.value:(console.warn("You override Roomle defined behaviour. To disalbe this warning pass in an object with the following properties"),console.warn("{ mute: true, value: () => void }"),r=i)}})},N=()=>window.innerHeight*.01+"px",M=s=>{s&&setTimeout(()=>s.style.setProperty(O,N()),0)},D="rml-styles",G=450,O="--rml-full-height",l={CONTAINER:"rml-container",FILL:"rml-fill",POSITION:"rml-pos",TRANSITION:"rml-transition",ANDROID_HEIGHT:"rml-android-height",OVERFLOW_HIDDEN:"rml-overflow-hidden"},E=new Map;class q{constructor(e,t,r,i){if(u(this,"ui",{callbacks:null}),u(this,"extended",{callbacks:null}),u(this,"analytics",{callbacks:{}}),u(this,"global",{callbacks:{}}),u(this,"_waitForIframe"),u(this,"_container"),u(this,"_messageHandler"),u(this,"_configuratorSettings"),u(this,"_initData",{}),u(this,"_iframe"),!e||typeof e.id!="string")throw new Error("Please provide a correct configuratorId, you get the correct ID from your Roomle Contact Person");if(E.has(t))throw new Error("There is already an instance on this DOM element");if(!document.getElementById(D)){const a=r.zIndex||9999999,n=document.createElement("style");n.type="text/css",n.id=D;const c="transition:all ease-in-out "+G+"ms;",h=["-webkit-","-o-"].reduce((g,m)=>g+=m+c,"")+c,f=N();n.innerHTML=`
|
|
2
|
+
.${l.CONTAINER}{${O}:${f};}
|
|
3
|
+
.${l.POSITION}{position:fixed;top:0;left:0;z-index:${a};opacity:0}
|
|
4
|
+
.${l.TRANSITION}{${h}}
|
|
5
|
+
.${l.FILL}{width:100%;height:100%;opacity:1}
|
|
6
|
+
.${l.ANDROID_HEIGHT}{height:calc(var(${O},1vh)*100)}
|
|
7
|
+
.${l.OVERFLOW_HIDDEN}{overflow:hidden}
|
|
8
|
+
`,document.head.appendChild(n)}this._onResize=this._onResize.bind(this),v()&&window.addEventListener("resize",this._onResize),this._container=t,this._initData=r,this._configuratorSettings=e;const o=this._createIframe();this._onUseFullPage=this._onUseFullPage.bind(this),this._executeMessage=this._executeMessage.bind(this),this._onBackToWebsite=this._onBackToWebsite.bind(this),this._messageHandler=new S("website",window,null,this._executeMessage),this._waitForIframe=i,this._container.appendChild(o),this._iframe=o,E.set(t,!0)}static createPlanner(e,t,r){return this._create(e,t,r)}static createConfigurator(e,t,r){return this._create(e,t,r)}static create(e,t,r){return this._create(e,t,r)}static createViewer(e,t,r){return this._create(e,t,r)}static _create(e,t,r){return new Promise(async(i,o)=>{try{const a=b(z(),J(r));a.featureFlags||(a.featureFlags={}),typeof a.featureFlags.realPartList!="boolean"&&(a.featureFlags.realPartList=!0),typeof a.featureFlags.globalCallbacks!="boolean"&&(a.featureFlags.globalCallbacks=!0),typeof a.featureFlags.mocAr!="boolean"&&(a.featureFlags.mocAr=!1);const n=await F(e,a);return r=$(n,a),new this(n,t,r,i)}catch(a){return o(a)}})}teardown(){this._container&&E.delete(this._container);const e=this._container.querySelector("iframe");e&&this._container.removeChild(e),window.removeEventListener("resize",this._onResize)}_createIframe(){var e;const t=document.createElement("iframe");let r=((e=this._configuratorSettings)==null?void 0:e.url)||"https://www.roomle.com/t/cp/";return this._initData.useLocalRoomle&&(r=location.href.replace("embedding.html","")),location.href.includes("roomle.gitlab.io")&&(r=location.href.replace("embedding.html","index.html")),this._initData.overrideServerUrl&&(r=this._initData.overrideServerUrl),t.src=r,t.classList.add(l.CONTAINER),t.classList.add(l.FILL),t}_onResize(){M(this._iframe)}_onUseFullPage(){this._iframe.classList.add(l.POSITION),document.documentElement.classList.add(l.OVERFLOW_HIDDEN),window.document.body.classList.add(l.OVERFLOW_HIDDEN),v()&&(M(this._iframe),this._iframe.classList.add(l.ANDROID_HEIGHT))}_onBackToWebsite(){this._iframe.classList.remove(l.POSITION),this._iframe.classList.remove(l.ANDROID_HEIGHT),document.documentElement.classList.remove(l.OVERFLOW_HIDDEN),window.document.body.classList.remove(l.OVERFLOW_HIDDEN)}_executeMessage({message:e,args:t},r){var i;if(!r.source||r.source!==((i=this._iframe)==null?void 0:i.contentWindow))return;if(e===w.REQUEST_BOOT)return this._messageHandler.setOutgoingMessageBus(r.source),Promise.resolve({result:this._initData});if(e===w.SETUP){const{methods:h,callbacks:f}=t[0];return h.forEach(g=>{const m=g.split(p),d=m[0],_=m[1];this[d]||(this[d]={}),this[d][_]=function(){return this._messageHandler.sendMessage(g,[...arguments])}.bind(this)}),f.forEach(g=>{const m=g.split(p),d=m[0],_=m[1],L=m[2];this[d]||(this[d]={}),this[d][_]||(this[d][_]={}),this[d][_][L]=()=>{}}),T(this.ui.callbacks,"onUseFullPage",this._onUseFullPage),T(this.ui.callbacks,"onBackToWebsite",this._onBackToWebsite),this._waitForIframe(this),setTimeout(()=>this._messageHandler.sendMessage(w.WEBSITE_READY),0),Promise.resolve({result:null})}const o=e.split(p),a=o[0],n=o[1],c=o.length===3?o[2]:null;if(c&&this[a][n][c]){const h=this[a][n][c](...t);return h instanceof Promise?h.then(f=>({result:f})):h!==void 0?Promise.resolve({result:h}):Promise.resolve({result:null})}return Promise.reject('Message "'+e+'" is unkown')}}export{q as default};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
(function(l,u){typeof exports=="object"&&typeof module<"u"?module.exports=u():typeof define=="function"&&define.amd?define(u):(l=typeof globalThis<"u"?globalThis:l||self,l["roomle-embedding-lib"]=l["roomle-embedding-lib"]||{},l["roomle-embedding-lib"].umd=l["roomle-embedding-lib"].umd||{},l["roomle-embedding-lib"].umd.js=u())})(this,function(){"use strict";var Y=Object.defineProperty;var q=(l,u,m)=>u in l?Y(l,u,{enumerable:!0,configurable:!0,writable:!0,value:m}):l[u]=m;var f=(l,u,m)=>q(l,typeof u!="symbol"?u+"":u,m);class l{constructor(e,t,r,o){f(this,"_side");f(this,"_incomingMessageBus");f(this,"_outgoingMessageBus",null);f(this,"_execMessage",null);this._side=e,this._incomingMessageBus=t,this._outgoingMessageBus=r,this._execMessage=o,this._incomingMessageBus.addEventListener("message",this._handleMessage.bind(this))}setOutgoingMessageBus(e){this._outgoingMessageBus=e}setMessageExecution(e){this._execMessage=e}sendMessage(e,t=[]){return new Promise((r,o)=>{const n=new MessageChannel;n.port1.onmessage=a=>{if(!a||!a.data)return n.port1.close(),n.port2.close(),o(new Error(this._side+" received message but response can not be interpreted"));let d;try{d=JSON.parse(a.data)}catch(g){return n.port1.close(),n.port2.close(),this._prepareError(g),o(g)}d.error?o(d.error):d.result!==void 0?r(d.result):r(void 0),n.port1.close(),n.port2.close()};let i="";try{i=JSON.stringify({message:e,args:t})}catch{return o(new Error(this._side+": can not create command because it is not JSON.stringify able"))}if(!this._outgoingMessageBus)return o(new Error(this._side+": outgoing bus not set yet"));this._outgoingMessageBus.postMessage(i,"*",[n.port2])})}_handleMessage(e){const t=e.ports&&Array.isArray(e.ports)&&e.ports.length>0?e.ports[0]:null;if(e.data&&t)try{const r=JSON.parse(e.data);if(!this._execMessage)return t.postMessage(JSON.stringify({error:this._side+" is not ready to handle messages"}));Array.isArray(r.args)||(r.args=[r.args]);const o=this._execMessage(r,e);if(o===void 0)return;o.then((n={})=>{let i,a;typeof n=="object"&&n!==null&&(i=n.error,a=n.result),i?t.postMessage(JSON.stringify({error:i})):a!==void 0?t.postMessage(JSON.stringify({result:a})):t.postMessage(JSON.stringify({result:n}))},n=>{t.postMessage(JSON.stringify({error:this._prepareError(n)}))})}catch(r){t.postMessage(JSON.stringify({error:this._prepareError(r)}))}}_prepareError(e){if(typeof e=="string"){const t=this._side+": "+e;return console.error(t),t}return e.message=this._side+": "+e.message,console.error(e),e.message}}const u=".",m={REQUEST_BOOT:"requestBoot",SETUP:"setup",WEBSITE_READY:"websiteReady"},M=async(s,e)=>{if(typeof s!="string")throw new Error('Configurator ID is not a string type: "'+typeof s+'"');const t=e.customApiUrl?e.customApiUrl:"https://api.roomle.com/v2",r=e.overrideTenant||9,o=t+"/configurators/"+s,n="roomle_portal_v2",i="03-"+window.btoa(new Date().toISOString()+";anonymous;"+n),a=()=>{const _={apiKey:n,currentTenant:r,locale:"en",language:"en",device:1,token:i,platform:"web"};return new Headers(_)},d=new Request(o,{method:"GET",headers:a(),mode:"cors",cache:"default"}),g=await fetch(d),{configurator:E}=await g.json();return E},v=()=>{try{return window.self!==window.top}catch{return!0}},P=["127.0.0.1","localhost","0.0.0.0"],H=()=>{const s=v();let e=window.location.href;if(s){if(!document.referrer)return null;e=document.referrer}const{hostname:t}=new URL(e);return t},F=s=>!!(P.includes(s)||s.endsWith("roomle.com")||s.endsWith("gitlab.io")||s.endsWith("gitlab.com")),b=["language","browserLanguage","userLanguage","systemLanguage"],D=(s=null)=>{const e=window.navigator;if(s)return s.substr(0,2);if(Array.isArray(e.languages)&&e.languages.length>0)return e.languages[0].substr(0,2);for(let t=0,r=b.length;t<r;t++){const o=e[b[t]];if(o)return o.substr(0,2)}return"en"},C=(s,e)=>{const t=JSON.parse(JSON.stringify(s));return y(t,e)},y=(s,e)=>{for(const t in e)try{e[t].constructor===Object?s[t]=y(s[t],e[t]):s[t]=e[t]}catch{s[t]=e[t]}return s},B={mobileLandscape:!0,floorMaterialRootTag:"materials_root",buttons:{renderimage:!0,requestproduct:!0,requestplan:!0,load_product:!0,partlist_print:!0},helpcenter:{roomdesigner:!0,configurator:!1,disable:!1},firstPersonView:!0,saveToIdb:!0,featureFlags:{mocAr:!0}},k="(idle)",U=s=>(O(s),s!=null&&s.customApiUrl&&(s.customApiUrl=decodeURIComponent(s.customApiUrl)),s.shareUrl&&(s.deeplink=s.shareUrl.replace(G,J)),s),O=s=>{if(!s)return;const e=Object.keys(s);for(const t of e){const r=s[t];if(!Array.isArray(r)&&typeof r=="object"&&r!==null&&O(r),Array.isArray(r))for(const o of r)O(o);(r==="true"||r==="false")&&(s[t]=r==="true")}},x=(s,e)=>{e.configuratorId=s.id;const t=s.settings||{};return!e.overrideTenant&&s.tenant&&(e.overrideTenant=s.tenant),C(t,e)},W=()=>{const s={...B};s.locale||(s.locale=D()),s.id===k&&delete s.id;const e=H();return e&&F(e)&&(s.configuratorId="demoConfigurator"),s.customApiUrl="https://www.roomle.com/api/v2",s.emails=!1,s},G="<CONF_ID>",J="#CONFIGURATIONID#",T=()=>/(android)/i.test(navigator.userAgent),R=(s,e,t)=>{let r=null;Object.defineProperty(s,e,{get(){return r||t},set(o){o!=null&&o.mute?r=o.value:(console.warn("You override Roomle defined behaviour. To disalbe this warning pass in an object with the following properties"),console.warn("{ mute: true, value: () => void }"),r=o)}})},L=()=>window.innerHeight*.01+"px",N=s=>{s&&setTimeout(()=>s.style.setProperty(A,L()),0)},S="rml-styles",$=450,A="--rml-full-height",c={CONTAINER:"rml-container",FILL:"rml-fill",POSITION:"rml-pos",TRANSITION:"rml-transition",ANDROID_HEIGHT:"rml-android-height",OVERFLOW_HIDDEN:"rml-overflow-hidden"},I=new Map;class z{constructor(e,t,r,o){f(this,"ui",{callbacks:null});f(this,"extended",{callbacks:null});f(this,"analytics",{callbacks:{}});f(this,"global",{callbacks:{}});f(this,"_waitForIframe");f(this,"_container");f(this,"_messageHandler");f(this,"_configuratorSettings");f(this,"_initData",{});f(this,"_iframe");if(!e||typeof e.id!="string")throw new Error("Please provide a correct configuratorId, you get the correct ID from your Roomle Contact Person");if(I.has(t))throw new Error("There is already an instance on this DOM element");if(!!!document.getElementById(S)){const a=r.zIndex||9999999,d=document.createElement("style");d.type="text/css",d.id=S;const g="transition:all ease-in-out "+$+"ms;",E=["-webkit-","-o-"].reduce((p,h)=>p+=h+g,"")+g,_=L();d.innerHTML=`
|
|
2
|
+
.${c.CONTAINER}{${A}:${_};}
|
|
3
|
+
.${c.POSITION}{position:fixed;top:0;left:0;z-index:${a};opacity:0}
|
|
4
|
+
.${c.TRANSITION}{${E}}
|
|
5
|
+
.${c.FILL}{width:100%;height:100%;opacity:1}
|
|
6
|
+
.${c.ANDROID_HEIGHT}{height:calc(var(${A},1vh)*100)}
|
|
7
|
+
.${c.OVERFLOW_HIDDEN}{overflow:hidden}
|
|
8
|
+
`,document.head.appendChild(d)}this._onResize=this._onResize.bind(this),T()&&window.addEventListener("resize",this._onResize),this._container=t,this._initData=r,this._configuratorSettings=e;const i=this._createIframe();this._onUseFullPage=this._onUseFullPage.bind(this),this._executeMessage=this._executeMessage.bind(this),this._onBackToWebsite=this._onBackToWebsite.bind(this),this._messageHandler=new l("website",window,null,this._executeMessage),this._waitForIframe=o,this._container.appendChild(i),this._iframe=i,I.set(t,!0)}static createPlanner(e,t,r){return this._create(e,t,r)}static createConfigurator(e,t,r){return this._create(e,t,r)}static create(e,t,r){return this._create(e,t,r)}static createViewer(e,t,r){return this._create(e,t,r)}static _create(e,t,r){return new Promise(async(o,n)=>{try{const i=y(W(),U(r));i.featureFlags||(i.featureFlags={}),typeof i.featureFlags.realPartList!="boolean"&&(i.featureFlags.realPartList=!0),typeof i.featureFlags.globalCallbacks!="boolean"&&(i.featureFlags.globalCallbacks=!0),typeof i.featureFlags.mocAr!="boolean"&&(i.featureFlags.mocAr=!1);const a=await M(e,i);return r=x(a,i),new this(a,t,r,o)}catch(i){return n(i)}})}teardown(){this._container&&I.delete(this._container);const e=this._container.querySelector("iframe");e&&this._container.removeChild(e),window.removeEventListener("resize",this._onResize)}_createIframe(){var r;const e=document.createElement("iframe");let t=((r=this._configuratorSettings)==null?void 0:r.url)||"https://www.roomle.com/t/cp/";return this._initData.useLocalRoomle&&(t=location.href.replace("embedding.html","")),location.href.includes("roomle.gitlab.io")&&(t=location.href.replace("embedding.html","index.html")),this._initData.overrideServerUrl&&(t=this._initData.overrideServerUrl),e.src=t,e.classList.add(c.CONTAINER),e.classList.add(c.FILL),e}_onResize(){N(this._iframe)}_onUseFullPage(){this._iframe.classList.add(c.POSITION),document.documentElement.classList.add(c.OVERFLOW_HIDDEN),window.document.body.classList.add(c.OVERFLOW_HIDDEN),T()&&(N(this._iframe),this._iframe.classList.add(c.ANDROID_HEIGHT))}_onBackToWebsite(){this._iframe.classList.remove(c.POSITION),this._iframe.classList.remove(c.ANDROID_HEIGHT),document.documentElement.classList.remove(c.OVERFLOW_HIDDEN),window.document.body.classList.remove(c.OVERFLOW_HIDDEN)}_executeMessage({message:e,args:t},r){var d;if(!r.source||r.source!==((d=this._iframe)==null?void 0:d.contentWindow))return;if(e===m.REQUEST_BOOT)return this._messageHandler.setOutgoingMessageBus(r.source),Promise.resolve({result:this._initData});if(e===m.SETUP){const{methods:g,callbacks:E}=t[0];return g.forEach(_=>{const p=_.split(u),h=p[0],w=p[1];this[h]||(this[h]={}),this[h][w]=(function(){return this._messageHandler.sendMessage(_,[...arguments])}).bind(this)}),E.forEach(_=>{const p=_.split(u),h=p[0],w=p[1],V=p[2];this[h]||(this[h]={}),this[h][w]||(this[h][w]={}),this[h][w][V]=()=>{}}),R(this.ui.callbacks,"onUseFullPage",this._onUseFullPage),R(this.ui.callbacks,"onBackToWebsite",this._onBackToWebsite),this._waitForIframe(this),setTimeout(()=>this._messageHandler.sendMessage(m.WEBSITE_READY),0),Promise.resolve({result:null})}const o=e.split(u),n=o[0],i=o[1],a=o.length===3?o[2]:null;if(a&&this[n][i][a]){const g=this[n][i][a](...t);return g instanceof Promise?g.then(E=>({result:E})):g!==void 0?Promise.resolve({result:g}):Promise.resolve({result:null})}return Promise.reject('Message "'+e+'" is unkown')}}return z});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
(function(g,p){typeof exports=="object"&&typeof module<"u"?module.exports=p():typeof define=="function"&&define.amd?define(p):(g=typeof globalThis<"u"?globalThis:g||self,g["roomle-embedding-lib"]=g["roomle-embedding-lib"]||{},g["roomle-embedding-lib"].umd=g["roomle-embedding-lib"].umd||{},g["roomle-embedding-lib"].umd.min=g["roomle-embedding-lib"].umd.min||{},g["roomle-embedding-lib"].umd.min.js=p())})(this,function(){"use strict";var g=Object.defineProperty,p=(s,e,t)=>e in s?g(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t,c=(s,e,t)=>p(s,typeof e!="symbol"?e+"":e,t);class A{constructor(e,t,r,i){c(this,"_side"),c(this,"_incomingMessageBus"),c(this,"_outgoingMessageBus",null),c(this,"_execMessage",null),this._side=e,this._incomingMessageBus=t,this._outgoingMessageBus=r,this._execMessage=i,this._incomingMessageBus.addEventListener("message",this._handleMessage.bind(this))}setOutgoingMessageBus(e){this._outgoingMessageBus=e}setMessageExecution(e){this._execMessage=e}sendMessage(e,t=[]){return new Promise((r,i)=>{const o=new MessageChannel;o.port1.onmessage=a=>{if(!a||!a.data)return o.port1.close(),o.port2.close(),i(new Error(this._side+" received message but response can not be interpreted"));let u;try{u=JSON.parse(a.data)}catch(d){return o.port1.close(),o.port2.close(),this._prepareError(d),i(d)}u.error?i(u.error):u.result!==void 0?r(u.result):r(void 0),o.port1.close(),o.port2.close()};let n="";try{n=JSON.stringify({message:e,args:t})}catch{return i(new Error(this._side+": can not create command because it is not JSON.stringify able"))}if(!this._outgoingMessageBus)return i(new Error(this._side+": outgoing bus not set yet"));this._outgoingMessageBus.postMessage(n,"*",[o.port2])})}_handleMessage(e){const t=e.ports&&Array.isArray(e.ports)&&e.ports.length>0?e.ports[0]:null;if(e.data&&t)try{const r=JSON.parse(e.data);if(!this._execMessage)return t.postMessage(JSON.stringify({error:this._side+" is not ready to handle messages"}));Array.isArray(r.args)||(r.args=[r.args]);const i=this._execMessage(r,e);if(i===void 0)return;i.then((o={})=>{let n,a;typeof o=="object"&&o!==null&&(n=o.error,a=o.result),n?t.postMessage(JSON.stringify({error:n})):a!==void 0?t.postMessage(JSON.stringify({result:a})):t.postMessage(JSON.stringify({result:o}))},o=>{t.postMessage(JSON.stringify({error:this._prepareError(o)}))})}catch(r){t.postMessage(JSON.stringify({error:this._prepareError(r)}))}}_prepareError(e){if(typeof e=="string"){const t=this._side+": "+e;return console.error(t),t}return e.message=this._side+": "+e.message,console.error(e),e.message}}const w=".",y={REQUEST_BOOT:"requestBoot",SETUP:"setup",WEBSITE_READY:"websiteReady"},S=async(s,e)=>{if(typeof s!="string")throw new Error('Configurator ID is not a string type: "'+typeof s+'"');const t=e.customApiUrl?e.customApiUrl:"https://api.roomle.com/v2",r=e.overrideTenant||9,i=t+"/configurators/"+s,o="roomle_portal_v2",n="03-"+window.btoa(new Date().toISOString()+";anonymous;"+o),a=()=>{const m={apiKey:o,currentTenant:r,locale:"en",language:"en",device:1,token:n,platform:"web"};return new Headers(m)},u=new Request(i,{method:"GET",headers:a(),mode:"cors",cache:"default"}),d=await fetch(u),{configurator:_}=await d.json();return _},F=()=>{try{return window.self!==window.top}catch{return!0}},P=["127.0.0.1","localhost","0.0.0.0"],H=()=>{const s=F();let e=window.location.href;if(s){if(!document.referrer)return null;e=document.referrer}const{hostname:t}=new URL(e);return t},U=s=>!!(P.includes(s)||s.endsWith("roomle.com")||s.endsWith("gitlab.io")||s.endsWith("gitlab.com")),T=["language","browserLanguage","userLanguage","systemLanguage"],B=(s=null)=>{const e=window.navigator;if(s)return s.substr(0,2);if(Array.isArray(e.languages)&&e.languages.length>0)return e.languages[0].substr(0,2);for(let t=0,r=T.length;t<r;t++){const i=e[T[t]];if(i)return i.substr(0,2)}return"en"},k=(s,e)=>{const t=JSON.parse(JSON.stringify(s));return O(t,e)},O=(s,e)=>{for(const t in e)try{e[t].constructor===Object?s[t]=O(s[t],e[t]):s[t]=e[t]}catch{s[t]=e[t]}return s},x={mobileLandscape:!0,floorMaterialRootTag:"materials_root",buttons:{renderimage:!0,requestproduct:!0,requestplan:!0,load_product:!0,partlist_print:!0},helpcenter:{roomdesigner:!0,configurator:!1,disable:!1},firstPersonView:!0,saveToIdb:!0,featureFlags:{mocAr:!0}},W="(idle)",C=s=>(E(s),s!=null&&s.customApiUrl&&(s.customApiUrl=decodeURIComponent(s.customApiUrl)),s.shareUrl&&(s.deeplink=s.shareUrl.replace(j,z)),s),E=s=>{if(!s)return;const e=Object.keys(s);for(const t of e){const r=s[t];if(!Array.isArray(r)&&typeof r=="object"&&r!==null&&E(r),Array.isArray(r))for(const i of r)E(i);(r==="true"||r==="false")&&(s[t]=r==="true")}},J=(s,e)=>{e.configuratorId=s.id;const t=s.settings||{};return!e.overrideTenant&&s.tenant&&(e.overrideTenant=s.tenant),k(t,e)},$=()=>{const s={...x};s.locale||(s.locale=B()),s.id===W&&delete s.id;const e=H();return e&&U(e)&&(s.configuratorId="demoConfigurator"),s.customApiUrl="https://www.roomle.com/api/v2",s.emails=!1,s},j="<CONF_ID>",z="#CONFIGURATIONID#",N=()=>/(android)/i.test(navigator.userAgent),M=(s,e,t)=>{let r=null;Object.defineProperty(s,e,{get(){return r||t},set(i){i!=null&&i.mute?r=i.value:(console.warn("You override Roomle defined behaviour. To disalbe this warning pass in an object with the following properties"),console.warn("{ mute: true, value: () => void }"),r=i)}})},D=()=>window.innerHeight*.01+"px",L=s=>{s&&setTimeout(()=>s.style.setProperty(I,D()),0)},R="rml-styles",V=450,I="--rml-full-height",l={CONTAINER:"rml-container",FILL:"rml-fill",POSITION:"rml-pos",TRANSITION:"rml-transition",ANDROID_HEIGHT:"rml-android-height",OVERFLOW_HIDDEN:"rml-overflow-hidden"},v=new Map;class G{constructor(e,t,r,i){if(c(this,"ui",{callbacks:null}),c(this,"extended",{callbacks:null}),c(this,"analytics",{callbacks:{}}),c(this,"global",{callbacks:{}}),c(this,"_waitForIframe"),c(this,"_container"),c(this,"_messageHandler"),c(this,"_configuratorSettings"),c(this,"_initData",{}),c(this,"_iframe"),!e||typeof e.id!="string")throw new Error("Please provide a correct configuratorId, you get the correct ID from your Roomle Contact Person");if(v.has(t))throw new Error("There is already an instance on this DOM element");if(!document.getElementById(R)){const n=r.zIndex||9999999,a=document.createElement("style");a.type="text/css",a.id=R;const u="transition:all ease-in-out "+V+"ms;",d=["-webkit-","-o-"].reduce((m,f)=>m+=f+u,"")+u,_=D();a.innerHTML=`
|
|
2
|
+
.${l.CONTAINER}{${I}:${_};}
|
|
3
|
+
.${l.POSITION}{position:fixed;top:0;left:0;z-index:${n};opacity:0}
|
|
4
|
+
.${l.TRANSITION}{${d}}
|
|
5
|
+
.${l.FILL}{width:100%;height:100%;opacity:1}
|
|
6
|
+
.${l.ANDROID_HEIGHT}{height:calc(var(${I},1vh)*100)}
|
|
7
|
+
.${l.OVERFLOW_HIDDEN}{overflow:hidden}
|
|
8
|
+
`,document.head.appendChild(a)}this._onResize=this._onResize.bind(this),N()&&window.addEventListener("resize",this._onResize),this._container=t,this._initData=r,this._configuratorSettings=e;const o=this._createIframe();this._onUseFullPage=this._onUseFullPage.bind(this),this._executeMessage=this._executeMessage.bind(this),this._onBackToWebsite=this._onBackToWebsite.bind(this),this._messageHandler=new A("website",window,null,this._executeMessage),this._waitForIframe=i,this._container.appendChild(o),this._iframe=o,v.set(t,!0)}static createPlanner(e,t,r){return this._create(e,t,r)}static createConfigurator(e,t,r){return this._create(e,t,r)}static create(e,t,r){return this._create(e,t,r)}static createViewer(e,t,r){return this._create(e,t,r)}static _create(e,t,r){return new Promise(async(i,o)=>{try{const n=O($(),C(r));n.featureFlags||(n.featureFlags={}),typeof n.featureFlags.realPartList!="boolean"&&(n.featureFlags.realPartList=!0),typeof n.featureFlags.globalCallbacks!="boolean"&&(n.featureFlags.globalCallbacks=!0),typeof n.featureFlags.mocAr!="boolean"&&(n.featureFlags.mocAr=!1);const a=await S(e,n);return r=J(a,n),new this(a,t,r,i)}catch(n){return o(n)}})}teardown(){this._container&&v.delete(this._container);const e=this._container.querySelector("iframe");e&&this._container.removeChild(e),window.removeEventListener("resize",this._onResize)}_createIframe(){var e;const t=document.createElement("iframe");let r=((e=this._configuratorSettings)==null?void 0:e.url)||"https://www.roomle.com/t/cp/";return this._initData.useLocalRoomle&&(r=location.href.replace("embedding.html","")),location.href.includes("roomle.gitlab.io")&&(r=location.href.replace("embedding.html","index.html")),this._initData.overrideServerUrl&&(r=this._initData.overrideServerUrl),t.src=r,t.classList.add(l.CONTAINER),t.classList.add(l.FILL),t}_onResize(){L(this._iframe)}_onUseFullPage(){this._iframe.classList.add(l.POSITION),document.documentElement.classList.add(l.OVERFLOW_HIDDEN),window.document.body.classList.add(l.OVERFLOW_HIDDEN),N()&&(L(this._iframe),this._iframe.classList.add(l.ANDROID_HEIGHT))}_onBackToWebsite(){this._iframe.classList.remove(l.POSITION),this._iframe.classList.remove(l.ANDROID_HEIGHT),document.documentElement.classList.remove(l.OVERFLOW_HIDDEN),window.document.body.classList.remove(l.OVERFLOW_HIDDEN)}_executeMessage({message:e,args:t},r){var i;if(!r.source||r.source!==((i=this._iframe)==null?void 0:i.contentWindow))return;if(e===y.REQUEST_BOOT)return this._messageHandler.setOutgoingMessageBus(r.source),Promise.resolve({result:this._initData});if(e===y.SETUP){const{methods:d,callbacks:_}=t[0];return d.forEach(m=>{const f=m.split(w),h=f[0],b=f[1];this[h]||(this[h]={}),this[h][b]=function(){return this._messageHandler.sendMessage(m,[...arguments])}.bind(this)}),_.forEach(m=>{const f=m.split(w),h=f[0],b=f[1],q=f[2];this[h]||(this[h]={}),this[h][b]||(this[h][b]={}),this[h][b][q]=()=>{}}),M(this.ui.callbacks,"onUseFullPage",this._onUseFullPage),M(this.ui.callbacks,"onBackToWebsite",this._onBackToWebsite),this._waitForIframe(this),setTimeout(()=>this._messageHandler.sendMessage(y.WEBSITE_READY),0),Promise.resolve({result:null})}const o=e.split(w),n=o[0],a=o[1],u=o.length===3?o[2]:null;if(u&&this[n][a][u]){const d=this[n][a][u](...t);return d instanceof Promise?d.then(_=>({result:_})):d!==void 0?Promise.resolve({result:d}):Promise.resolve({result:null})}return Promise.reject('Message "'+e+'" is unkown')}}return G});
|