Issue With pageScript in a JavaScript File - javascript

I wanted to make a FPS Unlimiter Userscript for gpop.io because the current fps cap is 60 and wanted to increase to 240fps and I don't understand JavaScript well enough to know what I am doing and am requesting help, The Section Of pageScript.js, I have The pageScript.js in the URL and The Code Below
!function pageScript() {
let speedConfig = {
speed: 1.0,
cbSetIntervalChecked: true,
cbSetTimeoutChecked: true,
cbPerformanceNowChecked: true,
cbDateNowChecked: true,
cbRequestAnimationFrameChecked: false,
};
const emptyFunction = () => {};
const originalClearInterval = window.clearInterval;
const originalclearTimeout = window.clearTimeout;
const originalSetInterval = window.setInterval;
const originalSetTimeout = window.setTimeout;
const originalPerformanceNow = window.performance.now.bind(
window.performance
);
const originalDateNow = Date.now;
const originalRequestAnimationFrame = window.requestAnimationFrame;
let timers = [];
const reloadTimers = () => {
console.log(timers);
const newtimers = [];
timers.forEach((timer) => {
originalClearInterval(timer.id);
if (timer.customTimerId) {
originalClearInterval(timer.customTimerId);
}
if (!timer.finished) {
const newTimerId = originalSetInterval(
timer.handler,
speedConfig.cbSetIntervalChecked
? timer.timeout / speedConfig.speed
: timer.timeout,
...timer.args
);
timer.customTimerId = newTimerId;
newtimers.push(timer);
}
});
timers = newtimers;
};
window.addEventListener("message", (e) => {
if (e.data.command === "setSpeedConfig") {
speedConfig = e.data.config;
reloadTimers();
}
});
window.postMessage({ command: "getSpeedConfig" });
window.clearInterval = (id) => {
originalClearInterval(id);
timers.forEach((timer) => {
if (timer.id == id) {
timer.finished = true;
if (timer.customTimerId) {
originalClearInterval(timer.customTimerId);
}
}
});
};
window.clearTimeout = (id) => {
originalclearTimeout(id);
timers.forEach((timer) => {
if (timer.id == id) {
timer.finished = true;
if (timer.customTimerId) {
originalclearTimeout(timer.customTimerId);
}
}
});
};
window.setInterval = (handler, timeout, ...args) => {
console.log("timeout ", timeout);
if (!timeout) timeout = 0;
const id = originalSetInterval(
handler,
speedConfig.cbSetIntervalChecked ? timeout / speedConfig.speed : timeout,
...args
);
timers.push({
id: id,
handler: handler,
timeout: timeout,
args: args,
finished: false,
customTimerId: null,
});
return id;
};
window.setTimeout = (handler, timeout, ...args) => {
if (!timeout) timeout = 0;
return originalSetTimeout(
handler,
speedConfig.cbSetTimeoutChecked ? timeout / speedConfig.speed : timeout,
...args
);
};
// performance.now
(function () {
let performanceNowValue = null;
let previusPerformanceNowValue = null;
window.performance.now = () => {
const originalValue = originalPerformanceNow();
if (performanceNowValue) {
performanceNowValue +=
(originalValue - previusPerformanceNowValue) *
(speedConfig.cbPerformanceNowChecked ? speedConfig.speed : 1);
} else {
performanceNowValue = originalValue;
}
previusPerformanceNowValue = originalValue;
return Math.floor(performanceNowValue);
};
})();
// Date.now
(function () {
let dateNowValue = null;
let previusDateNowValue = null;
Date.now = () => {
const originalValue = originalDateNow();
if (dateNowValue) {
dateNowValue +=
(originalValue - previusDateNowValue) *
(speedConfig.cbDateNowChecked ? speedConfig.speed : 1);
} else {
dateNowValue = originalValue;
}
previusDateNowValue = originalValue;
return Math.floor(dateNowValue);
};
})();
// requestAnimationFrame
(function () {
let dateNowValue = null;
let previusDateNowValue = null;
const callbackFunctions = [];
const callbackTick = [];
const newRequestAnimationFrame = (callback) => {
return originalRequestAnimationFrame((timestamp) => {
const originalValue = originalDateNow();
if (dateNowValue) {
dateNowValue +=
(originalValue - previusDateNowValue) *
(speedConfig.cbRequestAnimationFrameChecked
? speedConfig.speed
: 1);
} else {
dateNowValue = originalValue;
}
previusDateNowValue = originalValue;
const dateNowValue_MathFloor = Math.floor(dateNowValue);
const index = callbackFunctions.indexOf(callback);
let tickFrame = null;
if (index == -1) {
callbackFunctions.push(callback);
callbackTick.push(0);
callback(dateNowValue_MathFloor);
} else if (speedConfig.cbRequestAnimationFrameChecked) {
tickFrame = callbackTick[index];
tickFrame += speedConfig.speed;
if (tickFrame >= 1) {
while (tickFrame >= 1) {
callback(dateNowValue_MathFloor);
window.requestAnimationFrame = emptyFunction;
tickFrame -= 1;
}
window.requestAnimationFrame = newRequestAnimationFrame;
} else {
window.requestAnimationFrame(callback);
}
callbackTick[index] = tickFrame;
} else {
callback(dateNowValue_MathFloor);
}
});
};
window.requestAnimationFrame = newRequestAnimationFrame;
})();
}()
//# sourceURL=pageScript.js
I was trying to read through the code to find what was capping the fps but I wasn't able to find anything that was easy enough for me to understand.

