@financial-times/custom-code-component 2.0.1-beta.13 → 2.0.1-beta.15
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/dist/custom-element.d.ts +5 -3
- package/dist/custom-element.js +216 -154
- package/dist/custom-element.js.map +1 -1
- package/package.json +1 -1
- package/src/custom-code-component.ts +76 -30
- package/src/events.ts +46 -4
- package/src/path.ts +9 -3
package/dist/custom-element.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
function
|
|
2
|
-
this.listenerMap = [{}, {}], o && this.root(o), this.handle =
|
|
1
|
+
function l(o) {
|
|
2
|
+
this.listenerMap = [{}, {}], o && this.root(o), this.handle = l.prototype.handle.bind(this), this._removedListeners = [];
|
|
3
3
|
}
|
|
4
|
-
|
|
4
|
+
l.prototype.root = function(o) {
|
|
5
5
|
const t = this.listenerMap;
|
|
6
6
|
let e;
|
|
7
7
|
if (this.rootElement) {
|
|
@@ -19,29 +19,29 @@ m.prototype.root = function(o) {
|
|
|
19
19
|
t[0].hasOwnProperty(e) && this.rootElement.addEventListener(e, this.handle, !1);
|
|
20
20
|
return this;
|
|
21
21
|
};
|
|
22
|
-
|
|
22
|
+
l.prototype.captureForType = function(o) {
|
|
23
23
|
return ["blur", "error", "focus", "load", "resize", "scroll"].indexOf(o) !== -1;
|
|
24
24
|
};
|
|
25
|
-
|
|
25
|
+
l.prototype.on = function(o, t, e, n) {
|
|
26
26
|
let r, s, i, c;
|
|
27
27
|
if (!o)
|
|
28
28
|
throw new TypeError("Invalid event type: " + o);
|
|
29
29
|
if (typeof t == "function" && (n = e, e = t, t = null), n === void 0 && (n = this.captureForType(o)), typeof e != "function")
|
|
30
30
|
throw new TypeError("Handler must be a type of Function");
|
|
31
|
-
return r = this.rootElement, s = this.listenerMap[n ? 1 : 0], s[o] || (r && r.addEventListener(o, this.handle, n), s[o] = []), t ? /^[a-z]+$/i.test(t) ? (c = t, i =
|
|
31
|
+
return r = this.rootElement, s = this.listenerMap[n ? 1 : 0], s[o] || (r && r.addEventListener(o, this.handle, n), s[o] = []), t ? /^[a-z]+$/i.test(t) ? (c = t, i = x) : /^#[a-z0-9\-_]+$/i.test(t) ? (c = t.slice(1), i = U) : (c = t, i = Element.prototype.matches) : (c = null, i = P.bind(this)), s[o].push({
|
|
32
32
|
selector: t,
|
|
33
33
|
handler: e,
|
|
34
34
|
matcher: i,
|
|
35
35
|
matcherParam: c
|
|
36
36
|
}), this;
|
|
37
37
|
};
|
|
38
|
-
|
|
39
|
-
let r, s, i, c,
|
|
38
|
+
l.prototype.off = function(o, t, e, n) {
|
|
39
|
+
let r, s, i, c, a;
|
|
40
40
|
if (typeof t == "function" && (n = e, e = t, t = null), n === void 0)
|
|
41
41
|
return this.off(o, t, e, !0), this.off(o, t, e, !1), this;
|
|
42
42
|
if (i = this.listenerMap[n ? 1 : 0], !o) {
|
|
43
|
-
for (
|
|
44
|
-
i.hasOwnProperty(
|
|
43
|
+
for (a in i)
|
|
44
|
+
i.hasOwnProperty(a) && this.off(a, t, e);
|
|
45
45
|
return this;
|
|
46
46
|
}
|
|
47
47
|
if (c = i[o], !c || !c.length)
|
|
@@ -50,46 +50,46 @@ m.prototype.off = function(o, t, e, n) {
|
|
|
50
50
|
s = c[r], (!t || t === s.selector) && (!e || e === s.handler) && (this._removedListeners.push(s), c.splice(r, 1));
|
|
51
51
|
return c.length || (delete i[o], this.rootElement && this.rootElement.removeEventListener(o, this.handle, n)), this;
|
|
52
52
|
};
|
|
53
|
-
|
|
53
|
+
l.prototype.handle = function(o) {
|
|
54
54
|
let t, e;
|
|
55
55
|
const n = o.type;
|
|
56
|
-
let r, s, i, c,
|
|
57
|
-
const
|
|
58
|
-
if (o[
|
|
56
|
+
let r, s, i, c, a = [], h;
|
|
57
|
+
const m = "ftLabsDelegateIgnore";
|
|
58
|
+
if (o[m] === !0)
|
|
59
59
|
return;
|
|
60
|
-
switch (
|
|
60
|
+
switch (h = o.target, h.nodeType === 3 && (h = h.parentNode), h.correspondingUseElement && (h = h.correspondingUseElement), r = this.rootElement, s = o.eventPhase || (o.target !== o.currentTarget ? 3 : 2), s) {
|
|
61
61
|
case 1:
|
|
62
|
-
|
|
62
|
+
a = this.listenerMap[1][n];
|
|
63
63
|
break;
|
|
64
64
|
case 2:
|
|
65
|
-
this.listenerMap[0] && this.listenerMap[0][n] && (
|
|
65
|
+
this.listenerMap[0] && this.listenerMap[0][n] && (a = a.concat(this.listenerMap[0][n])), this.listenerMap[1] && this.listenerMap[1][n] && (a = a.concat(this.listenerMap[1][n]));
|
|
66
66
|
break;
|
|
67
67
|
case 3:
|
|
68
|
-
|
|
68
|
+
a = this.listenerMap[0][n];
|
|
69
69
|
break;
|
|
70
70
|
}
|
|
71
|
-
let
|
|
72
|
-
for (e =
|
|
73
|
-
for (t = 0; t < e && (i =
|
|
74
|
-
|
|
75
|
-
if (
|
|
71
|
+
let p = [];
|
|
72
|
+
for (e = a.length; h && e; ) {
|
|
73
|
+
for (t = 0; t < e && (i = a[t], !!i); t++)
|
|
74
|
+
h.tagName && ["button", "input", "select", "textarea"].indexOf(h.tagName.toLowerCase()) > -1 && h.hasAttribute("disabled") ? p = [] : i.matcher.call(h, i.matcherParam, h) && p.push([o, h, i]);
|
|
75
|
+
if (h === r || (e = a.length, h = h.parentElement || h.parentNode, h instanceof HTMLDocument))
|
|
76
76
|
break;
|
|
77
77
|
}
|
|
78
|
-
let
|
|
79
|
-
for (t = 0; t <
|
|
80
|
-
if (!(this._removedListeners.indexOf(
|
|
81
|
-
|
|
78
|
+
let L;
|
|
79
|
+
for (t = 0; t < p.length; t++)
|
|
80
|
+
if (!(this._removedListeners.indexOf(p[t][2]) > -1) && (c = this.fire.apply(this, p[t]), c === !1)) {
|
|
81
|
+
p[t][0][m] = !0, p[t][0].preventDefault(), L = !1;
|
|
82
82
|
break;
|
|
83
83
|
}
|
|
84
|
-
return
|
|
84
|
+
return L;
|
|
85
85
|
};
|
|
86
|
-
|
|
86
|
+
l.prototype.fire = function(o, t, e) {
|
|
87
87
|
return e.handler.call(t, o, t);
|
|
88
88
|
};
|
|
89
|
-
function
|
|
89
|
+
function x(o, t) {
|
|
90
90
|
return o.toLowerCase() === t.tagName.toLowerCase();
|
|
91
91
|
}
|
|
92
|
-
function
|
|
92
|
+
function P(o, t) {
|
|
93
93
|
return this.rootElement === window ? (
|
|
94
94
|
// Match the outer document (dispatched from document)
|
|
95
95
|
t === document || // The <html> element (dispatched from document.body or document.documentElement)
|
|
@@ -97,20 +97,20 @@ function k(o, t) {
|
|
|
97
97
|
t === window
|
|
98
98
|
) : this.rootElement === t;
|
|
99
99
|
}
|
|
100
|
-
function
|
|
100
|
+
function U(o, t) {
|
|
101
101
|
return o === t.id;
|
|
102
102
|
}
|
|
103
|
-
|
|
103
|
+
l.prototype.destroy = function() {
|
|
104
104
|
this.off(), this.root();
|
|
105
105
|
};
|
|
106
|
-
function
|
|
106
|
+
function $(o) {
|
|
107
107
|
return typeof o == "string" ? o.trim() : o;
|
|
108
108
|
}
|
|
109
|
-
function
|
|
109
|
+
function C(o, t) {
|
|
110
110
|
for (const e in o)
|
|
111
111
|
t[e] ? console.warn(`You can't set a custom property called ${e}`) : t[e] = o[e];
|
|
112
112
|
}
|
|
113
|
-
const
|
|
113
|
+
const u = Object.freeze({
|
|
114
114
|
DEBUG: 0,
|
|
115
115
|
INFO: 1,
|
|
116
116
|
WARN: 2,
|
|
@@ -118,88 +118,88 @@ const p = Object.freeze({
|
|
|
118
118
|
TEST: 4,
|
|
119
119
|
DEFAULT: 2
|
|
120
120
|
});
|
|
121
|
-
function
|
|
121
|
+
function I(o) {
|
|
122
122
|
const t = o == null ? void 0 : o.toLowerCase();
|
|
123
|
-
return t === "debug" ?
|
|
123
|
+
return t === "debug" ? u.DEBUG : t === "info" ? u.INFO : t === "warn" ? u.WARN : t === "error" ? u.ERROR : t === "test" ? u.TEST : u.DEFAULT;
|
|
124
124
|
}
|
|
125
|
-
class
|
|
126
|
-
constructor({ level: t =
|
|
127
|
-
level:
|
|
125
|
+
class N {
|
|
126
|
+
constructor({ level: t = u.DEFAULT } = {
|
|
127
|
+
level: u.DEFAULT
|
|
128
128
|
}) {
|
|
129
129
|
this.log = this.debug, this.level = t;
|
|
130
130
|
}
|
|
131
131
|
debug(...t) {
|
|
132
|
-
this.level <=
|
|
132
|
+
this.level <= u.DEBUG && console.info(...t);
|
|
133
133
|
}
|
|
134
134
|
info(...t) {
|
|
135
|
-
this.level <=
|
|
135
|
+
this.level <= u.INFO && console.info(...t);
|
|
136
136
|
}
|
|
137
137
|
warn(...t) {
|
|
138
|
-
this.level <=
|
|
138
|
+
this.level <= u.WARN && console.warn(...t);
|
|
139
139
|
}
|
|
140
140
|
error(...t) {
|
|
141
|
-
this.level <=
|
|
141
|
+
this.level <= u.ERROR && console.error(...t);
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
|
-
const
|
|
144
|
+
const D = (o, t, e) => {
|
|
145
145
|
const n = Array.from((o == null ? void 0 : o.querySelectorAll(e)) ?? []), r = n.findIndex((s) => s === t);
|
|
146
146
|
if (r !== -1)
|
|
147
147
|
return {
|
|
148
148
|
siblings: n.length,
|
|
149
149
|
position: r
|
|
150
150
|
};
|
|
151
|
-
},
|
|
151
|
+
}, O = [
|
|
152
152
|
"nodeName",
|
|
153
153
|
"className",
|
|
154
154
|
"id",
|
|
155
155
|
"href",
|
|
156
156
|
"text",
|
|
157
157
|
"role"
|
|
158
|
-
],
|
|
158
|
+
], M = (o) => {
|
|
159
159
|
const t = {};
|
|
160
|
-
for (const e of
|
|
160
|
+
for (const e of O) {
|
|
161
161
|
const n = o[e] || o.getAttribute(e) || o.hasAttribute(e);
|
|
162
|
-
n !== void 0 && (typeof n == "boolean" ? t[e] = n : t[e] =
|
|
162
|
+
n !== void 0 && (typeof n == "boolean" ? t[e] = n : t[e] = $(n));
|
|
163
163
|
}
|
|
164
164
|
return t;
|
|
165
|
-
},
|
|
165
|
+
}, j = (o) => {
|
|
166
166
|
try {
|
|
167
167
|
const t = JSON.parse(o), e = Object.prototype.toString.call(t);
|
|
168
168
|
return [e === "[object Object]" || e === "[object Array]", t];
|
|
169
169
|
} catch {
|
|
170
170
|
return [!1, null];
|
|
171
171
|
}
|
|
172
|
-
},
|
|
173
|
-
const [t, e] =
|
|
172
|
+
}, _ = (o) => {
|
|
173
|
+
const [t, e] = j(o);
|
|
174
174
|
return t ? e : o;
|
|
175
|
-
},
|
|
175
|
+
}, F = (o, t) => (o.filter(
|
|
176
176
|
(e) => e.name.match(/^data-trackable|^data-o-|^aria-/i)
|
|
177
177
|
).forEach((e) => {
|
|
178
178
|
t[e.name] = e.value;
|
|
179
|
-
}), t),
|
|
179
|
+
}), t), H = (o, t, e) => {
|
|
180
180
|
const n = {};
|
|
181
|
-
return e &&
|
|
181
|
+
return e && O.forEach((r) => {
|
|
182
182
|
typeof t[r] < "u" && r !== "id" && (n[r] = t[r]);
|
|
183
183
|
}), o.filter((r) => r.name.match(/^data-trackable-context-/i)).forEach((r) => {
|
|
184
|
-
n[r.name.replace("data-trackable-context-", "")] =
|
|
184
|
+
n[r.name.replace("data-trackable-context-", "")] = _(r.value);
|
|
185
185
|
}), n;
|
|
186
186
|
};
|
|
187
|
-
function
|
|
187
|
+
function z(o, t) {
|
|
188
188
|
const e = o, n = e != null && e.getAttribute("data-trackable") ? `[data-trackable="${e.getAttribute("data-trackable")}"]` : e == null ? void 0 : e.nodeName, r = [], s = {};
|
|
189
189
|
for (; o && o !== t; ) {
|
|
190
|
-
const i =
|
|
191
|
-
let
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
)), r.push(
|
|
196
|
-
const
|
|
197
|
-
|
|
190
|
+
const i = M(o), c = Array.from(o.attributes);
|
|
191
|
+
let a = F(c, i);
|
|
192
|
+
a["data-trackable"] && (a = Object.assign(
|
|
193
|
+
a,
|
|
194
|
+
D(o, e, n)
|
|
195
|
+
)), r.push(a);
|
|
196
|
+
const h = H(c, i, o === e);
|
|
197
|
+
C(h, s), o = o.parentNode;
|
|
198
198
|
}
|
|
199
199
|
return { trace: r, customContext: s };
|
|
200
200
|
}
|
|
201
|
-
const
|
|
202
|
-
class
|
|
201
|
+
const V = ["ctrlKey", "altKey", "shiftKey", "metaKey"];
|
|
202
|
+
class Y {
|
|
203
203
|
constructor({
|
|
204
204
|
id: t = "00000000-0000-0000-0000-000000000000",
|
|
205
205
|
name: e = "ccc-component",
|
|
@@ -208,17 +208,17 @@ class _ {
|
|
|
208
208
|
shadowRoot: s = null,
|
|
209
209
|
category: i = "cta",
|
|
210
210
|
elements: c = 'a, button, input, [role="button"]',
|
|
211
|
-
logger:
|
|
211
|
+
logger: a
|
|
212
212
|
}) {
|
|
213
|
-
this.cccId = t, this.cccName = e, this.subtype = n, this.teamName = r, this.shadowRoot = s, this.category = i, this.elements = c, this.isInitialised = !1, this.log =
|
|
213
|
+
this.cccId = t, this.cccName = e, this.subtype = n, this.teamName = r, this.shadowRoot = s, this.category = i, this.elements = c, this.isInitialised = !1, this.log = a ?? new N();
|
|
214
214
|
}
|
|
215
215
|
// Get properties for the event (as opposed to properties of the clicked element)
|
|
216
216
|
getEventProperties(t) {
|
|
217
217
|
const e = {};
|
|
218
|
-
for (const n of
|
|
218
|
+
for (const n of V)
|
|
219
219
|
if (t[n])
|
|
220
220
|
try {
|
|
221
|
-
e[n] =
|
|
221
|
+
e[n] = $(t[n]);
|
|
222
222
|
} catch (r) {
|
|
223
223
|
this.log.info(r);
|
|
224
224
|
}
|
|
@@ -227,13 +227,13 @@ class _ {
|
|
|
227
227
|
// Controller for handling click events
|
|
228
228
|
handleClickEvent(t, e) {
|
|
229
229
|
return (n, r) => {
|
|
230
|
-
const s = this.getEventProperties(n), { trace: i, customContext: c } =
|
|
230
|
+
const s = this.getEventProperties(n), { trace: i, customContext: c } = z(r, e);
|
|
231
231
|
s.custom = r.dataset && r.dataset.custom ? JSON.parse(r.dataset.custom) : null, s.domPathTokens = i, s.component = {
|
|
232
232
|
id: this.cccId,
|
|
233
233
|
name: this.cccName,
|
|
234
234
|
type: "custom-code-component",
|
|
235
235
|
subtype: this.subtype
|
|
236
|
-
}, s.teamName = this.teamName, s.url = document.URL,
|
|
236
|
+
}, s.teamName = this.teamName, s.url = document.URL, C(c, s), s.method = "ftCustomAnalytics", t = { ...t, ...s }, document.body.dispatchEvent(
|
|
237
237
|
new CustomEvent("oTracking.event", {
|
|
238
238
|
detail: t,
|
|
239
239
|
bubbles: !0,
|
|
@@ -273,7 +273,7 @@ class _ {
|
|
|
273
273
|
action: "click",
|
|
274
274
|
category: this.category
|
|
275
275
|
}, r = (e = this.shadowRoot) == null ? void 0 : e.querySelector("[data-component-root]");
|
|
276
|
-
r && new
|
|
276
|
+
r && new l(r).on(
|
|
277
277
|
"click",
|
|
278
278
|
this.elements,
|
|
279
279
|
this.handleClickEvent(n, r),
|
|
@@ -285,28 +285,32 @@ class _ {
|
|
|
285
285
|
class f {
|
|
286
286
|
constructor(t) {
|
|
287
287
|
this.org = "local", this.repo = "dev";
|
|
288
|
-
const { org: e, repo: n, name: r, versionRange: s } =
|
|
288
|
+
const { org: e, repo: n, name: r, versionRange: s } = S(t) ? t : f.fromString(t);
|
|
289
289
|
e && (this.org = e), n && (this.repo = n), this.name = r, this.versionRange = s;
|
|
290
290
|
}
|
|
291
291
|
set path(t) {
|
|
292
|
-
const { org: e, repo: n, name: r, versionRange: s } =
|
|
292
|
+
const { org: e, repo: n, name: r, versionRange: s } = S(t) ? t : f.fromString(t);
|
|
293
293
|
this.org = e, this.repo = n, this.name = r, this.versionRange = s;
|
|
294
294
|
}
|
|
295
295
|
get path() {
|
|
296
296
|
return `${this.org}/${this.repo}@${this.versionRange}/${this.name}`;
|
|
297
297
|
}
|
|
298
|
+
get isValid() {
|
|
299
|
+
return [this.org, this.repo, this.name].every(
|
|
300
|
+
(t) => t !== "unknown"
|
|
301
|
+
);
|
|
302
|
+
}
|
|
298
303
|
toString() {
|
|
299
304
|
return this.path;
|
|
300
305
|
}
|
|
301
306
|
static fromString(t, e) {
|
|
302
|
-
var
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
return new f({ org: s, repo: r, name: n, versionRange: i });
|
|
307
|
+
var a;
|
|
308
|
+
const n = t ?? "unknown/unknown/unknown", [r, s, i] = n.replace(/@[^\/]+/, "").split("/").reverse(), c = e ?? ((a = n.match(/@[^\/]+/)) == null ? void 0 : a.toString().replace("@", "")) ?? "unknown";
|
|
309
|
+
if (s && !c) throw new d("No version specified");
|
|
310
|
+
return new f({ org: i, repo: s, name: r, versionRange: c });
|
|
307
311
|
}
|
|
308
312
|
}
|
|
309
|
-
function
|
|
313
|
+
function S(o) {
|
|
310
314
|
return typeof o == "object" && o !== null ? "org" in o && "repo" in o && "name" in o : !1;
|
|
311
315
|
}
|
|
312
316
|
class d extends Error {
|
|
@@ -314,85 +318,106 @@ class d extends Error {
|
|
|
314
318
|
var n;
|
|
315
319
|
!e && t ? (super(t), this.component = null) : typeof (e == null ? void 0 : e.component) == "string" ? (super(
|
|
316
320
|
t ?? `${e.cause ?? "Unknown error"} in ${e.component} imported from ${e.source ?? "an undefined source"}.`
|
|
317
|
-
), this.component = f.fromString(e.component)) :
|
|
321
|
+
), this.component = f.fromString(e.component)) : S(e == null ? void 0 : e.component) ? (super(
|
|
318
322
|
t ?? `${e.cause ?? "Unknown error"} in ${e.component.org}/${e.component.repo}/${e.component.name}@${e.component.versionRange} imported from ${e.source ?? "an undefined source"}.`
|
|
319
323
|
), this.component = new f(e.component)) : (super(
|
|
320
324
|
`${(e == null ? void 0 : e.cause) ?? "Unknown error"} in unknown component imported from ${(e == null ? void 0 : e.source) ?? "unknown source"}.`
|
|
321
325
|
), this.component = null), this.source = (e == null ? void 0 : e.source) ?? "unknown source", this.errors = [], e != null && e.error && ((n = this.errors) == null || n.push(e == null ? void 0 : e.error)), Error.captureStackTrace && Error.captureStackTrace(this, d), this.name = "CCCError";
|
|
322
326
|
}
|
|
323
327
|
}
|
|
324
|
-
class
|
|
328
|
+
class w extends d {
|
|
325
329
|
constructor(t, e) {
|
|
326
330
|
super(t, { ...e, cause: "Import error" }), this.name = "CCCImportError";
|
|
327
331
|
}
|
|
328
332
|
}
|
|
329
|
-
class
|
|
333
|
+
class q extends d {
|
|
330
334
|
constructor(t, e) {
|
|
331
335
|
super(t, { ...e, cause: "Render error" }), this.name = "CCCRenderError";
|
|
332
336
|
}
|
|
333
337
|
}
|
|
334
|
-
class
|
|
338
|
+
class J extends d {
|
|
335
339
|
constructor(t) {
|
|
336
340
|
super(null, { ...t, cause: "Timeout error" }), this.name = "CCCTimeoutError";
|
|
337
341
|
}
|
|
338
342
|
}
|
|
339
|
-
const
|
|
340
|
-
constructor(t, e) {
|
|
341
|
-
super(
|
|
343
|
+
const b = class b extends Event {
|
|
344
|
+
constructor(t = b.eventType, e, n) {
|
|
345
|
+
super(t, {
|
|
342
346
|
bubbles: !0,
|
|
343
347
|
cancelable: !1,
|
|
344
348
|
composed: !0,
|
|
345
|
-
...
|
|
346
|
-
}), this.component =
|
|
349
|
+
...n
|
|
350
|
+
}), this.component = e.component, this.source = e.source;
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
b.eventType = "ccc:event";
|
|
354
|
+
let g = b;
|
|
355
|
+
const y = class y extends g {
|
|
356
|
+
constructor(t, e) {
|
|
357
|
+
super(y.eventType, t, e);
|
|
347
358
|
}
|
|
348
359
|
};
|
|
349
|
-
|
|
350
|
-
let
|
|
351
|
-
const
|
|
360
|
+
y.eventType = "ccc:connected";
|
|
361
|
+
let T = y;
|
|
362
|
+
const E = class E extends g {
|
|
363
|
+
constructor(t, e) {
|
|
364
|
+
super(E.eventType, t, e);
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
E.eventType = "ccc:ready";
|
|
368
|
+
let k = E;
|
|
369
|
+
const v = class v extends g {
|
|
370
|
+
constructor(t, e) {
|
|
371
|
+
super(v.eventType, t, e), this.intersecting = !1, this.intersecting = t.intersecting, this.entry = t.entry;
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
v.eventType = "ccc:viewport";
|
|
375
|
+
let R = v;
|
|
376
|
+
const W = (o) => o.replace(
|
|
352
377
|
/[A-Z]+(?![a-z])|[A-Z]/g,
|
|
353
378
|
(t, e) => (e ? "-" : "") + t.toLowerCase()
|
|
354
379
|
);
|
|
355
|
-
function
|
|
356
|
-
return
|
|
380
|
+
function G(o) {
|
|
381
|
+
return A([
|
|
357
382
|
"localhost",
|
|
358
383
|
"local.ft.com",
|
|
359
384
|
/^.*\.apps\.in\.ft\.com$/
|
|
360
385
|
], o);
|
|
361
386
|
}
|
|
362
|
-
function
|
|
363
|
-
return
|
|
387
|
+
function K() {
|
|
388
|
+
return A([
|
|
364
389
|
"localhost",
|
|
365
390
|
"local.ft.com",
|
|
366
391
|
/^.*\.in\.ft\.com$/
|
|
367
392
|
], window.location.hostname);
|
|
368
393
|
}
|
|
369
|
-
function
|
|
370
|
-
return
|
|
394
|
+
function B() {
|
|
395
|
+
return A([
|
|
371
396
|
"spark.ft.com",
|
|
372
397
|
"spark-staging.ft.com"
|
|
373
398
|
], window.location.host);
|
|
374
399
|
}
|
|
375
|
-
function
|
|
400
|
+
function A(o, t) {
|
|
376
401
|
return t ? o.some((e) => typeof e == "string" ? e === t : e.test(t)) : !1;
|
|
377
402
|
}
|
|
378
|
-
function
|
|
403
|
+
function Z(o) {
|
|
379
404
|
if (o === null)
|
|
380
405
|
return;
|
|
381
406
|
let t;
|
|
382
407
|
const e = new URL("http://localhost:5173");
|
|
383
408
|
try {
|
|
384
409
|
if (typeof o == "string") {
|
|
385
|
-
if ((o === "" || o.toLowerCase() === "true") &&
|
|
410
|
+
if ((o === "" || o.toLowerCase() === "true") && K())
|
|
386
411
|
t = e;
|
|
387
|
-
else if (t = o.startsWith("http://") || o.startsWith("https://") ? new URL(o) : void 0, t && !
|
|
412
|
+
else if (t = o.startsWith("http://") || o.startsWith("https://") ? new URL(o) : void 0, t && !G(t == null ? void 0 : t.hostname))
|
|
388
413
|
throw new Error("Unsafe testing host override");
|
|
389
|
-
} else
|
|
414
|
+
} else B() && (t = e);
|
|
390
415
|
} catch {
|
|
391
416
|
return t;
|
|
392
417
|
}
|
|
393
418
|
return t;
|
|
394
419
|
}
|
|
395
|
-
async function
|
|
420
|
+
async function Q(o, t) {
|
|
396
421
|
return t ? fetch(
|
|
397
422
|
new URL(`src/${o}/config.yaml`, t),
|
|
398
423
|
{
|
|
@@ -400,8 +425,8 @@ async function J(o, t) {
|
|
|
400
425
|
}
|
|
401
426
|
).then(() => !0).catch(() => !1) : !1;
|
|
402
427
|
}
|
|
403
|
-
const
|
|
404
|
-
class
|
|
428
|
+
const X = ":host{width:var(--ccc-root-width, 100%);margin:var(--ccc-root-margin);padding:var(--ccc-root-padding);display:var(--ccc-root-display, block);font-size:var(--ccc-root-fontSize);box-sizing:var(--ccc-root-boxSizing);border:var(--ccc-root-border);grid:var(--ccc-root-grid);line-height:var(--ccc-root-lineHeight)}";
|
|
429
|
+
class tt extends HTMLElement {
|
|
405
430
|
constructor() {
|
|
406
431
|
super(), this.mode = "open", this.RESERVED_ATTRS = /* @__PURE__ */ new Set([
|
|
407
432
|
"iframe",
|
|
@@ -412,7 +437,18 @@ class G extends HTMLElement {
|
|
|
412
437
|
"shadow-open",
|
|
413
438
|
"env",
|
|
414
439
|
"load-timeout"
|
|
415
|
-
]), this.
|
|
440
|
+
]), this.component = new f(), this.observer = new IntersectionObserver((e) => {
|
|
441
|
+
e.forEach((n) => {
|
|
442
|
+
this.dispatchEvent(
|
|
443
|
+
new R({
|
|
444
|
+
component: this.component,
|
|
445
|
+
source: this.source,
|
|
446
|
+
intersecting: n.isIntersecting,
|
|
447
|
+
entry: n
|
|
448
|
+
})
|
|
449
|
+
);
|
|
450
|
+
});
|
|
451
|
+
}), this.channel = new MessageChannel(), this.initTracking = async () => {
|
|
416
452
|
var e;
|
|
417
453
|
try {
|
|
418
454
|
(e = this.tracking) == null || e.init(this.id);
|
|
@@ -435,8 +471,8 @@ class G extends HTMLElement {
|
|
|
435
471
|
`.trim(), document.head.appendChild(e);
|
|
436
472
|
const n = document.createElement("script");
|
|
437
473
|
n.type = "module", n.src = `${(s = this.testUrl) == null ? void 0 : s.origin}/@vite/client`, document.head.appendChild(n);
|
|
438
|
-
}, this.log = new
|
|
439
|
-
level:
|
|
474
|
+
}, this.log = new N({
|
|
475
|
+
level: I(this.getAttribute("log"))
|
|
440
476
|
});
|
|
441
477
|
const t = HTMLElement.prototype.hasOwnProperty("attachInternals");
|
|
442
478
|
try {
|
|
@@ -456,17 +492,35 @@ class G extends HTMLElement {
|
|
|
456
492
|
}
|
|
457
493
|
}
|
|
458
494
|
emitError(t) {
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
495
|
+
if (t instanceof d)
|
|
496
|
+
this.dispatchEvent(
|
|
497
|
+
new ErrorEvent("ccc:error", {
|
|
498
|
+
bubbles: !0,
|
|
499
|
+
cancelable: !1,
|
|
500
|
+
composed: !0,
|
|
501
|
+
error: t,
|
|
502
|
+
message: t.message
|
|
503
|
+
})
|
|
504
|
+
);
|
|
505
|
+
else {
|
|
506
|
+
const e = new d(t.message, {
|
|
507
|
+
component: this.component,
|
|
508
|
+
error: t
|
|
509
|
+
});
|
|
510
|
+
this.dispatchEvent(
|
|
511
|
+
new ErrorEvent("ccc:error", {
|
|
512
|
+
bubbles: !0,
|
|
513
|
+
cancelable: !1,
|
|
514
|
+
composed: !0,
|
|
515
|
+
error: e,
|
|
516
|
+
message: e.message
|
|
517
|
+
})
|
|
518
|
+
);
|
|
519
|
+
}
|
|
466
520
|
}
|
|
467
521
|
disconnectedCallback() {
|
|
468
522
|
const t = this.getAttribute("path");
|
|
469
|
-
this.log.info(`<custom-code-component:${t}> disconnected`), typeof this.onunmount == "function" && this.onunmount();
|
|
523
|
+
this.log.info(`<custom-code-component:${t}> disconnected`), typeof this.onunmount == "function" && this.onunmount(), this.observer.disconnect();
|
|
470
524
|
}
|
|
471
525
|
onmessage() {
|
|
472
526
|
}
|
|
@@ -474,10 +528,15 @@ class G extends HTMLElement {
|
|
|
474
528
|
}
|
|
475
529
|
async onready(t) {
|
|
476
530
|
try {
|
|
477
|
-
await t
|
|
531
|
+
await t, this.dispatchEvent(
|
|
532
|
+
new k({
|
|
533
|
+
component: this.component,
|
|
534
|
+
source: this.source
|
|
535
|
+
})
|
|
536
|
+
), this.dataset.cccReady = "true", delete this.dataset.cccError, this.observer.observe(this);
|
|
478
537
|
} catch (e) {
|
|
479
538
|
if (e instanceof Error) {
|
|
480
|
-
const n = new
|
|
539
|
+
const n = new q(e.message, {
|
|
481
540
|
error: e,
|
|
482
541
|
component: this.component
|
|
483
542
|
});
|
|
@@ -494,24 +553,24 @@ class G extends HTMLElement {
|
|
|
494
553
|
var e, n;
|
|
495
554
|
try {
|
|
496
555
|
if (this.mode = this.getAttribute("shadow-open") == "false" ? "closed" : "open", this.component) {
|
|
556
|
+
if (!this.app)
|
|
557
|
+
throw new Error("CCC mounted without App");
|
|
558
|
+
const r = this.shadowRoot !== null, s = this.shadowRoot ?? this.attachShadow({ mode: this.mode });
|
|
497
559
|
if (this.dispatchEvent(
|
|
498
|
-
new
|
|
560
|
+
new T({
|
|
499
561
|
component: this.component,
|
|
500
562
|
source: this.source
|
|
501
563
|
})
|
|
502
|
-
),
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
if (!s.querySelector('link[href~="custom-code-component.css"]') && !s.adoptedStyleSheets.length && (window.CCC_LAYOUT_STYLESHEET || (window.CCC_LAYOUT_STYLESHEET = new CSSStyleSheet(), window.CCC_LAYOUT_STYLESHEET.replaceSync(W)), s.adoptedStyleSheets = [window.CCC_LAYOUT_STYLESHEET]), !r) {
|
|
506
|
-
const u = document.createElement("template");
|
|
507
|
-
u.innerHTML = "<div data-component-root><slot></slot></div>", this.appendChild(u), s.appendChild(u.content.cloneNode(!0));
|
|
564
|
+
), !s.querySelector('link[href~="custom-code-component.css"]') && !s.adoptedStyleSheets.length && (window.CCC_LAYOUT_STYLESHEET || (window.CCC_LAYOUT_STYLESHEET = new CSSStyleSheet(), window.CCC_LAYOUT_STYLESHEET.replaceSync(X)), s.adoptedStyleSheets = [window.CCC_LAYOUT_STYLESHEET]), !r) {
|
|
565
|
+
const p = document.createElement("template");
|
|
566
|
+
p.innerHTML = "<div data-component-root><slot></slot></div>", this.appendChild(p), s.appendChild(p.content.cloneNode(!0));
|
|
508
567
|
}
|
|
509
568
|
const i = JSON.parse(this.getAttribute("data-component-props")), c = Object.fromEntries(
|
|
510
569
|
[...this.attributes].filter(
|
|
511
|
-
(
|
|
512
|
-
).map((
|
|
570
|
+
(p) => !this.RESERVED_ATTRS.has(p.name) && !p.name.startsWith("data-")
|
|
571
|
+
).map((p) => [p.name, p.value])
|
|
513
572
|
);
|
|
514
|
-
this.tracking = new
|
|
573
|
+
this.tracking = new Y({
|
|
515
574
|
name: (e = this.component) == null ? void 0 : e.toString(),
|
|
516
575
|
subtype: "interactive",
|
|
517
576
|
teamName: "djd",
|
|
@@ -526,7 +585,7 @@ class G extends HTMLElement {
|
|
|
526
585
|
"text-decoration: underline;",
|
|
527
586
|
" attribute instead."
|
|
528
587
|
));
|
|
529
|
-
const { unmount:
|
|
588
|
+
const { unmount: a, onmessage: h, ready: m } = this.app(
|
|
530
589
|
s,
|
|
531
590
|
{
|
|
532
591
|
...i ?? c,
|
|
@@ -538,7 +597,7 @@ class G extends HTMLElement {
|
|
|
538
597
|
},
|
|
539
598
|
r
|
|
540
599
|
) || {};
|
|
541
|
-
|
|
600
|
+
a && (this.onunmount = a), h && (this.onmessage = h), m && this.onready(m);
|
|
542
601
|
}
|
|
543
602
|
} catch (r) {
|
|
544
603
|
throw this.log.info(
|
|
@@ -555,22 +614,25 @@ class G extends HTMLElement {
|
|
|
555
614
|
const e = this.querySelector(
|
|
556
615
|
"template[data-component-fallback]"
|
|
557
616
|
) ?? this.querySelector("template");
|
|
558
|
-
e && ((n = this.shadowRoot) == null || n.replaceChildren(e.content.cloneNode(!0))), this.dataset.cccError || (this.dataset.cccError =
|
|
617
|
+
e && ((n = this.shadowRoot) == null || n.replaceChildren(e.content.cloneNode(!0))), this.dataset.cccError || (this.dataset.cccError = W(t.name.replace("CCC", ""))), delete this.dataset.cccReady, this.observer.disconnect();
|
|
559
618
|
}
|
|
560
619
|
async load() {
|
|
561
620
|
var c;
|
|
562
|
-
if (!this.component)
|
|
621
|
+
if (!this.component.isValid)
|
|
563
622
|
throw new Error("No path found");
|
|
564
623
|
const t = this.getAttribute("path"), e = this.getAttribute("version"), n = Number(this.getAttribute("load-timeout") || 1e4), r = this.getAttribute("test-env");
|
|
565
|
-
this.testUrl =
|
|
566
|
-
const s = await
|
|
624
|
+
this.testUrl = Z(r);
|
|
625
|
+
const s = await Q(
|
|
626
|
+
this.component.name,
|
|
627
|
+
this.testUrl
|
|
628
|
+
), i = this.getAttribute("id");
|
|
567
629
|
s && this.testUrl && this.injectViteScripts(), this.source = s ? `${(c = this.testUrl) == null ? void 0 : c.origin}/src/${this.component.name}/index.jsx?id=${i}` : `https://www.ft.com/__component/${this.component.org}/${this.component.repo}${e ? `@${e}` : "@latest"}/${this.component.name}/${this.component.name}.js?id=${i}`;
|
|
568
630
|
try {
|
|
569
631
|
return await new Promise(
|
|
570
|
-
(
|
|
571
|
-
const
|
|
572
|
-
this.log.error("CCC import timeout error"),
|
|
573
|
-
new
|
|
632
|
+
(a, h) => {
|
|
633
|
+
const m = setTimeout(() => {
|
|
634
|
+
this.log.error("CCC import timeout error"), h(
|
|
635
|
+
new J({
|
|
574
636
|
component: this.component,
|
|
575
637
|
source: this.source
|
|
576
638
|
})
|
|
@@ -581,40 +643,40 @@ class G extends HTMLElement {
|
|
|
581
643
|
/* webpackIgnore: true */
|
|
582
644
|
this.source
|
|
583
645
|
/* @vite-ignore */
|
|
584
|
-
).then(({ default:
|
|
585
|
-
if (
|
|
586
|
-
clearTimeout(
|
|
646
|
+
).then(({ default: p }) => {
|
|
647
|
+
if (p)
|
|
648
|
+
clearTimeout(m), a(p);
|
|
587
649
|
else
|
|
588
|
-
throw new
|
|
650
|
+
throw new w(
|
|
589
651
|
"No component renderer default export found",
|
|
590
652
|
{
|
|
591
653
|
component: this.component,
|
|
592
654
|
source: this.source
|
|
593
655
|
}
|
|
594
656
|
);
|
|
595
|
-
}).catch((
|
|
596
|
-
clearTimeout(
|
|
597
|
-
new
|
|
657
|
+
}).catch((p) => {
|
|
658
|
+
clearTimeout(m), this.log.error(p), p instanceof Error && !(p instanceof w) ? h(
|
|
659
|
+
new w(p.message, {
|
|
598
660
|
component: this.component,
|
|
599
661
|
source: this.source
|
|
600
662
|
})
|
|
601
|
-
) :
|
|
663
|
+
) : h(p);
|
|
602
664
|
});
|
|
603
665
|
else
|
|
604
|
-
throw clearTimeout(
|
|
666
|
+
throw clearTimeout(m), new w(`Unable to mount ${t}`, {
|
|
605
667
|
component: this.component,
|
|
606
668
|
source: this.source
|
|
607
669
|
});
|
|
608
670
|
}
|
|
609
671
|
);
|
|
610
|
-
} catch (
|
|
672
|
+
} catch (a) {
|
|
611
673
|
throw this.log.error(
|
|
612
674
|
`<custom-code-component> error during import from ${t}@${e}`
|
|
613
|
-
),
|
|
675
|
+
), a;
|
|
614
676
|
}
|
|
615
677
|
}
|
|
616
678
|
}
|
|
617
679
|
export {
|
|
618
|
-
|
|
680
|
+
tt as FTCustomCodeComponent
|
|
619
681
|
};
|
|
620
682
|
//# sourceMappingURL=custom-element.js.map
|