-
Notifications
You must be signed in to change notification settings - Fork 1
/
block-editor-classes.js
105 lines (93 loc) · 3.43 KB
/
block-editor-classes.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
/* global wp, tailwindTypographyClasses */
/**
* This file adds front-end post title and Tailwind Typography classes to the
* block editor. It also adds some helper classes so you can access the post
* type when modifying the block editor’s appearance.
*
* To see this integrated in _tw, please review:
* https://github.com/gregsullivan/_tw
*/
// Set our target classes and the classes we’ll add to them.
var targetClasses = {
'edit-post-visual-editor__post-title-wrapper': ['entry-header'],
'wp-block-post-title': ['entry-title'],
'wp-block-post-content': ['entry-content', ...tailwindTypographyClasses],
}
wp.domReady(() => {
// Add the necessary Tailwind Typography classes to the block editor.
addTypographyClasses()
})
/**
* Get the class for the current post type from the `body` element. (We would
* use `wp.data`, but it doesn't work reliably both inside and outside of the
* post editor `iframe`.)
*/
function getCurrentPostTypeClass() {
let currentClass = null
for (const classToCheck of document.body.classList) {
if (classToCheck.startsWith('post-type-')) {
currentClass = classToCheck
break
}
}
return currentClass
}
/**
* Because Gutenberg’s `isEditorReady` function remains unstable,
* we’ll use an interval to watch for the arrival of the elements we need.
*/
function addTypographyClasses() {
const editorLoadedInterval = setInterval(function () {
// Wait until elements with all target classes are present.
if (
Object.keys(targetClasses).every(
(className) => document.getElementsByClassName(className).length
)
) {
if (getCurrentPostTypeClass()) {
// Add the post type class throughout.
Object.values(targetClasses).forEach((className) =>
className.push(getCurrentPostTypeClass())
)
}
// Add the classes before creating the mutation observer.
Object.entries(targetClasses).forEach(([targetClass, classes]) => {
document.getElementsByClassName(targetClass)[0].classList.add(...classes)
})
// Add mutation observers to each element.
Object.keys(targetClasses).forEach((className) => {
mutationObserver.observe(document.querySelector('.' + className), {
attributes: true,
attributeFilter: ['class'],
})
})
// Stop the interval.
clearInterval(editorLoadedInterval)
} else if (document.getElementsByName('editor-canvas').length) {
// If the block editor has been loaded in an iframe, and this code
// is running outside of that iframe, stop the interval. (This code
// will run again inside the iframe.)
clearInterval(editorLoadedInterval)
}
}, 40)
}
/**
* We need to ensure the class names we add are added again if the React
* component is updated, removing them in the process. The mutation observer
* below will check for the needed classes and add them if they’ve been
* removed.
*/
const mutationObserver = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
const classList = mutation.target.classList
Object.entries(targetClasses).forEach(([targetClass, classes]) => {
if (classList.contains(targetClass)) {
// Check whether all added classes are present.
if (!classes.every((className) => classList.contains(className))) {
// Add them again if they’re not.
classList.add(...classes)
}
}
})
})
})