Version 0.1.0.
Added infinite scroll to the public Forum threads, and added options page to adjust whether to enable infinite scrolling in thread lists and inside threads separately.
diff --git a/background.js b/background.js
new file mode 100644
index 0000000..513d12e
--- /dev/null
+++ b/background.js
@@ -0,0 +1,13 @@
+function isEmpty(obj) {
+ return Object.keys(obj).length === 0;
+}
+
+chrome.runtime.onInstalled.addListener(function(details) {
+ chrome.storage.sync.get(null, function(items) {
+ if (details.reason == "install") {
+ if (isEmpty(items)) {
+ chrome.storage.sync.set({"list": true, "thread": true});
+ }
+ }
+ });
+});
diff --git a/console_inject.js b/console_inject.js
index 0cfbeae..2bc6f15 100644
--- a/console_inject.js
+++ b/console_inject.js
@@ -1,12 +1,14 @@
+var mutationObserver, intersectionObserver, options;
+
function mutationCallback(mutationList, observer) {
mutationList.forEach((mutation) => {
if (mutation.type == "childList") {
mutation.addedNodes.forEach(function (node) {
- if ((typeof node.classList !== "undefined") && node.classList.contains("view-more-button-container")) {
+ if (options.list && (typeof node.classList !== "undefined") && node.classList.contains("view-more-button-container")) {
intersectionObserver.observe(node.querySelector(".view-more-button"));
}
- if ((typeof node.classList !== "undefined") && node.classList.contains("load-more-bar")) {
+ if (options.thread && (typeof node.classList !== "undefined") && node.classList.contains("load-more-bar")) {
intersectionObserver.observe(node.querySelector(".load-more-button"));
}
});
@@ -28,13 +30,17 @@
subtree: true
}
-var mutationObserver = new MutationObserver(mutationCallback);
-mutationObserver.observe(document.querySelector(".scrollable-content"), observerOptions);
-
var intersectionOptions = {
root: document.querySelector('.scrollable-content'),
rootMargin: '0px',
threshold: 1.0
}
-var intersectionObserver = new IntersectionObserver(intersectionCallback, intersectionOptions);
+chrome.storage.sync.get(null, function(items) {
+ options = items;
+
+ mutationObserver = new MutationObserver(mutationCallback);
+ mutationObserver.observe(document.querySelector(".scrollable-content"), observerOptions);
+
+ intersectionObserver = new IntersectionObserver(intersectionCallback, intersectionOptions);
+});
diff --git a/forum_inject.js b/forum_inject.js
index 204c2fc..a2209cd 100644
--- a/forum_inject.js
+++ b/forum_inject.js
@@ -1,3 +1,5 @@
+var intersectionObserver;
+
function intersectionCallback(entries, observer) {
entries.forEach(entry => {
if (entry.isIntersecting) {
@@ -10,5 +12,10 @@
threshold: 1.0
}
-var intersectionObserver = new IntersectionObserver(intersectionCallback, intersectionOptions);
-intersectionObserver.observe(document.querySelector(".thread-list-threads__load-more-button"));
+chrome.storage.sync.get(null, function(items) {
+ var button = document.querySelector(".thread-list-threads__load-more-button");
+ if (items.list && button !== null) {
+ intersectionObserver = new IntersectionObserver(intersectionCallback, intersectionOptions);
+ intersectionObserver.observe(button);
+ }
+});
diff --git a/manifest.json b/manifest.json
index 83171f9..5587c04 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "Infinite Scroll in TW",
- "version": "0.0.4",
+ "version": "0.1.0",
"description": "Get infinite Scroll in the Google Forums and the Community Console",
"icons": {
"512": "icons/512.png",
@@ -15,10 +15,26 @@
{
"matches": ["https://support.google.com/*/threads*"],
"js": ["forum_inject.js"]
+ },
+ {
+ "matches": ["https://support.google.com/*/thread/*"],
+ "js": ["thread_inject.js"]
}
],
"permissions": [
"https://support.google.com/s/community*",
- "https://support.google.com/*/threads*"
- ]
+ "https://support.google.com/*/threads*",
+ "https://support.google.com/*/thread/*",
+ "storage"
+ ],
+ "options_page": "options.html",
+ "options_ui": {
+ "page": "options.html",
+ "chrome_style": true,
+ "open_in_tab": false
+ },
+ "background": {
+ "scripts": ["background.js"],
+ "persistent": false
+ }
}
diff --git a/options.html b/options.html
new file mode 100644
index 0000000..48ce91e
--- /dev/null
+++ b/options.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Options</title>
+ </head>
+ <body>
+ <p><input type="checkbox" id="list"><label for="list"> Enable infinite scrolling in thread lists.</label><br>
+ <input type="checkbox" id="thread"><label for="thread"> Enable infinite scrolling inside threads.</label></p>
+ <p style="text-align: center;"><button id="save">Save</button></p>
+ <script src="options.js"></script>
+ </body>
+</html>
diff --git a/options.js b/options.js
new file mode 100644
index 0000000..d8ce844
--- /dev/null
+++ b/options.js
@@ -0,0 +1,31 @@
+function isEmpty(obj) {
+ return Object.keys(obj).length === 0;
+}
+
+function save() {
+ chrome.storage.sync.set({
+ "list": document.querySelector("#list").checked,
+ "thread": document.querySelector("#thread").checked
+ }, function() {
+ window.close();
+ });
+}
+
+window.addEventListener("load", function() {
+ chrome.storage.sync.get(null, function(items) {
+ if (isEmpty(items)) {
+ items = {"list": true, "thread": true};
+ chrome.storage.sync.set(items);
+ }
+
+ if (items.list === true) {
+ document.querySelector("#list").checked = true;
+ }
+
+ if (items.thread === true) {
+ document.querySelector("#thread").checked = true;
+ }
+
+ document.querySelector("#save").addEventListener("click", save);
+ });
+});
diff --git a/thread_inject.js b/thread_inject.js
new file mode 100644
index 0000000..0cbc254
--- /dev/null
+++ b/thread_inject.js
@@ -0,0 +1,21 @@
+var intersectionObserver;
+
+function intersectionCallback(entries, observer) {
+ entries.forEach(entry => {
+ if (entry.isIntersecting) {
+ entry.target.click();
+ }
+ });
+};
+
+var intersectionOptions = {
+ threshold: 1.0
+}
+
+chrome.storage.sync.get(null, function(items) {
+ var button = document.querySelector(".thread-all-replies__load-more-button");
+ if (items.thread && button !== null) {
+ intersectionObserver = new IntersectionObserver(intersectionCallback, intersectionOptions);
+ intersectionObserver.observe(button);
+ }
+});