-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmangadex-inline-comments.user.js
184 lines (152 loc) · 6.12 KB
/
mangadex-inline-comments.user.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
// ==UserScript==
// @name MangaDex Inline Comments
// @namespace metapone
// @version 0.2.1
// @description Display chapter comments inside MangaDex's sidebar
// @author metapone
// @license GPL-2.0-only; https://opensource.org/licenses/GPL-2.0
// @homepage https://github.com/metapone/userscript-collection
// @supportURL https://github.com/metapone/userscript-collection/issues
// @noframes
// @match *://mangadex.org/chapter/*
// @grant GM_addStyle
// ==/UserScript==
GM_addStyle('\
/* Fix unable to click on scrollbar because of invisible swiping divs */\
#right_swipe_area {\
display: none;\
}\
\
/* Fix overlapping flex items */\
.reader-controls-mode, .reader-controls-footer {\
flex-shrink: 0 !important;\
}\
\
/* Fix sidebar going off-screen because of the collapser */\
.reader-controls {\
max-width: calc(100% - 34px);\
}\
');
function updateSidebar() {
let modeNode = document.querySelector('.reader-controls-mode');
let footerNode = document.querySelector('.reader-controls-footer');
let pageNode = document.querySelector('.reader-controls-pages');
let oldWrapperNodes = document.querySelectorAll('.inline-comments'); // Multiple divs can show up if users switch chapter too fast
// Clear old comments
if (oldWrapperNodes) {
for (let i = 0; i < oldWrapperNodes.length; i++) {
oldWrapperNodes[i].parentNode.removeChild(oldWrapperNodes[i]);
}
}
// Hide sidebar components. Comment out anything you want to keep
modeNode.style.setProperty('display', 'none', 'important'); // Common keyboard shortcuts
footerNode.style.setProperty('display', 'none', 'important'); // Footer credit
// Push pagination to the bottom of the sidebar
if (footerNode.style.display === 'none') pageNode.classList.add('mt-auto');
addToggleCommentButton();
}
function addToggleCommentButton() {
let oldToggleCommentNode = document.querySelector('.toggle-comments');
/* Reset node state if already exists, else create a new node */
if (oldToggleCommentNode) {
oldToggleCommentNode.querySelector('#kbd_comment_usage').textContent = 'Show comments';
} else {
let toggleCommentNode = document.createElement('div');
toggleCommentNode.className = 'toggle-comments cursor-pointer pt-2 pb-2 pl-2';
/* Inner content */
let kbNode = document.createElement('kbd');
kbNode.innerHTML = ' k/numpad 5';
let whitespaceNode = document.createTextNode('\u00A0');
let iconNode = document.createElement('span');
iconNode.className = 'fas fa-comments fa-fw';
iconNode.setAttribute('aria-hidden', 'true');
iconNode.title = 'Display comments';
let usageNode = document.createElement('span');
usageNode.id = 'kbd_comment_usage';
usageNode.textContent = 'Show comments';
toggleCommentNode.appendChild(kbNode);
toggleCommentNode.appendChild(whitespaceNode);
toggleCommentNode.appendChild(iconNode);
toggleCommentNode.appendChild(whitespaceNode.cloneNode(true));
toggleCommentNode.appendChild(usageNode);
/* END inner content */
/* Event listener */
toggleCommentNode.addEventListener('click', handleToggleComments);
document.addEventListener('keydown', function (e) {
// 12 is 5 in numpad with NumLock off
// 101 is 5 in numpad with NumLock on
// 75 is k
if (e.keyCode === 12 || e.keyCode === 101 || e.keyCode === 75) handleToggleComments();
});
/* END event listener */
let footerNode = document.querySelector('.reader-controls-footer');
footerNode.parentNode.insertBefore(toggleCommentNode, footerNode);
}
}
function handleToggleComments() {
let textNode = document.querySelector('#kbd_comment_usage');
toggleComments(textNode.textContent.indexOf('Hide') === -1);
if (textNode.textContent.indexOf('Hide') === -1) {
textNode.textContent = 'Hide comments';
let oldWrapperNodes = document.querySelector('.inline-comments');
if (!oldWrapperNodes) insertComments();
} else {
textNode.textContent = 'Show comments';
}
}
function toggleComments(isDisplay) {
let oldWrapperNode = document.querySelector('.inline-comments');
if (oldWrapperNode) oldWrapperNode.style.display = !!isDisplay ? '' : 'none';
}
function insertComments() {
let oldChapterId = lastChapterId;
let xhr = new XMLHttpRequest();
xhr.open('GET', '/chapter/' + lastChapterId + '/comments');
xhr.responseType = 'document';
xhr.addEventListener('load', function () {
// Only display comments if user hasn't switched chapter before the request finished
if (xhr.status !== 200 || oldChapterId !== lastChapterId) return;
let htmlDocument = xhr.responseXML.documentElement;
let posts = htmlDocument.querySelectorAll('table .post:not(.post-moderated)');
let wrapperNode = document.createElement('div');
wrapperNode.className = 'inline-comments';
wrapperNode.style.overflow = 'auto';
wrapperNode.style.overflowWrap = 'break-word';
wrapperNode.style.wordWrap = 'break-word';
for (let i = 0; i < posts.length; i++) {
let poster = posts[i].querySelector('td:first-child span');
let post = posts[i].querySelector('.postbody');
let commentNode = document.createElement('div');
if (!(i % 2)) commentNode.style.backgroundColor = 'rgba(0,0,0,.05)';
commentNode.innerHTML = '<div style="color: #06f">' + poster.innerHTML + '</div>' + post.innerHTML;
wrapperNode.appendChild(commentNode);
}
// Button to redirect to chapter thread
let toThread = htmlDocument.querySelector('table+div');
if (toThread) wrapperNode.appendChild(toThread);
let footerNode = document.querySelector('.reader-controls-footer');
footerNode.parentNode.insertBefore(wrapperNode, footerNode);
fixSpoilerButton(wrapperNode);
});
xhr.send();
}
function fixSpoilerButton(post) {
let spoilerBtns = post.querySelectorAll('.btn-spoiler');
for (let i = 0; i < spoilerBtns.length; i++) {
spoilerBtns[i].addEventListener('click', function () {
this.nextElementSibling.classList.toggle('display-none');
});
}
}
let lastPath = '';
let lastChapterId = '';
setInterval(function () {
if (lastPath !== location.pathname) {
lastPath = location.pathname;
let path = location.pathname.split('/');
if (path.length === 4 && !isNaN(path[3]) && lastChapterId !== path[2]) {
lastChapterId = path[2];
updateSidebar();
}
}
}, 500);