· 5 years ago · Sep 26, 2020, 05:22 PM
1const hasPreviewOpened = (mut) => {
2 //just several booleans to check if the preview modal for the movie has been mounted
3 let previousSiblingBool, targetBool, addedNodesBool
4 if (mut.previousSibling) {
5 previousSiblingBool = mut.previousSibling.className === "previewModal--metadatAndControls-info"
6 }
7 if (mut.target) {
8 targetBool = mut.target.className === "previewModal--metadatAndControls-container"
9 }
10 if (mut.addedNodes[0]) {
11 addedNodesBool = mut.addedNodes[0].className === "focus-trap-wrapper previewModal--wrapper mini-modal"
12 }
13 return (
14 (previousSiblingBool && targetBool)
15 || addedNodesBool
16 )
17}
18
19const getTitleFromMutations = (mutations) => {
20 // a function which returns null if title node not mounted and the title otherwise
21
22 const hasModalWithTitle = (mut) => {
23 // a function with a few booleans to spot if the div with the title has been mounted to dom
24 if (!mut.target.parentNode) {
25 return false
26 }
27 return (
28 mut.target.parentNode.innerHTML.length < 10000 &&
29 mut.target.parentNode.innerHTML.includes('<div class="previewModal--player-titleTreatment-left previewModal--player-titleTreatment mini-modal mini-modal"><img class="previewModal--player-titleTreatment-logo" alt="')
30 )
31 }
32
33 if (mutations.some(hasModalWithTitle)) {
34 // find the node with the title as alt of the preview image
35 const rightNode = mutations.filter(mut => {
36 if (mut.target.parentNode === null) return false
37 return mut.target.parentNode.innerHTML.includes('<div class="previewModal--player-titleTreatment-left previewModal--player-titleTreatment mini-modal mini-modal"><img class="previewModal--player-titleTreatment-logo" alt="')
38 })
39 if (
40 rightNode.length < 1 ||
41 !rightNode[0] ||
42 !rightNode[0].addedNodes ||
43 !rightNode[0].addedNodes[0]
44 ) return null
45 return rightNode[0].addedNodes[0].alt
46 }
47 return null
48}
49
50const getMovieDetails = () => {
51 // a function to get the movie details from the preview modal
52 const [evidenceTags, maturityNumber, duration] = [
53 document.querySelector(".evidence-list"),
54 document.querySelectorAll(".maturity-number"),
55 document.querySelector(".duration")
56 ]
57
58 if (evidenceTags && maturityNumber && duration) {
59 const maturitySpanIndex = maturityNumber.length === 2 ? 1 : 0
60 return [
61 Array.from(evidenceTags.childNodes).map(c => c.innerText),
62 maturityNumber[maturitySpanIndex].innerText,
63 duration.innerText
64 ]
65 }
66 return null
67}
68
69const getRightMovie = (title, d) => {
70 // if cache already contains title :
71 // make sure that the current title held through mutations fits the movie details
72 // in any case return the right title by comparing the movie details given in preview
73 if (movies[title]) {
74 const keys = Object.keys(movies)
75 const i = keys.findIndex(k => {
76 return (
77 movies[k].maturity === d[1] &&
78 movies[k].length === d[2] &&
79 movies[k].tags.join("") === d[0].join("")
80 )
81 })
82 return keys[i]
83 }
84
85 // if the cache does not contain a key which matches the title in arguments
86 // append to cache and return title
87 movies[title] = {
88 tags: d[0],
89 maturity: d[1],
90 length: d[2]
91 }
92 return title
93}
94
95const movies = {}, baseUrl = "https://api.imdflix.tk/movie?"
96let title, isIntervalOn = false, isFetching = false
97
98const observer = new MutationObserver(function(mutations, me) {
99 // some mutation will hold the movie title during hovering
100 // other mutations will return null
101 const getTitleAttempt = getTitleFromMutations(mutations)
102 title = getTitleAttempt ? getTitleAttempt : title
103
104 if (mutations.some(hasPreviewOpened) && !isIntervalOn) {
105 // when the preview is opened and there's not a interval already running
106
107 // initialise a timer for the interval
108 let timer = 0
109 const waitForTags = setInterval(() => {
110 // set boolean to not run another interval
111 isIntervalOn = true
112 timer += 100
113
114 // try to get the node with imdb ratings to make sure, it's not already inserted
115 // wait for the node with movie tags to be mounted (AJAX)
116 const movieRatings = document.querySelector(".jaunie-class")
117 const evidenceTags = document.querySelector(".evidence-tags")
118 if (evidenceTags !== null && movieRatings === null && !isFetching) {
119 // check cached titles
120 const realTitle = getRightMovie(title, getMovieDetails())
121
122 // fetch the API
123 // then append rating and reset booleans which make sure operation is only done once
124 isFetching = true
125 fetch(`${baseUrl}title=${encodeURI(realTitle)}`)
126 .then(res => res.json())
127 .then(data => {
128 let span = document.createElement("span")
129 span.innerHTML = `IMDB: ${data[0].value}`
130 span.classList.add("jaunie-class")
131 evidenceTags.appendChild(span)
132 clearInterval(waitForTags)
133 previewIsMounted = false
134 isIntervalOn = false
135 isFetching = false
136 })
137 }
138 // if interval takes too long, remove it to not clog the dom
139 if (timer > 4000) {
140 clearInterval(waitForTags)
141 isIntervalOn = false
142 }
143 }, 100)
144 }
145})
146
147observer.observe(document, {
148 childList: true,
149 subtree: true
150})
151