Related

Error on Sortting Items is not a function

I have a problem with my code
So, there is picture with like, when i click on the heart that add a like
there is a container down ma page and then the likes are also displayed in it.
(picture to show you a context)
The problem is everything work fine, but when you use my function "filter"
the likes are working on the photos but not down the page and that return me an error i don't really understand from where that come.
So can you help me please ?
import showMethods from "../factories/showMethods.js";
import lightbox from "../factories/lightbox.js";
import formularSecur from "../factories/formularSecur.js";
export default class OnePhotographer {
constructor() {
this.photographer = null;
this.medias = [];
this.likes = 0;
this.lightbox = lightbox;
this.indexLightbox = 0;
this.getPhotographer();
this.eInit();
}
eInit() {
document.getElementById("filtre").addEventListener("change", (e) => {
this.filter(e.target.value);
});
document.getElementById("filtre").addEventListener("click", (e) => {
this.filter(e.target.value);
});
document.getElementById("contactForm").addEventListener("submit", (e) => {
e.preventDefault();
formularSecur.checkForm(this);
document.getElementById("contactForm").reset();
});
this.lightbox.init(this);
document.getElementById("closeLightbox").addEventListener("click", () => {
this.lightbox.closeLightbox();
});
document.getElementById("prevBox").addEventListener("click", () => {
this.lightbox.navLightbox("prev");
});
document.getElementById("nextBox").addEventListener("click", () => {
this.lightbox.navLightbox("next");
});
document.addEventListener("keydown", (event) => {
if (event.code == "ArrowLeft") {
this.lightbox.navLightbox("prev");
} else if (event.code == "ArrowRight") {
this.lightbox.navLightbox("next");
} else if (event.code == "Escape") {
this.lightbox.closeLightbox();
}
});
}
filter(param) {
if (param === "popular") {
this.medias = this.medias.sort(this.order(param));
} else {
this.medias = this.medias.sort(this.order(param)).reverse();
}
document.querySelector(".containerMedias").innerHTML = "";
this.medias.forEach((media, index) => {
showMethods.showMedia(media, index);
showMethods.showLikes(this, instance);
});
}
order(settings) {
return function (x, y) {
if (x[settings] < y[settings]) {
return -1;
}
if (x[settings] > y[settings]) {
return 1;
}
return 0;
};
}
setMedias(media) {
this.medias = media;
}
async getPhotographer() {
const response = await fetch("./data/photographers.json");
const res = await response.json();
const id = this.idUrlCatch();
res.photographers.forEach((photographer) => {
if (photographer.id == id) {
this.photographer = photographer;
res.media.forEach((media) => {
if (media.photographerId == this.photographer.id) {
this.medias.push(media);
this.likes += media.likes;
}
});
this.medias = this.medias.sort(this.order("popular"));
}
});
showMethods.showData(this);
showMethods.showLikes(this, instance);
}
idUrlCatch() {
const str = window.location.href;
const url = new URL(str);
if (url.searchParams.get("id")) {
const id = url.searchParams.get("id");
return id;
}
}
showData() {
showMethods.showData(this);
showMethods.showLikes(this, instance);
}
showHeader() {
showMethods.showHeader(this);
}
showMedia(media, index) {
showMethods.showMedia(media, index, this);
}
showLikes() {
showMethods.showLikes(this, instance);
}
setSrcLightbox() {
showMethods.setSrcLightbox(this);
}
closeLightbox() {
showMethods.closeLightbox(this);
}
navLightbox() {
}
}
this is the second part of my code
import lightbox from "../factories/lightbox.js";
export default {
showData: function (instance) {
this.showHeader(instance);
instance.medias.forEach((media, index) => {
this.showMedia(media, index, instance);
});
instance.showLikes();
},
showHeader: function (instance) {
const infoHeader = document.querySelector(".photograph-header .containerInfo");
const title = document.createElement("h1");
title.textContent = instance.photographer.name;
const loc = document.createElement("h3");
loc.textContent = `${instance.photographer.city}, ${instance.photographer.country}`;
const tagline = document.createElement("span");
tagline.textContent = instance.photographer.tagline;
infoHeader.appendChild(title);
infoHeader.appendChild(loc);
const headerImg = document.querySelector(
".photograph-header .containerImg"
);
const pic = `assets/photographers/${instance.photographer.portrait}`;
const img = document.createElement("img");
img.setAttribute("src", pic);
img.setAttribute("alt", instance.photographer.name);
headerImg.appendChild(img);
},
showMedia: function (media, index, instance) {
const mediaSection = document.querySelector(".containerMedias");
const card = document.createElement("div");
card.classList.add("cardMedia");
const containerImg = document.createElement("div");
containerImg.classList.add("containerImg");
if (media.image) {
const mediaUrl = `assets/medias/${media.image}`;
const mediaItem = document.createElement("img");
mediaItem.dataset.index = index;
mediaItem.setAttribute("tabindex", 0);
mediaItem.addEventListener("click", (e) => {
lightbox.showLightbox(e, instance);
});
mediaItem.addEventListener("focus", () => {
mediaItem.addEventListener("keydown", (e) => {
if (e.code == "Enter") {
lightbox.showLightbox(e, instance);
}
});
});
mediaItem.setAttribute("src", mediaUrl);
mediaItem.setAttribute("alt", media.title);
containerImg.appendChild(mediaItem);
} else {
const mediaUrl = `assets/medias/${media.video}`;
const mediaItem = document.createElement("video");
mediaItem.dataset.index = index;
mediaItem.controls = true;
mediaItem.classList.add("media");
mediaItem.addEventListener("click", (e) => {
lightbox.showLightbox(e, instance);
});
mediaItem.setAttribute("src", mediaUrl);
mediaItem.setAttribute("alt", media.title);
mediaItem.setAttribute("data-index", index);
containerImg.appendChild(mediaItem);
}
const subContain = document.createElement("div");
subContain.classList.add("subContain");
const picTitle = document.createElement("h3");
picTitle.textContent = media.title;
const like = document.createElement("span");
like.setAttribute("tabindex", 0);
like.classList.add("like");
like.innerHTML = `${media.likes} <i class="fa-regular fa-heart"></i>`;
like.addEventListener("click", () => {
like.classList.toggle("active");
if (like.classList.contains("active")) {
media.likes += 1;
instance.likes += 1;
like.innerHTML = `${media.likes} <i class="fa-solid fa-heart"></i>`;
} else {
media.likes -= 1;
instance.likes -= 1;
like.innerHTML = `${media.likes} <i class="fa-regular fa-heart"></i>`;
}
instance.showLikes();
});
like.addEventListener("focus", () => {
like.addEventListener("keydown", (event) => {
if (event.code == "Enter") {
like.classList.toggle("active");
if (like.classList.contains("active")) {
media.likes += 1;
instance.likes += 1;
like.innerHTML = `${media.likes} <i class="fa-solid fa-heart"></i>`;
} else {
media.likes -= 1;
instance.likes -= 1;
like.innerHTML = `${media.likes} <i class="fa-regular fa-heart"></i>`;
}
instance.showLikes();
}
});
});
subContain.appendChild(picTitle);
subContain.appendChild(like);
card.appendChild(containerImg);
card.appendChild(subContain);
mediaSection.appendChild(card);
},
showLikes: function (instance) {
const priceContainer = document.createElement("div");
priceContainer.classList.add("priceContainer");
const likes = document.createElement("span");
likes.classList.add("likes");
likes.innerHTML = `<i class="fa-solid fa-heart"></i> ${instance.likes}`;
const priceDay = document.createElement("span");
priceDay.classList.add("priceDay");
priceDay.innerHTML = `<i class="fa-solid fa-dollar-sign"></i> ${instance.photographer.price}`;
priceContainer.appendChild(likes);
priceContainer.appendChild(priceDay);
document.querySelector(".photograph-header").appendChild(priceContainer);
},
};
i don't really get why with my function showMedia everithing is fine, but with showLikes not
the code error
Uncaught TypeError: instance.showLikes is not a function
at HTMLSpanElement.<anonymous> (showMethods.js:101:16)
(anonyme) # showMethods.js:101
if you help me that will save my life
Thank you for your time <3
So i find why the bug is happening when i use my "filter" Function.
I lose Instance on "showLikes" Function, so i don't have accès to the current instance.
One of my solution make my code in the onePhotograph.js, so no Instance ==> No bug.
I know this is maybe not the only solution, and maybe not the best. But this is a great solution also !
Best Regards

