Skip to content

Commit

Permalink
Merge branch 'v-next'
Browse files Browse the repository at this point in the history
  • Loading branch information
Saphareas committed Oct 25, 2018
2 parents bdf4e8a + e5168bd commit c0ce1b3
Show file tree
Hide file tree
Showing 11 changed files with 334 additions and 239 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
*.pem
*.pdf
*.pptx
32 changes: 32 additions & 0 deletions background.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
let manifest = function() {
try { return browser.runtime.getManifest(); } catch (e) { console.debug(e); }
try { return chrome.runtime.getManifest(); } catch (e) { console.debug(e); }
}();

function handleOnInstalled(details) {
if (details.reason == "install") {
let notificationOptions = {
type: "basic",
title: "Thanks!",
message: "Thanks for installing Better 9gag.",
iconUrl: "icons/icon-48.png"
};
try { browser.notifications.create(notificationOptions); } catch (e) { console.debug(e); }
try { chrome.notifications.create(notificationOptions); } catch (e) { console.debug(e); }
}
else if (details.reason == "update") {
let notificationOptions = {
type: "basic",
title: `Version ${manifest.version} Changelog`,
message: `Better 9gag was updated. Here is what has changed:
• This notification was added
• The extension now removes the sticky button in the bottom right
• Under-the-hood changes in preparation for version 2.0`,
iconUrl: "icons/icon-48.png"
};
try { browser.notifications.create(notificationOptions); } catch (e) { console.debug(e); }
try { chrome.notifications.create(notificationOptions); } catch (e) { console.debug(e); }
}
}
try { browser.runtime.onInstalled.addListener(handleOnInstalled); } catch (e) { console.debug(e); }
try { chrome.runtime.onInstalled.addListener(handleOnInstalled); } catch (e) { console.debug(e); }
152 changes: 152 additions & 0 deletions components/night-mode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/* #### Dark/Night theme on desktop #### */
function getResourceURL(resource) {
if (typeof(browser) == "undefined") {
return chrome.runtime.getURL(resource);
}
else {
return chrome.runtime.getURL(resource);
}
}

const LowBrightness = getResourceURL("icons/low-brightness-symbol.png");
const HighBrightness = getResourceURL("icons/high-brightness-symbol.png");

function addThemeSwitch() {
// Code to inject into the site; triggers the body observer
const switchFunctionTrigger = 'function switchThemeTrigger() { let trigger = document.createElement("div"); trigger.id = "switch-theme-trigger"; let stylesheet = document.getElementById("dark-theme"); if (stylesheet) { trigger.setAttribute("data-switch-to", "reset"); } else { trigger.setAttribute("data-switch-to", "toDark"); } document.body.append(trigger); }';
// Inject code (end of body)
let switchFunctionTag = document.createElement("script");
switchFunctionTag.id = "theme-switch-function";
switchFunctionTag.appendChild(document.createTextNode(switchFunctionTrigger));
document.head.append(switchFunctionTag);

// Create the switch button
let themeSwitchWrapper = document.createElement("div");
themeSwitchWrapper.classList.add("general-function");
themeSwitchWrapper.id = "theme-switch-wrapper";

let themeSwitchLink = document.createElement("a");
themeSwitchLink.id = "theme-switch";
themeSwitchLink.href= "javascript:void(0)";
themeSwitchLink.setAttribute("onclick", "switchThemeTrigger()");

let themeSwitchImg = document.createElement("img");
themeSwitchImg.src = LowBrightness;

themeSwitchLink.append(themeSwitchImg);
themeSwitchWrapper.appendChild(themeSwitchLink);

// ... and add it to the site (in the header, next to the search)
let wrapper = document.getElementsByClassName("function-wrap")[0];
wrapper.insertBefore(themeSwitchWrapper, wrapper.childNodes[0]);
}

// Actual function to switch the theme; is run by the body observer
function switchTheme(target) {
let themeSwitch = document.getElementById("theme-switch");
// If the target theme is not dark, means back to normal
if (target != "toDark") {
let stylesheet = document.getElementById("dark-theme");
// remove the dark stylesheet (if present) and change the switch icon
if (stylesheet) {
stylesheet.parentNode.removeChild(stylesheet);
themeSwitch.firstChild.src = LowBrightness;
}
// finally save the state in extension storage
if (typeof(browser) == "undefined") {
chrome.storage.local.set({gagIsDark: false});
}
else {
browser.storage.local.set({gagIsDark: false});
}
}
// If the target theme is dark
else if (target == "toDark") {
let stylesheet = document.getElementById("dark-theme");
// create and add a link to the dark stylesheet (if not already present) and change the switch icon
if (!stylesheet) {
stylesheet = document.createElement("link");
stylesheet.id = "dark-theme";
stylesheet.href = getResourceURL("stylesheets/darken-9gag.css");
stylesheet.rel = "stylesheet";
stylesheet.type = "text/css";
document.getElementsByTagName("head")[0].appendChild(stylesheet);
themeSwitch.firstChild.src = HighBrightness;
}
// finally save the state in extension storage
if (typeof(browser) == "undefined") {
chrome.storage.local.set({gagIsDark: true});
}
else {
browser.storage.local.set({gagIsDark: true});
}
}
}

