· 5 years ago · Sep 26, 2020, 05:36 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((mutations, me) => {
99 // some mutation will hold the movie title during hovering
100 // other mutations will return null
101 const getTitleAttempt = getTitleFromMutations(mutations)
102 console.log(getTitleAttempt);
103 title = getTitleAttempt ? getTitleAttempt : title
104
105 if (mutations.some(hasPreviewOpened) && !isIntervalOn) {
106 // when the preview is opened and there's not a interval already running
107
108 // initialise a timer for the interval
109 let timer = 0
110 const waitForTags = setInterval(() => {
111 // set boolean to not run another interval
112 isIntervalOn = true
113 timer += 100
114
115 // try to get the node with imdb ratings to make sure, it's not already inserted
116 // wait for the node with movie tags to be mounted (AJAX)
117 const movieRatings = document.querySelector(".jaunie-class")
118 const evidenceTags = document.querySelector(".evidence-tags")
119 if (evidenceTags !== null && movieRatings === null && !isFetching) {
120 // check cached titles
121 const realTitle = getRightMovie(title, getMovieDetails())
122
123 // fetch the API
124 // then append rating and reset booleans which make sure operation is only done once
125 isFetching = true
126 fetch(`${baseUrl}title=${encodeURI(realTitle)}`)
127 .then(res => res.json())
128 .then(data => {
129 let span = document.createElement("span")
130 span.innerHTML = `IMDB: ${data[0].value}`
131 span.classList.add("jaunie-class")
132 evidenceTags.appendChild(span)
133 clearInterval(waitForTags)
134 previewIsMounted = false
135 isIntervalOn = false
136 isFetching = false
137 })
138 }
139 // if interval takes too long, remove it to not clog the dom
140 if (timer > 4000) {
141 clearInterval(waitForTags)
142 isIntervalOn = false
143 }
144 }, 100)
145 }
146})
147
148observer.observe(document, {
149 childList: true,
150 subtree: true
151})
152