How to simply Load more from JSON content once user scrolls to the bottom of the div using vanilla javascript?

Okay I simply want to know what I have to add to my Vanilla JavaScript code to load more content once the bottom of the scrolled div/page (wholewrapper) is reached. The code I have included works pretty well as I'm a beginner at vanilla JavaScript. But I need help understanding how to structure onScrollEvents with HttpRequest.
Here is my code:
Vanilla JavaScript:
let page = 1;
const last_page = 10;
const pixel_offset = 200;
const throttle = (callBack, delay) => {
let withinInterval;
return function () {
const args = arguments;
const context = this;
if (!withinInterval) {
callBack.call(context, args);
withinInterval = true;
setTimeout(() => (withinInterval = false), delay);
}
};
};
const httpRequestWrapper = (method, URL) => {
return new Promise((resolve, reject) => {
const xhr_obj = new XMLHttpRequest();
xhr_obj.responseType = "json";
xhr_obj.open(method, URL);
xhr_obj.onload = () => {
const data = xhr_obj.response;
resolve(data);
};
xhr_obj.onerror = () => {
reject("failed");
};
xhr_obj.send();
});
};
const getData = async (page_no = 1) => {
const data = await httpRequestWrapper("GET", `myXML.json`);
const { results } = data;
populateUI(results);
};
let handleLoad;
let trottleHandler = () => {
throttle(handleLoad.call(this), 1000);
};
document.addEventListener("DOMContentLoaded", () => {
getData(1);
window.addEventListener("scroll", trottleHandler);
});
handleLoad = () => {
if (
window.innerHeight + window.scrollY >=
document.body.offsetHeight - pixel_offset
) {
page = page + 1;
if (page <= last_page) {
window.removeEventListener("scroll", trottleHandler);
getData(page).then((res) => {
window.addEventListener("scroll", trottleHandler);
});
}
}
};
const populateUI = (data) => {
const container = document.querySelector(".whole_wrapper");
data &&
data.length &&
data.map((each, index) => {
const { photoVar } = image;
const { textVar } = text;
const { noteVar } = note;
container.innerHTML += `
<div class="each_bubble">
<div class="imageContainer">
<img src="${photoVar}" alt="" />
</div>
<div class="right_contents_container">
<div class="text_field">${textVar}</div>
<div class="note_field">${noteVar}</div>
</div>
</div>
`;
});
};

