-
Notifications
You must be signed in to change notification settings - Fork 91
/
lookbook.js
125 lines (99 loc) · 3.04 KB
/
lookbook.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
window.Lookbook = window.Lookbook || {};
window.Lookbook.initEmbeds = initEmbeds;
const embedUrlPrefix = "embed";
const whiteListedAttributes = [
"preview",
"scenario",
"panels",
"actions",
"param-*",
];
function initEmbeds(root = document) {
if (typeof window.iFrameResize !== "function") {
console.error(
"Lookbook embeds require the 'iframe-resizer' library to be available. Skipping embed instantiation."
);
return;
}
if (typeof root === "string") {
root = document.querySelector(root);
}
if (!root) {
return console.error(
"Could not initialize Lookbook embeds. Root node not found."
);
}
const embeds = Array.from(root.querySelectorAll("lookbook-embed"));
embeds.forEach((embed) => {
const attrs = Array.from(embed.attributes);
const wrapper = createWrapper();
const iframe = createIframe(attrs);
wrapper.appendChild(iframe);
embed.replaceWith(wrapper);
});
window.iFrameResize({ checkOrigin: false }, "[data-lookbook-embed-iframe]");
}
function createWrapper() {
const wrapper = document.createElement("div");
wrapper.setAttribute("data-lookbook-embed", "");
wrapper.classList.add("lookbook-embed");
return wrapper;
}
function createIframe(attrs) {
const src = buildSrc(attrs);
const id = attrValue(attrs, "id");
const styles = attrValue(attrs, "style");
const classes = attrValue(attrs, "class", "")
.split(" ")
.map((c) => c.trim())
.filter((c) => c.length);
const iframe = document.createElement("iframe");
iframe.src = src;
if (id) iframe.id = id;
iframe.setAttribute("frameborder", 0);
iframe.setAttribute("data-lookbook-embed-iframe", "");
if (classes.length) iframe.classList.add(...classes);
if (styles) iframe.style.cssText = styles;
iframe.style.width = "100%";
iframe.style.transition = "height 0.3s";
return iframe;
}
function buildSrc(attrs) {
const appPath = attrValue(attrs, "app") || guessBasePath();
const props = {};
permittedAttrs(attrs).forEach(({ name, value }) => {
name = name.replace("-", "_").toLowerCase();
props[name] = value;
});
return encodeURI(
[appPath, embedUrlPrefix].join("/") + `?props=${JSON.stringify(props)}`
);
}
function attrValue(attrs, name, fallback = null) {
const attr = attrs.find((attr) => attr.name === name);
return attr ? attr.value : fallback;
}
function permittedAttrs(attrs) {
return attrs.filter((attr) => {
return whiteListedAttributes.find((key) => {
const name = attr.name;
return (
key === name ||
(key.includes("*") && name.startsWith(key.replace("*", "")))
);
});
});
}
function guessBasePath() {
const script =
document.currentScript ||
document.querySelector('script[src*="lookbook.js"]');
const scriptSrc = script.src;
if (scriptSrc && scriptSrc.includes("lookbook-assets")) {
return scriptSrc
.split("?")[0]
.replace("lookbook-assets/js/lookbook.js", "lookbook");
}
return `//${location.host}/lookbook`;
}
document.addEventListener("DOMContentLoaded", () => initEmbeds());