forked from mastodon/mastodon
-
Notifications
You must be signed in to change notification settings - Fork 184
/
embed.js
130 lines (100 loc) · 3.46 KB
/
embed.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
126
127
128
129
130
// @ts-check
const allowedPrefixes = (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT' && document.currentScript.dataset.allowedPrefixes) ? document.currentScript.dataset.allowedPrefixes.split(' ') : [];
(function () {
'use strict';
/**
* @param {() => void} loaded
*/
var ready = function (loaded) {
if (document.readyState === 'complete') {
loaded();
} else {
document.addEventListener('readystatechange', function () {
if (document.readyState === 'complete') {
loaded();
}
});
}
};
/**
* @param {Map} map
*/
var generateId = function (map) {
var id = 0, failCount = 0, idBuffer = new Uint32Array(1);
while (id === 0 || map.has(id)) {
id = crypto.getRandomValues(idBuffer)[0];
failCount++;
if (failCount > 100) {
// give up and assign (easily guessable) unique number if getRandomValues is broken or no luck
id = -(map.size + 1);
break;
}
}
return id;
};
ready(function () {
/** @type {Map<number, HTMLQuoteElement | HTMLIFrameElement>} */
var embeds = new Map();
window.addEventListener('message', function (e) {
var data = e.data || {};
if (typeof data !== 'object' || data.type !== 'setHeight' || !embeds.has(data.id)) {
return;
}
var embed = embeds.get(data.id);
if (embed instanceof HTMLIFrameElement) {
embed.height = data.height;
}
if (embed instanceof HTMLQuoteElement) {
var iframe = embed.querySelector('iframe');
if (!iframe || ('source' in e && iframe.contentWindow !== e.source)) {
return;
}
iframe.height = data.height;
var placeholder = embed.querySelector('a');
if (!placeholder) return;
embed.removeChild(placeholder);
}
});
// Legacy embeds
document.querySelectorAll('iframe.mastodon-embed').forEach(iframe => {
var id = generateId(embeds);
embeds.set(id, iframe);
iframe.allow = 'fullscreen';
iframe.sandbox = 'allow-scripts allow-same-origin';
iframe.style.border = 0;
iframe.style.overflow = 'hidden';
iframe.style.display = 'block';
iframe.onload = function () {
iframe.contentWindow.postMessage({
type: 'setHeight',
id: id,
}, '*');
};
iframe.onload(); // In case the script is executing after the iframe has already loaded
});
// New generation of embeds
document.querySelectorAll('blockquote.mastodon-embed').forEach(container => {
var id = generateId(embeds);
embeds.set(id, container);
var iframe = document.createElement('iframe');
var embedUrl = new URL(container.getAttribute('data-embed-url'));
if (embedUrl.protocol !== 'https:' && embedUrl.protocol !== 'http:') return;
if (allowedPrefixes.every((allowedPrefix) => !embedUrl.toString().startsWith(allowedPrefix))) return;
iframe.src = embedUrl.toString();
iframe.width = container.clientWidth;
iframe.height = 0;
iframe.allow = 'fullscreen';
iframe.sandbox = 'allow-scripts allow-same-origin';
iframe.style.border = 0;
iframe.style.overflow = 'hidden';
iframe.style.display = 'block';
iframe.onload = function () {
iframe.contentWindow.postMessage({
type: 'setHeight',
id: id,
}, '*');
};
container.appendChild(iframe);
});
});
})();