passing a simon game from jQuery to vanilla JS

Long story short, I made this Simon Game in a bootcamp a month ago in jQuery, but the days pass and I started to feel the necesity of translate it to pure vanilla javaScript.
the thing is that I feel stuck in the last part, when I have to check the answers of the game and add that to the gamePatern array and userChosenPattern.
here is the main part in jQuery
var buttonColors = ["red", "blue", "green", "yellow"];
var gamePattern = [];
var userClickedPattern = [];
var started = false;
var level = 0;
$(document).keypress(function () {
if (!started) {
$("#level-title").text("level " + level);
nextSequence();
started = true;
}
});
function nextSequence() {
userClickedPattern = [];
level++;
$("#level-title").text("level " + level);
var randomNumber = Math.floor(Math.random() * 4);
var randomChosenColour = buttonColors[randomNumber];
gamePattern.push(randomChosenColour);
$("#" + randomChosenColour)
.fadeIn(100)
.fadeOut(100)
.fadeIn(100);
playSound(randomChosenColour);
}
$(".btn").click(function () {
var userChosenColor = $(this).attr("id");
userClickedPattern.push(userChosenColor);
playSound(userChosenColor);
animatePress(userChosenColor);
checkTheAnswer(userClickedPattern.length - 1);
});
function checkTheAnswer(currentLevel) {
if (gamePattern[currentLevel] === userClickedPattern[currentLevel]) {
console.log("success");
if (userClickedPattern.length === gamePattern.length) {
setTimeout(function () {
nextSequence();
}, 1000);
}
} else {
$("body").addClass("game-over");
setTimeout(function () {
$("body").removeClass("game-over");
}, 200);
gameOverAudio();
$("#level-title").text("Game Over, Press Any Key to Restart");
$("#level-title").css("font-size", "2rem");
startOver();
}
}
function startOver() {
level = 0;
gamePattern = [];
started = false;
}
function playSound(name) {
var audio = new Audio("sounds/" + name + ".mp3");
audio.play();
}
function gameOverAudio() {
var gameOver = new Audio("sounds/wrong.mp3");
gameOver.play();
}
function animatePress(currentColor) {
$("#" + currentColor).addClass("pressed");
setTimeout(function () {
$("#" + currentColor).removeClass("pressed");
}, 100);
}
and here is the same part and the whole code but in vanilla JS
const buttonColors = ["red", "blue", "green", "yellow"];
const gamePattern = [];
const userClickedPattern = [];
const started = false;
const level = 0;
const body = document.querySelector("body");
const levelTitle = document.getElementById("level-title");
// to start the game
document.addEventListener("keypress", () => {
if (!started) {
levelTitle.innerHTML = `level ${level}`;
nextSequence();
sarted = true;
}
});
// generete the next sequence
function nextSequence() {
var randomNumber = Math.floor(Math.random() * 4);
var randomChosenColour = buttonColors[randomNumber];
gamePattern.push(randomChosenColour);
let animationBtn = document.querySelector("#" + randomChosenColour);
animationBtn.classList.add("FadeInFadeOut");
setTimeout(() => {
animationBtn.classList.remove("FadeInFadeOut");
}, 50);
playSound(randomChosenColour);
}
// here we detect which button is pressed by the user
var bTn = document.getElementsByClassName("btn");
document.querySelectorAll(".btn").forEach((bt) => {
bt.onclick = () => {
let userChosenColor = bt.id;
userClickedPattern.push(userChosenColor);
playSound(userChosenColor);
animatePress(userChosenColor);
checkTheAnswer(userClickedPattern.length - 1);
};
});
// check the answer and dynamic of the game
const checkTheAnswer = (currentLevel) => {
if (gamePattern[currentLevel] === userClickedPattern[currentLevel]) {
console.log("succes");
if (userClickedPattern.length === gamePattern.length) {
setTimeout(() => {
nextSequence();
}, 1000);
}
} else {
body.classList.add("game-over");
setTimeout(() => {
body.classList.remove("game-over");
}, 200);
gameOverAudio();
levelTitle.innerHTML = `Game Over, Press Any Key to Restart`;
levelTitle.style.fontSize = "2rem";
startOver();
}
};
const startOver = () => {
level = 0;
gamePattern = [];
started = false;
};
// adudio stuff
const playSound = (name) => {
let audio = new Audio("sounds/" + name + ".mp3");
audio.play();
};
function gameOverAudio() {
var gameOver = new Audio("sounds/wrong.mp3");
gameOver.play();
}
//animation in button
const animatePress = (currentColor) => {
const buttons = document.querySelector(`#${currentColor}`);
buttons.classList.add("pressed");
setTimeout(() => {
buttons.classList.remove("pressed");
}, 100);
};
console.log(gamePattern);
console.log(userClickedPattern);
Also here is the game in my codepen, it’s without the sounds for obvious reasons.
Simon Game