function registerThemeSwitchObserver() {
// function to call, if body observer fires
let callback = function() {
// function to be run by the below promise on success
function onGot(item) {
if (item.gagIsDark == undefined) {
if (typeof(browser) == "undefined") { chrome.storage.local.set({gagIsDark: false}); }
else { browser.storage.local.set({gagIsDark: false}); }
}
// check if the trigger is present
var trigger = document.getElementById("switch-theme-trigger");
// if the trigger is present (user requested theme change)
if (trigger != null) {
// if storage is dark and request is smth else (reset) => switch theme to normal
if (item.gagIsDark === true && trigger.getAttribute("data-switch-to") != "toDark") {
switchTheme("reset");
}
// if storage is normal and request change to dark => switch theme to dark
else if (item.gagIsDark === false && trigger.getAttribute("data-switch-to") == "toDark") {
switchTheme("toDark");
}
//finally remove the trigger
trigger.parentNode.removeChild(trigger);
}
//if the trigger is not present (first load or user navigated)
else {
// switch theme according to the storage item
if (item.gagIsDark === true) {
switchTheme("toDark");
} else {
switchTheme("reset");
}
}
}
// function to be run by the below promise on an error
function onError(error) {
console.debug(`Error: ${error}`);
}
// Chrome: uses "chrome" namespace, doesn't support promises
if (typeof(browser) == "undefined" && typeof(chrome) != "undefined") {
// read the extension storage and run onGot() as callback
chrome.storage.local.get(null, onGot);
}
// Edge: uses "browser" namespace, doesn't support promises
else if (typeof(chrome) == "undefined" && typeof(browser) != "undefined") {
// read the extension storage and run onGot() as callback
browser.storage.local.get(null, onGot);
}
// Firefox: supports both namespaces and promises
else {
// read the extension storage (it's a promise)
let get_storage = browser.storage.local.get();
// if successful, run onGot(); if not run onError()
get_storage.then(onGot, onError);
}
};
// elements to be observed
let config = { childList: true, subtree: true };
// create and attach the observer
let body_observer = new MutationObserver(callback);
body_observer.observe(document.body, config);
}

// Add the switch to the site when DOM is ready
document.addEventListener("DOMContentLoaded", addThemeSwitch);
// Register the observer
document.addEventListener("DOMContentLoaded", registerThemeSwitchObserver);
12 changes: 12 additions & 0 deletions components/no-ora-tv.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* ### Remove annoying paid video post from ora.tv ### */
function rmOraVid() {
// find it
let ora = document.querySelector('iframe[src^="https://www.ora.tv"]');
// and delete it
if (ora) {
ora = ora.parentNode.parentNode;
ora.parentNode.removeChild(ora);
}
}
// TODO: Replace event by Mutation Observer
document.addEventListener("scroll", rmOraVid);
18 changes: 18 additions & 0 deletions components/no-social-buttons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* #### Remove sharing buttons #### */
function rmShareBtns() {
// get all of the buttons (actually the wrappers)
let shareBtnsWrap = document.getElementsByClassName("share");
// ...and remove 'em
for (let i = 0; i < shareBtnsWrap.length; i++) {
shareBtnsWrap[i].parentNode.removeChild(shareBtnsWrap[i]);
}
}

function rmStickyBtn() {
let stickyBtn = document.getElementById("jsid-sticky-button");
stickyBtn.parentNode.removeChild(stickyBtn);
}

// TODO: replace onscroll event with Mutation Observer
document.addEventListener("scroll", rmShareBtns);
document.addEventListener("DOMContentLoaded", rmStickyBtn);
39 changes: 39 additions & 0 deletions components/nsfw-unlock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* #### Show NSFW posts when not logged in #### */
// Helper function to support both image and video/gif posts
function hasVideo(postId, parentNode) {
const srcUrlBase = "https://img-9gag-fun.9cache.com/photo/" + postId;
// create a video node with the unlocked post as source
var video = document.createElement("video");
video.src = srcUrlBase + "_460sv.mp4";
video.loop = true;
video.controls = true;
video.volume = 0.5;
// inject it into the site asap
video.onloadedmetadata = function() {
parentNode.appendChild(video);
}
// on error == if no video exists, replace it with the still image
video.onerror = function() {
var image = document.createElement("img");
image.src= srcUrlBase + "_460s.jpg";
parentNode.appendChild(image);
}
}

// Main function that detects and replaces NSFW posts
function unlockNsfwPosts() {
// get all NSFW post
let nsfwPosts = document.getElementsByClassName("nsfw-post");
// for each of them:
for (let i = 0; i < nsfwPosts.length; i++) {
let parent = nsfwPosts[i].parentNode;
// get the 9gag id
let postId = parent.parentNode.parentNode.parentNode.getAttribute("id").split('-')[2];
// inject unlocked post
hasVideo(postId, parent);
// finally remove the placeholder
parent.removeChild(nsfwPosts[i]);
}
}
// TODO: replace onscroll event with Mutation Observer
document.addEventListener("scroll", unlockNsfwPosts);
14 changes: 14 additions & 0 deletions components/video-controls.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* #### Add controls to all videos/gifs #### */
function addControls() {
let videos = document.getElementsByTagName("video");
for (let i = 0; i < videos.length; i++) {
videos[i].controls = true;
videos[i].volume = 0.5; // TODO: default video volume customizable
if (videos[i].nextElementSibling.classList[0] == "sound-toggle") {
videos[i].parentNode.removeChild(videos[i].nextElementSibling);
}
// TODO: remove a.badge-track around videos (div.post-container > div > a.badge-track > video)
}
}
// TODO: replace onscroll event with Mutation Observer
document.addEventListener("scroll", addControls);
Loading

0 comments on commit c0ce1b3

Please sign in to comment.