-
Notifications
You must be signed in to change notification settings - Fork 6.2k
Expand file tree
/
Copy pathsnackPlayerInitializer.ts
More file actions
99 lines (87 loc) · 2.78 KB
/
Copy pathsnackPlayerInitializer.ts
File metadata and controls
99 lines (87 loc) · 2.78 KB
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
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
export default (() => {
if (!ExecutionEnvironment.canUseDOM) {
return null;
}
const updateSnacksTheme = () => {
const theme = document.querySelector('html').dataset.theme;
document.querySelectorAll('.snack-player').forEach(snack => {
(snack as HTMLElement).dataset.snackTheme = theme;
});
};
const initSnackPlayers = () => {
updateSnacksTheme();
window?.ExpoSnack?.initialize();
};
const setupTabPanelsMutationObservers = () => {
const tabPanels = document.querySelectorAll('[role=tabpanel]');
tabPanels.forEach(tabPanel => {
new MutationObserver(() => {
initSnackPlayers();
}).observe(tabPanel, {childList: true});
});
};
if (document.readyState === 'complete') {
updateSnacksTheme();
setupTabPanelsMutationObservers();
} else {
document.addEventListener('readystatechange', () => {
if (document.readyState === 'complete') {
updateSnacksTheme();
setupTabPanelsMutationObservers();
}
});
}
// Reset snack iframes on theme changes to sync theme
// Hacky, but no better solution for now
// see https://github.com/expo/snack/blob/main/website/src/client/components/EmbedCode.tsx#L61
const setupThemeSynchronization = () => {
new MutationObserver(() => {
if ('ExpoSnack' in window) {
document.querySelectorAll('.snack-player').forEach(container => {
updateSnacksTheme();
window?.ExpoSnack?.remove(container);
window?.ExpoSnack?.append(container);
});
}
}).observe(document.getElementsByTagName('html')[0], {
attributeFilter: ['data-theme'],
attributes: true,
childList: false,
subtree: false,
});
};
const setupSnackObserver = () => {
const observer = new MutationObserver(() => {
const snacks = document.body.querySelectorAll('.snack-player');
if (snacks.length) {
initSnackPlayers();
}
});
// Homepage or Showcase pages does not use MDX content, so `.container` node is not present there
const mdxContentContainer = document.body.querySelector('.container');
if (mdxContentContainer) {
observer.observe(mdxContentContainer, {
childList: true,
subtree: true,
});
}
};
// Need to set the theme before the snack script (deferred) initialize
updateSnacksTheme();
setupSnackObserver();
setupThemeSynchronization();
return {
onRouteDidUpdate() {
initSnackPlayers();
setupSnackObserver();
setupTabPanelsMutationObservers();
},
};
})();