Run function only once until onmouseout

I have an anchor tag that plays a sound everytime the link is hovered:
<a onmouseenter="playAudio();">LINK</a>
However, when hovered, the link creates some characters that, if I keep moving the mouse inside the element, it keeps playing the sound over and over again.
Is there a way to play the onmouseenter function only once until it has detected the event onmouseout?
I've tried adding:
<a onmouseenter="playAudio();this.onmouseenter = null;">LINK</a>
but then it only plays the sound once.
Here goes the TextScramble animation function:
// ——————————————————————————————————————————————————
// TextScramble
// ——————————————————————————————————————————————————
class TextScramble {
constructor(el) {
this.el = el
this.chars = '!<>-_\\/[]{}—=+*^?#________'
this.update = this.update.bind(this)
}
setText(newText) {
const oldText = this.el.innerText
const length = Math.max(oldText.length, newText.length)
const promise = new Promise((resolve) => this.resolve = resolve)
this.queue = []
for (let i = 0; i < length; i++) {
const from = oldText[i] || ''
const to = newText[i] || ''
const start = Math.floor(Math.random() * 40)
const end = start + Math.floor(Math.random() * 40)
this.queue.push({
from,
to,
start,
end
})
}
cancelAnimationFrame(this.frameRequest)
this.frame = 0
this.update()
return promise
}
update() {
let output = ''
let complete = 0
for (let i = 0, n = this.queue.length; i < n; i++) {
let {
from,
to,
start,
end,
char
} = this.queue[i]
if (this.frame >= end) {
complete++
output += to
} else if (this.frame >= start) {
if (!char || Math.random() < 0.28) {
char = this.randomChar()
this.queue[i].char = char
}
output += `<span class="dud">${char}</span>`
} else {
output += from
}
}
this.el.innerHTML = output
if (complete === this.queue.length) {
this.resolve()
} else {
this.frameRequest = requestAnimationFrame(this.update)
this.frame++
}
}
randomChar() {
return this.chars[Math.floor(Math.random() * this.chars.length)]
}
}
// ——————————————————————————————————————————————————
// Configuration
// ——————————————————————————————————————————————————
const phrases = [
'MAIN_HUB'
]
const el = document.querySelector('.link_mainhub')
const fx = new TextScramble(el)
let counter = 0
const next = () => {
fx.setText(phrases[counter]).then(() => {});
}
el.addEventListener('mouseenter', next);
<a class="link_mainhub" onmouseenter="playAudio();">LINK</a>
Thanks.
Set a variable when you start playing the audio, and check for this before playing it again. Have the animation unset the variable when it's done.
function audioPlaying = false;
function playAudio() {
if (!audioPlaying) {
audioPlaying = true;
audioEl.play();
}
}
const next = () => {
fx.setText(phrases[counter]).then(() => {
audioPlaying = false;
});
}

