Add code
This commit is contained in:
parent
14d59b8546
commit
6824c594c9
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
node_modules
|
||||
.web-extension-id
|
21
LICENSE.md
Normal file
21
LICENSE.md
Normal 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
20
README.md
Normal 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
BIN
icons/herp128.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.0 KiB |
BIN
icons/herp48.png
Normal file
BIN
icons/herp48.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
103
index.js
Normal file
103
index.js
Normal 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
23
manifest.json
Normal 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"]
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user