This commit is contained in:
Michael Campagnaro 2019-03-19 22:54:00 -04:00
parent 14d59b8546
commit 6824c594c9
7 changed files with 169 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules
.web-extension-id

21
LICENSE.md Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2016 Tanner Stokes
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

20
README.md Normal file
View File

@ -0,0 +1,20 @@
Replaces YouTube comments with random herp derps. This is modification of github.com/twstokes/herpderp
Note: Ignores iframe embedded videos, including the chat replay iframe on YouTube livestream vids.
## Install
* I have a signed xpi that you can immediately install. Open `build/` and drag the xpi into Firefox.
## Development
### Local Testing
In Firefox, open about:debugging and click `Load Temporary Add-on...` then select `manifest.json`.
file.
### Signing and Building
* Install web-ext with `$ npm install --global web-ext`
* Generate an unlisted xpi with 'web-ext sign --channel unlisted --api-key <your add-on signing key> --api-secret <your add-on signing secret>`. Those keys can be obtained from https://addons.mozilla.org/en-US/developers/addon/api/key/
* Drag downloaded xpi into Firefox.

BIN
icons/herp128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
icons/herp48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

103
index.js Normal file
View File

@ -0,0 +1,103 @@
// returns a random int from 1 to max
const randomInt = max => Math.floor(Math.random() * max);
// builds a string with random herps and derps
const derpString = (length = 20) => {
const randomLength = randomInt(length) + 1;
const randomDerp = randomInt(2) ? "herp" : "derp";
return Array.from({ length: randomLength }, () => randomDerp).join(" ");
};
// herp derps an element
const derpElement = element => {
const c = element;
// preserve the original contents
c.derpOriginal = c.textContent;
// swap between the two when clicked
c.onclick = () => {
c.clicked = !c.clicked;
c.textContent = c.clicked ? c.derpOriginal : c.derpString;
};
// add derped class
c.classList.add("derped");
// create a derp string for this comment
c.derpString = derpString();
// change the contents
c.textContent = c.derpString;
c.clicked = false;
};
const checkComment = commentElement => {
const c = commentElement;
// if everything is fine, return
if (c.clicked && c.textContent === c.derpOriginal) return;
if (!c.clicked && c.textContent === c.derpString) return;
// otherwise, fix the comment
// the only case of malformed comment encountered so far are these two cases:
if (c.textContent.indexOf(c.derpString) !== -1) {
// in the case of the new comment being appended after the derp string,
// just grab it and put it in the derpOriginal variable
const idx = c.derpString.length;
c.derpOriginal = c.textContent.substring(idx);
c.textContent = c.textContent.substring(0, idx);
c.clicked = false;
return;
}
if (c.textContent.indexOf(c.derpOriginal) !== -1) {
// Same issue but the comment was appended after derpOriginal
const idx = c.derpOriginal.length;
c.derpOriginal = c.textContent.substring(idx);
c.textContent = c.derpString;
c.clicked = false;
}
};
const init = commentsSection => {
// selectors for comments
const selectors = ["#content-text"];
// build the full selector string
const derpSelectorString = selectors
.map(sel => `${sel}:not(.derped)`)
.join(", ");
const checkSelectorString = selectors.map(sel => `${sel}.derped`).join(", ");
// Only watch for child list changes, as we're watching the comments container
const mutationConfig = { attributes: false, childList: true, subtree: true };
// Create a MutationObserver
// This object will monitor the comments for DOM changes
const observer = new MutationObserver(() => {
// Check that everything's fine with the already derped comments
// This is necessary because youtube does a lot of wizardry with comments in-between videos
document.querySelectorAll(checkSelectorString).forEach(checkComment);
// Derp all un-derped comments
document.querySelectorAll(derpSelectorString).forEach(derpElement);
});
observer.observe(commentsSection, mutationConfig);
};
// Check every so often if comments are loaded or not. Once they are, the timeout
// stops until the user leaves youtube or reloads the page. This needs to be
// done since comments are added in the DOM through js at an undetermined point
// through Youtube's execution.
const checkCommentsLoaded = () => {
setTimeout(() => {
// This selector is awful, but Youtube re-uses a lot of the DOM (the
// selector for the comments is re-used across a bunch of pages) so we need
// the exact path to the comments to match
const commentsSection = document.querySelector("html body ytd-app ytd-comments ytd-item-section-renderer #contents");
if (commentsSection !== null) {
init(commentsSection);
}
else {
checkCommentsLoaded();
}
}, 500);
};
checkCommentsLoaded();

23
manifest.json Normal file
View File

@ -0,0 +1,23 @@
{
"manifest_version": 2,
"name": "YouTube Herp Derp",
"description": "Replaces YouTube comments with herp derps. Forked from github.com/twstokes/herpderp",
"homepage_url": "https://michael.is",
"version": "1.0",
"icons": {
"48": "icons/herp48.png",
"128": "icons/herp128.png"
},
"content_scripts": [
{
"run_at": "document_idle",
"all_frames": false, // Ignore iframes.
"matches": [
"https://apis.google.com/*",
"https://plus.googleapis.com/*",
"https://www.youtube.com/*"
],
"js": ["./index.js"]
}
]
}