How to send data from Node.js(webpack) to pure Node.js(express)?

I am getting data in a local storage of Webpack in JSON format. Node.js of Webpack is not allowing me to create a connection with MySQL. So, I am thinking if there is a way to send data to a backend(pure Node/Express server) like REST API.
I cannot use MySQL directly in Webpack node.js file
1.ref stackoveflow
2.ref GitHub
Below is my Webpack code I want save my localstorage data to database like MySQL, mongoDB.
import twitter from 'twitter-text';
import PDFJSAnnotate from '../';
import initColorPicker from './shared/initColorPicker';
/*import mysql from '../';
var con = mysql.createConnection({
host: "localhost",
user: "ali",
password: "demopassword"
});
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
});*/
//var hummus = require('HummusJS/hummus');
const { UI } = PDFJSAnnotate;
const documentId = 'question.pdf';
let PAGE_HEIGHT;
let RENDER_OPTIONS = {
documentId,
pdfDocument: null,
scale: parseFloat(localStorage.getItem(`${documentId}/scale`), 10) || 1.33,
rotate: parseInt(localStorage.getItem(`${documentId}/rotate`), 10) || 0
};
PDFJSAnnotate.setStoreAdapter(new PDFJSAnnotate.LocalStoreAdapter());
PDFJS.workerSrc = './shared/pdf.worker.js';
//var annotationz = localStorage.getItem(RENDER_OPTIONS.documentId + '/annotations') || [];
//console.log(annotationz);
// Render stuff
let NUM_PAGES = 0;
document.getElementById('content-wrapper').addEventListener('scroll', function (e) {
let visiblePageNum = Math.round(e.target.scrollTop / PAGE_HEIGHT) + 1;
let visiblePage = document.querySelector(`.page[data-page-number="${visiblePageNum}"][data-loaded="false"]`);
if (visiblePage) {
setTimeout(function () {
UI.renderPage(visiblePageNum, RENDER_OPTIONS);
});
}
});
function render() {
PDFJS.getDocument(RENDER_OPTIONS.documentId).then((pdf) => {
RENDER_OPTIONS.pdfDocument = pdf;
let viewer = document.getElementById('viewer');
viewer.innerHTML = '';
NUM_PAGES = pdf.pdfInfo.numPages;
for (let i=0; i<NUM_PAGES; i++) {
let page = UI.createPage(i+1);
viewer.appendChild(page);
}
UI.renderPage(1, RENDER_OPTIONS).then(([pdfPage, annotations]) => {
let viewport = pdfPage.getViewport(RENDER_OPTIONS.scale, RENDER_OPTIONS.rotate);
PAGE_HEIGHT = viewport.height;
});
});
}
render();
// Text stuff
(function () {
let textSize;
let textColor;
// let fontface;
function initText() {
let size = document.querySelector('.toolbar .text-size');
[8, 9, 10, 11, 12, 14, 18, 24, 30, 36, 48, 60, 72, 96].forEach((s) => {
size.appendChild(new Option (s, s));
});
/*let face = document.querySelector('.toolbar .font-face');
['fontGeorgiaSerif', 'fontPalatinoSerif', 'fontTimesSerif', 'Sans-Serif Fonts', 'fontArialSansSerif', 'fontComicSansMS', 'fontVerdanaSansMS', 'Monospace Fonts', 'fontCourierNew', 'fontLucidaConsole'].forEach((s) => {
face.appendChild(new Option (s, s));
});*/
setText(
localStorage.getItem(`${RENDER_OPTIONS.documentId}/text/size`) || 10,
localStorage.getItem(`${RENDER_OPTIONS.documentId}/text/color`) || '#000000'
//localStorage.getItem(`${RENDER_OPTIONS.documentId}/text/face`) || 'fontGeorgiaSerif'
// console.log(${RENDER_OPTIONS.documentId});
);
initColorPicker(document.querySelector('.text-color'), textColor, function (value) {
setText(textSize, value);
});
}
function setText(size, color) {
let modified = false;
if (textSize !== size) {
modified = true;
textSize = size;
localStorage.setItem(`${RENDER_OPTIONS.documentId}/text/size`, textSize);
document.querySelector('.toolbar .text-size').value = textSize;
}
/* if (fontface !== face) {
modified = true;
fontface = face;
localStorage.setItem(`${RENDER_OPTIONS.documentId}/text/face`, fontface);
document.querySelector('.toolbar .font-face').value = fontface;
}*/
if (textColor !== color) {
modified = true;
textColor = color;
localStorage.setItem(`${RENDER_OPTIONS.documentId}/text/color`, textColor);
let selected = document.querySelector('.toolbar .text-color.color-selected');
if (selected) {
selected.classList.remove('color-selected');
selected.removeAttribute('aria-selected');
}
selected = document.querySelector(`.toolbar .text-color[data-color="${color}"]`);
if (selected) {
selected.classList.add('color-selected');
selected.setAttribute('aria-selected', true);
}
}
if (modified) {
UI.setText(textSize, textColor);
}
}
function handleTextSizeChange(e) {
setText(e.target.value, textColor);
}
document.querySelector('.toolbar .text-size').addEventListener('change', handleTextSizeChange);
initText();
})();
// Pen stuff
(function () {
let penSize;
let penColor;
function initPen() {
let size = document.querySelector('.toolbar .pen-size');
for (let i=0; i<20; i++) {
size.appendChild(new Option(i+1, i+1));
}
setPen(
localStorage.getItem(`${RENDER_OPTIONS.documentId}/pen/size`) || 1,
localStorage.getItem(`${RENDER_OPTIONS.documentId}/pen/color`) || '#000000'
);
initColorPicker(document.querySelector('.pen-color'), penColor, function (value) {
setPen(penSize, value);
});
}
function setPen(size, color) {
let modified = false;
if (penSize !== size) {
modified = true;
penSize = size;
localStorage.setItem(`${RENDER_OPTIONS.documentId}/pen/size`, penSize);
document.querySelector('.toolbar .pen-size').value = penSize;
}
if (penColor !== color) {
modified = true;
penColor = color;
localStorage.setItem(`${RENDER_OPTIONS.documentId}/pen/color`, penColor);
let selected = document.querySelector('.toolbar .pen-color.color-selected');
if (selected) {
selected.classList.remove('color-selected');
selected.removeAttribute('aria-selected');
}
selected = document.querySelector(`.toolbar .pen-color[data-color="${color}"]`);
if (selected) {
selected.classList.add('color-selected');
selected.setAttribute('aria-selected', true);
}
}
if (modified) {
UI.setPen(penSize, penColor);
}
}
function handlePenSizeChange(e) {
setPen(e.target.value, penColor);
}
document.querySelector('.toolbar .pen-size').addEventListener('change', handlePenSizeChange);
initPen();
})();
// Toolbar buttons
(function () {
let tooltype = localStorage.getItem(`${RENDER_OPTIONS.documentId}/tooltype`) || 'cursor';
if (tooltype) {
setActiveToolbarItem(tooltype, document.querySelector(`.toolbar button[data-tooltype=${tooltype}]`));
}
function setActiveToolbarItem(type, button) {
let active = document.querySelector('.toolbar button.active');
if (active) {
active.classList.remove('active');
switch (tooltype) {
case 'cursor':
UI.disableEdit();
break;
case 'draw':
UI.disablePen();
break;
case 'text':
UI.disableText();
break;
case 'point':
UI.disablePoint();
break;
case 'area':
case 'highlight':
case 'strikeout':
UI.disableRect();
break;
}
}
if (button) {
button.classList.add('active');
}
if (tooltype !== type) {
localStorage.setItem(`${RENDER_OPTIONS.documentId}/tooltype`, type);
}
tooltype = type;
switch (type) {
case 'cursor':
UI.enableEdit();
break;
case 'draw':
UI.enablePen();
break;
case 'text':
UI.enableText();
break;
case 'point':
UI.enablePoint();
break;
case 'area':
case 'highlight':
case 'strikeout':
UI.enableRect(type);
break;
}
}
function handleToolbarClick(e) {
if (e.target.nodeName === 'BUTTON') {
setActiveToolbarItem(e.target.getAttribute('data-tooltype'), e.target);
}
}
document.querySelector('.toolbar').addEventListener('click', handleToolbarClick);
})();
// Scale/rotate
(function () {
function setScaleRotate(scale, rotate) {
scale = parseFloat(scale, 10);
rotate = parseInt(rotate, 10);
if (RENDER_OPTIONS.scale !== scale || RENDER_OPTIONS.rotate !== rotate) {
RENDER_OPTIONS.scale = scale;
RENDER_OPTIONS.rotate = rotate;
localStorage.setItem(`${RENDER_OPTIONS.documentId}/scale`, RENDER_OPTIONS.scale);
localStorage.setItem(`${RENDER_OPTIONS.documentId}/rotate`, RENDER_OPTIONS.rotate % 360);
render();
}
}
function handleScaleChange(e) {
setScaleRotate(e.target.value, RENDER_OPTIONS.rotate);
}
function handleRotateCWClick() {
setScaleRotate(RENDER_OPTIONS.scale, RENDER_OPTIONS.rotate + 90);
}
function handleRotateCCWClick() {
setScaleRotate(RENDER_OPTIONS.scale, RENDER_OPTIONS.rotate - 90);
}
document.querySelector('.toolbar select.scale').value = RENDER_OPTIONS.scale;
document.querySelector('.toolbar select.scale').addEventListener('change', handleScaleChange);
document.querySelector('.toolbar .rotate-ccw').addEventListener('click', handleRotateCCWClick);
document.querySelector('.toolbar .rotate-cw').addEventListener('click', handleRotateCWClick);
})();
// Clear toolbar button
(function () {
function handleClearClick(e) {
if (confirm('Are you sure you want to clear annotations?')) {
for (let i=0; i<NUM_PAGES; i++) {
document.querySelector(`div#pageContainer${i+1} svg.annotationLayer`).innerHTML = '';
}
localStorage.removeItem(`${RENDER_OPTIONS.documentId}/annotations`);
}
}
document.querySelector('a.clear').addEventListener('click', handleClearClick);
})();
// Comment stuff
(function (window, document) {
let commentList = document.querySelector('#comment-wrapper .comment-list-container');
let commentForm = document.querySelector('#comment-wrapper .comment-list-form');
let commentText = commentForm.querySelector('input[type="text"]');
function supportsComments(target) {
let type = target.getAttribute('data-pdf-annotate-type');
return ['point', 'highlight', 'area'].indexOf(type) > -1;
}
function insertComment(comment) {
let child = document.createElement('div');
child.className = 'comment-list-item';
child.innerHTML = twitter.autoLink(twitter.htmlEscape(comment.content));
commentList.appendChild(child);
}
function handleAnnotationClick(target) {
if (supportsComments(target)) {
let documentId = target.parentNode.getAttribute('data-pdf-annotate-document');
let annotationId = target.getAttribute('data-pdf-annotate-id');
PDFJSAnnotate.getStoreAdapter().getComments(documentId, annotationId).then((comments) => {
commentList.innerHTML = '';
commentForm.style.display = '';
commentText.focus();
commentForm.onsubmit = function () {
PDFJSAnnotate.getStoreAdapter().addComment(documentId, annotationId, commentText.value.trim())
.then(insertComment)
.then(() => {
commentText.value = '';
commentText.focus();
});
return false;
};
comments.forEach(insertComment);
});
}
}
function handleAnnotationBlur(target) {
if (supportsComments(target)) {
commentList.innerHTML = '';
commentForm.style.display = 'none';
commentForm.onsubmit = null;
insertComment({content: 'No comments'});
}
}
UI.addEventListener('annotation:click', handleAnnotationClick);
UI.addEventListener('annotation:blur', handleAnnotationBlur);
})(window, document);
Simple AJAX was working on the page because Webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging read more...
So in my case Node js was using Webpack module to load javascript in a browser. It is pure javascript. So I just implemented ajax on my javascript code and it is simply working like a REST API.

Categories

Resources