-
Notifications
You must be signed in to change notification settings - Fork 2
/
kitsu-external-links.user.js
89 lines (83 loc) · 2.87 KB
/
kitsu-external-links.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
// ==UserScript==
// @name Kitsu External Links
// @namespace https://greasyfork.org/users/649
// @version 1.0.1
// @description adds a link to myanimelist and anilist on Kitsu entries
// @author Adrien Pyke
// @match *://kitsu.io/*
// @grant none
// @require https://cdn.jsdelivr.net/gh/fuzetsu/userscripts@ec863aa92cea78a20431f92e80ac0e93262136df/wait-for-elements/wait-for-elements.js
// ==/UserScript==
(() => {
'use strict';
const Api = {
cache: {},
getId: () =>
document
.querySelector('.cover-photo')
.getAttribute('style')
.match(/cover_images\/(?<id>\d+)/iu).groups.id,
getType: () =>
location.href.match(/kitsu\.io\/(?<type>anime|manga)/iu).groups.type,
getLinks: async (id, type) => {
const endpoint = `https://kitsu.io/api/edge/${type}/${id}?include=mappings`;
if (Api.cache[endpoint]) return Api.cache[endpoint];
const response = await fetch(endpoint);
const json = await response.json();
const mappings = json.included
.filter(i =>
i.attributes.externalSite.match(
/^(myanimelist|anilist)\/(anime|manga)$/iu
)
)
.map(i => i.attributes);
Api.cache[endpoint] = mappings;
return mappings;
}
};
const getLinksContainer = container => {
const node = document.createElement('div');
node.classList.add('where-to-watch-widget');
const links = document.createElement('ul');
links.classList.add('nav');
node.appendChild(links);
container.appendChild(node);
return links;
};
const getLinkNode = mapping => {
const { site, type } = mapping.externalSite.match(
/^(?<site>myanimelist|anilist)\/(?<type>anime|manga)$/iu
).groups;
const webSite =
site === 'anilist' ? 'https://anilist.co' : 'https://myanimelist.net';
const href = `${webSite}/${type}/${mapping.externalId}`;
const node = document.createElement('li');
const link = document.createElement('a');
link.classList.add('hint--top', 'hint--bounce', 'hint--rounded');
Object.assign(link, { href, target: '_blank', rel: 'noopener noreferrer' });
link.setAttribute('aria-label', site);
node.appendChild(link);
const logo = document.createElement('img');
Object.assign(logo, {
src:
site === 'anilist'
? 'https://anilist.co/img/icons/android-chrome-512x512.png'
: 'https://upload.wikimedia.org/wikipedia/commons/7/7a/MyAnimeList_Logo.png',
width: '20',
height: '20'
});
link.appendChild(logo);
return node;
};
waitForElems({
sel: '.media-sidebar',
onmatch(container) {
const links = getLinksContainer(container);
const id = Api.getId();
const type = Api.getType();
Api.getLinks(id, type).then(list =>
list.forEach(m => links.appendChild(getLinkNode(m)))
);
}
});
})();