Skip to content

Instantly share code, notes, and snippets.

@kvnxiao
Last active October 31, 2021 03:25
Show Gist options
  • Save kvnxiao/de9dbdc3bce98d10957df4d5c85492bd to your computer and use it in GitHub Desktop.
Save kvnxiao/de9dbdc3bce98d10957df4d5c85492bd to your computer and use it in GitHub Desktop.
mangadex-thumbnail-preview.js
// ==UserScript==
// @name Mangadex Thumbnail Preview
// @namespace https://github.com/kvnxiao
// @version 0.1.2
// @description Thumbnail preview addon for Mangadex
// @author Kevin Xiao
// @match https://mangadex.org/follows
// @grant none
// @require https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.min.js
// @updateURL https://gist.githubusercontent.com/kvnxiao/de9dbdc3bce98d10957df4d5c85492bd/raw
// @downloadURL https://gist.githubusercontent.com/kvnxiao/de9dbdc3bce98d10957df4d5c85492bd/raw
// ==/UserScript==
"use strict";
// convert html nodelist to js array
function toArray(obj) {
const array = [];
for (let i of obj) {
array.push(i)
}
return array;
}
// create div for vue to bind to
const body = document.getElementsByTagName("body")[0];
const div = document.createElement("div");
const vueId = "vue-addon";
div.id = vueId;
body.appendChild(div);
// retrieve manga anchor links
const p = document.getElementsByClassName("chapter-container")[0];
const rows = p.getElementsByClassName(
"col col-md-3 row no-gutters flex-nowrap align-items-start p-2 font-weight-bold border-bottom"
);
const links = toArray(p.getElementsByTagName("a")).filter(it =>
it.getAttribute("href").startsWith("/title/")
);
// instantiate an eventbus to communicate from webpage to vue instances
Vue.prototype.$eventbus = new Vue();
const HOVER_EVENT = "hover"
const LEAVE_EVENT = "leave"
const HoverThumb = {
template: `
<div v-if="url !== ''" id="vue-thumb" :style="styleObj">
<img :src="url"></img>
</div>
`,
data() {
return {
url: "",
styleObj: {
position: "absolute",
boxShadow: "0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23)",
top: "0",
left: "0",
pointerEvents: "none"
}
};
},
created() {
this.$eventbus.$on(HOVER_EVENT, event => {
this.url = "https://mangadex.org/images/manga/" + event.url + ".thumb.jpg";
this.styleObj.top = (document.documentElement.scrollTop + event.bound.top - 50) + "px"
if (event.bound.left < 140) {
this.styleObj.left = "240px"
} else {
this.styleObj.left = (event.bound.left - 130) + "px"
}
});
this.$eventbus.$on(LEAVE_EVENT, _url => {
this.url = "";
});
}
};
const app = new Vue({
components: {
"hover-thumb": HoverThumb
},
render: h => h(HoverThumb)
}).$mount("#" + vueId);
links.map(it => {
it.addEventListener("mouseover", function (event) {
Vue.prototype.$eventbus.$emit(HOVER_EVENT, {
url: event.target.getAttribute("href").split("/")[2],
bound: event.target.getBoundingClientRect()
});
});
it.addEventListener("mouseleave", function (event) {
Vue.prototype.$eventbus.$emit(LEAVE_EVENT, event.target.getAttribute("href").split("/")[2]);
})
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment