// ==UserScript== // @id YoutubeTweak@Lunatrius // @name Youtube Tweak // @version 0.3.1 // @namespace Lunatrius // @author Lunatrius <lunatrius@gmail.com> // @description Add a delete button, automatically delete watched videos. // @match http://www.youtube.com/ // @match http://www.youtube.com/?* // @match http://www.youtube.com/watch* // @match https://www.youtube.com/ // @match https://www.youtube.com/?* // @match https://www.youtube.com/watch* // @include http://www.youtube.com/ // @include http://www.youtube.com/?* // @include http://www.youtube.com/watch* // @include https://www.youtube.com/ // @include https://www.youtube.com/?* // @include https://www.youtube.com/watch* // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAARlUlEQVR42u1baYxc1ZU+r7beu93dttv7CpjNi2xsFoFjGQ9mEQEktmFsK4AESaQIEQhD8mOCxkkgUkbCEiAYM4QJIQgwazDGgEnwgklYzWZs433rttvufal623zfqXerX5erenNn5Mh+0u2qest993z3nO8s97bl+76czEdETvLjFACnADgFwMl9xHKdtCxLP6urq+Wee+6RSZMmjRs6dOiPotHoQs/zRuNSHO1Ecx8Wxme3trYe+OCDD95++eWXH//22293Zt+U7fWsXG7QAFBZWSmPPvroopqamkcikUgFmhQUFEg8Hj8hZ9O2bW0cY0dHR/Pjjz/+0+eee+5/egIg1lOHN9988+LJkyf/IZlMqjZAC6SwsFAIRBis3mKJvtzT6/T2oQ9op3Cshw8fllQqVX7vvfc+6ThOwYsvvvhY3n7zacCMGTMmPvbYYx+j06rx48dLVVWVvoD3D3bwNBgAmX7YOEFHjx6VvXv3SmdnZ+ttt922YNeuXX/LpQF5SfC66667I5FIVFFwmgKQzAAw2Mdg9cl+OEaO1Yy7oqKiFLL8JJ+25zw5YsSIimnTpi10XVdVP9cAiXJxcXEGeaoem+EPHkVFRRKLpV/BQcEu/9/4gEBw7C0tLTJz5sx5GO+ZOPdVnwAAiYxEGwsNUEJhZ+GDJLh792555plnBMyrgl911VVy/vnn6/egD3nllVfkk08+0XuGDRsmt956azf+yMvMIRDD17PP9waAIewhQ4YMKykpOR1g9A0AyoiXxvhwLvtk52VlZfLGG2+onZF5a2tr5YILLsgMFO5Ili1bJt988w0JSW6//XbBIKS9vX3AJtFfUyHYlAGfUYypMnDfdl84wMJDVj7Eqc4jR46UG264QVWc3oEzTa3gbyL/xRdfyJ49e4i+zv5NN90kNCmCF248Z4h1sPmF/QWkaAXCR/ocCRpGDQ8u3Izal5eX6++6ujpZt26d0GyI/Jo1a8jAet+5554rU6dO1d+53mGAyTcO9sdmJiR8zpw3LZ8c/Q6Fe7M3CnbWWWfJ7NmzVa05kLfeekuFaWpqUjCofrzvyiuvVEI0QpI8CRRNg40aw+sGcCMYuYON3/ksATTNkC6Jta2tTRu/sz/jsfoCQKyvGpDr4OCuvfZaeeedd1SAzz77TDnhwIEDsm3bNh348OHDZf78+To43k+AEJ3J6tWrZf/+/fqOsWPHqjYtWLBABeA9fPb111+XlStX6rtmzZqlJsfjww8/lBUrVug9fJb8Ysg1rB00RwKRi3h7zQX6AgBnfu7cucwV1N5JfJz5gwcPqsB8/vLLLxcGUpw1zgyiM3nttdf0eQrKY9OmTfLmm2/K1VdfLXfddZcOmlqyefNmNSUCRwI1gtXX18uGDRv0/DnnnKPv4Xcz6+yXjeRMEHoCINITg/bEAWwUiL72sssuUzCo1k8//bTOnOECCsV7qSEvvPCCzhzDacQact9998ndd9+tJEozePXVV2Xt2rUqLAWiCfE5487MmHiN5/gOcz7cjOmY1pMZ9EqCPbkjflJlaQaIuPR+ur0dO3boDJx22mnqGjn7zc3NOpucEWrHNddco3HBHXfckQGQx8cff5wRhP0bgjSMbsYU9ihhjc3XBkyC2W7LDMZ8Upizzz5bFi5cqEREAYk6z1P9OVOHDh3SOIGqy2tBtKlC8z5qgBHwyJEjGaEMyKYZ+851ftABCJtA9guzGwd84403qjpyZmgadI+MDEmI1AD2lQ2kGVz4HJ9Nn48EfbuZWMFoRvbEZJtArtYvALKR6y1AoYD08yRD46bo+ydMmKACGVcWVulsTxM+n7ZjDo3gGPC7m2VYG49HA2K9mUBfIjQzCBIiBeZvcgI1omtGrW4aY8gsHF6be7oG7QegWMdwQK77BxIIxXoyATNr+QAw6kvbZ1DCzMsIaHy5MaV8GpALgC615f0ENP3dMLwhQfP+MDfkk2NAAPQUB/Aa/SyFN/eYdNcIaNyQ6S+sUUYDsjUtzA18bfj9YUDDHNSTkAMCoDfbMfk/bZ0DoCD5QDLNeAcjpEmrDVBGGPp9wxlhcMw5ExOE3/cPyQWyvUA26ZnZ7gmksAAMWsaNG6daw77Xr1+vINIVMpMkQLxG4jRFlPDMM8rkeVR65fnnn9f+ciVM/fUCsf4GQgx8jBDZA+ipD846SlOCcrWee/vttzW2py1v2bJFz7HGwMiRxEkBGQ6b2sPGjRvl+uuvl61btyr41ASTXfamAT1NVKQ3EswuO4fdWnbjdRPzG5BMI3AXXXSRLF26VGsE5I6PPvpIPv30UxWINYOHHnpIUIrLvOfiiy/WeILZJQMkgsCAa8mSJdLY2Jhxuf8wDQh/54DYDJtnawDV8/7779e6AK+ffsYZYtMF0pRMCg0QFmPwc7/3PVmHmH/Hzp2CsotMRsh8ySWXyJjRo6UtSK0JwvQZM2T58uWy5r33pBjccOGFF2ryxUyTMQffO2rUqAyXDIQDcpbFEcNPe+mll9YildXFEKopZ/CY2IAgQHA/OF9UVKgRXCQArDNcBDV1PZIfngnbsMkpbNtJ3yBdA2biZDiB4+CM83cCJqBxAs4loU35hOS9CMG9efPm/Rha8zTelex3PcD49Ix5sIrD3B4kFt++XeJQUQshq3QCJMcWC8IkuELDdNfzOUz9FGoE/DoX1TLDDb7EKQDfEQegBAdVLIvRYCyqIENiiUJoFCrFixeIH0+Ij24d8IM1ckQagBxVpeMOhKiKYT+uNUF8b4fglc/8UYr37+sSRgX2JHDgx3oQgiB5luICgf0YPhMUGHl8Au6uCOkuNau0WKyyEnyWilVRKZEhqHGWVIhT2yBt+/ZKx8yZCpyVBcKgcEC4A8pwFJld9SOPSMmO78QpLsVsxOnMA9ksPpyh1whmLUIzSQfzOd4D3DqT4kL9o5jVaFGBmhSDP99Cny5aCmC2Q7P8dmgYAiVyURIFl/IWiVQPldIGrEeQTEGykqPE3m8NMKyay701wa7t9RtkyI6dEL5E7CuvksR5s8TnoogEE2zsmL79r3+Vwu3bxIrFj5l79uxwQfOK+ZI4d6qkNn0u/gcboOaYyUigFcwDXGiGzaepYSmhRfkpZIhJgNIA8ysploL6WrFPO128kTXo1B0cDQijZ+LuJhQ2KjZ/w7GJHQUZTZ8mlZdemvcFR7ZsFn/z19CQY1/l02wBQBFcXxnYvRn8QMB83uuluUZcapSbFirqqNDkGq8QQHQk1Uy8+jqJpBB279kt/his3rve4HFAuNiYop8HACMaG6CiuFYIdX3/fWnduk1s1vH+7RYpgD9v/fJLcVatgjoXSwRBToS5PcgRU5vuy3HSqhqwu7JZ+otE8J0kqr/IAV5EAj3AcwCho1M8oE9TkVSxuIkkzKMJ2hSDNhxNjzdM2APVgGz0tH5PgoEJxFvbdBARzJS1c4d4KIPZ+O1d+31BRCMOiiD2mndBXiiFl5ZJ24SJSo4F9YdV8OTIUTAJzNjRIxLp6Fop8u2UwLIldubZcG8oaKK0loikgfFa26UzUSgyeSL9rbj790hi23YpKCnEWABODGbT3KL9M/aQrOW0vG6yPybAwIYAREBaGULjrBZH9KcVCTI/VmLBDyRGd9JEqfrPpeJBc1ru+5lY7R1S8YufS7ymRo4++Bux1q3P+EJrzFgp/e1vpWzKFFqA1P/+fyX15HJBvVfappwp5XiuFHZOTFIA7igKrM5Ty6WoOCFewhavpVm9QHYQ1+9kyJBfdsjrElVmgFBR34+mjThogecLAhtLTNhDJo8rTvF0TAA1jgIgIu9jVp3aOvE6gwXVYcPFXv2OtG78UAhl+YL5koKmdEbiUoEosxzCt7/3F6l/+GE1oxGLl4g7b4E4R1rEbU1ytUYFyq4QD7gsnr38RKEiXHUBF7iwVZqEfur3Lh/PwMd1UTbnIkeQsOhy2iHs3MCagR+sBzgIe52WVq378WiFB2h/8CFpwcKJpslgdxdaZdcMleLJk8WhVkD4jl//RlreX5uOFKfPkGQHVoPak+I0NUuEQVuOXOW4vYAJZ9PVHkcHI8lOiXqIxBSELg1ghJg8eAAE5kkKqm6edXC/OF2LswTO15ZBXTwIHQk5TMdDfMAJoNvhvQh4UkPKpayyKgghY7gH5JlyxCWf5OCA41oay2VPDgbiUL3bMHtQUYvxeDKVmVkPQY3d3qokaWZXvThJ1HNDACDMxm8NlYN7KLCVqUTzN67Drfleuigy8YFfdoUawU02Z91zulWTJMRdAw6EstVHzQCDcMzAOKuo9ZN47Ei0WwmdsxK1PAWrazZRxwv5aC2Du07mOQ/3plSYLrfo4n4+YwUctA/qHz+4XwMoxgYO9gJZBXGxNTnDZLDypJFkpE9uMNIXDciUtTgIZGdJzKyuv9Ec0vGZqnNGMCEAnsYGbkgYU/c3JbE0AOnZTYcD3jFL5bzuBGG0BmLr10rTq6+DGKMSmzNb3NGjND4heD5qBxHmA4O1MhRuRLEQcT2TkVRBQl0iVc80Rwcd0gAOnMKEYvP2xiZJAsAoXWQAAEEy4lI52hoaEfp39UMAbcT9XlCI8QuLpAW2XoGFmFE//JGU/ctCScK12gQxyDtyjX9QQuECoJvAwqWN5rDwYa7h5coJpl6A7zbUPYqfDkJXihMvKZWaBx6Q0jNOl0R5WVpgVpm46hO8s/rSBWI/+d9SjkUWLb81NuN55Bh79krT559L9XnnyZj/+KU0f/WVVKM4wqP5o78rkXICCqgBdLe2PTgbJI4xAcxADCydQirq2K5mhpw12rsHN2A3NepsYr+qzryLIMnZ9p00b/pSSWs4Slx1L6yQhq+/xqwm1Vu4iBlsRpZ0cVjyLhpeI5VIjEiOdX/6k/hwkxEkPnv+/edSj6CpctpUmbhksbrXXQ8vk+YVL2Hmi7DxB6IwTWap/Xg1INfD/EwvVxdLK8JRG4NF+KUuUDkZLLzjhz9GPo/4nalqQaGk+HxLk2zFKnABbRW1Axek1bzyjXT6jMgtXlUptf/1O6lDeu1yYQXVnQMokfk0Mew5Yr7hIJeQXTtl+60/kL1jx0kEtQG77hC08JDEUCtwJL2GGBs3RmfUy+G5+hsKe7B5J/tBAlCBOPzQ7DnSuXK1FBypF4+8YBgbhUsrYGN6C6iGRoIWApR2XKN9WgnkB4eOdCVDZOiGZryxEaDQ32P5fMvWdAKEZEgDLIIcjetnctcuzRRZKbIw8/QMPgKqGHaQlGO7Tq5Q2Esffp8BQBW2vqGhoRY1wepsN1iFNb8qxPeHlywSeQJxekODCuHrRqx0s+D+EKtmFUCiGh2i8hEqMztZ2888SUuXLrxK0u5eUyQQ/OAfZoZep2pK9MwzZOyvlkopdof6QeE2PGYUatuxP6E9VzkqJwBYy6/Fvp/1U6ZMOSd7EZS7N8bXoAa34FJpZO69fqNYUG0tiCCmZ23QD5ImFdCXTIlMYwDXCaqx2XYnmfwB/jatRSagIY50b1B3NR1WmPA9VlQipdOny9h/vVGqsOii781xvPvuu/ugAXUB7/ZtszQ2PczFZqTVWJQoNHt5whub22GrTdzgwHgAaSxLWqwJ0pczSPGY0wfr+lofpEvUoqgbypq6A6AfjONNiS2omZHYWBC1zHYYqH8Mv4sxGRUVQ6SQ97puzk1c2DTtz5kz54/bt2//NU5t6c//C8SwheXBp5566t7wgmc2EJlFzVA/um4fFixY5PTy1AW7uaUchJU5F1oqy5Bbnv0LxgwWLVr02bPPPrsMX19kKHLMvbl2fISOUYsXL/496ukY+z/XAQ7zbrnlli8gwy/QxueTt8f/GAmOCdjmtuTOO++8/oorrpg0evToIqiWdaL9w2Ww49Tft29f56pVqw4/8cQTX2Hr3hpc+jPad3k3ZvcBAB7MPWdglWVWaWnpeKhXcbflmxPkoK/DKnIz8o3d+Mmd4Z8zvupxZ3ofATDWXIpWweLNiQhAQKusqDahteRye30C4GQ6Tv3j5CkATvLj/wDOP4vR7t0CuAAAAABJRU5ErkJggg== // @run-at document-end // ==/UserScript== /*jslint devel: true, browser: true, regexp: true, continue: true, plusplus: true, maxerr: 50, indent: 4 */ /*global XPathResult: false */ (function () { "use strict"; // add an item to the array if it doesn't exist Array.prototype.add = function (element) { var i; for (i = 0; i < this.length; i++) { if (this[i] === element) { return false; } } this.push(element); return true; }; // remove all matching items Array.prototype.remove = function (element) { var removed = [], i; for (i = 0; i < this.length; i++) { if (this[i] === element) { removed.push(this.splice(i--, 1)[0]); } } return removed; }; // return true if the element was found Array.prototype.exists = function (element) { var i; for (i = 0; i < this.length; i++) { if (this[i] === element) { return true; } } return false; }; // some variables var msg, debug, DomStorage, YoutubeTweak, yt, cfg, saveAmount; // inicialization yt = null; debug = true; saveAmount = 500; // correct a few things if (saveAmount > 0) { saveAmount = -saveAmount; } // debug function msg = debug ? function (message) { console.log(JSON.stringify(message)); } : function () {}; /*************************************************************** * Name: DOM Storage Wrapper Class * Author: Lunatrius <lunatrius@gmail.com> * * Public members: * ctor({"session"|"local"}[, <namespace>]) * set(<key>, <value>) * get(<key>, <default value>) * remove(<key>) * keys() * removeAll() ***************************************************************/ DomStorage = function (type, namespace) { // variables var t = this, s, value, keys, key, i; // check if type if specified if (typeof (type) !== "string") { type = "session"; } // check if namespace if specified if (!namespace || (typeof (namespace) !== "string" && typeof (namespace) !== "number")) { namespace = "script"; } // bind the storage of a specific type to a variable switch (type) { case "local": s = localStorage; break; default: // case "session": s = sessionStorage; break; } // concat the namespace string namespace = ["domstorage", namespace].join(".").replace(/[^a-z0-9\.\-]/gi, "_"); // set a key with a value t.set = function (key, value) { s.setItem([namespace, key].join(".").replace(/[^a-z0-9\.\-]/gi, "_"), JSON.stringify(value)); }; // get the value of a key, if there is none return the default value t.get = function (key, defaultValue) { value = JSON.parse(s.getItem([namespace, key].join(".").replace(/[^a-z0-9\.\-]/gi, "_"))); if (value !== null && value !== undefined) { return value; } return defaultValue; }; // remove a key t.remove = function (key) { s.removeItem([namespace, key].join(".").replace(/[^a-z0-9\.\-]/gi, "_")); }; // return an array of keys t.keys = function () { keys = []; for (i = s.length - 1; i >= 0; i--) { key = s.key(i).replace([namespace, ""].join("."), ""); if (key !== s.key(i)) { keys.push(key); } } keys.sort(); return keys; }; // remove all keys t.removeAll = function () { keys = t.keys(); for (i = keys.length - 1; i >= 0; i--) { t.remove(keys[i]); } }; }; // the core of the script YoutubeTweak = function () { // delarations var t = this; // initialization t.style = null; // hotkey handler t.hotkey = function (e) { var value = null; if (e.altKey === true) { switch (e.keyCode) { case 49: value = cfg.get("removewatched", true); if (confirm("Do you want to " + (value ? "disable" : "enable") + " the removal of watched videos?")) { value = !value; cfg.set("removewatched", value); alert((value ? "Enabled" : "Disabled") + " the removal of watched videos."); } break; case 50: value = cfg.get("removeignored", true); if (confirm("Do you want to " + (value ? "disable" : "enable") + " the removal of ignored videos?")) { value = !value; cfg.set("removeignored", value); alert((value ? "Enabled" : "Disabled") + " the removal of ignored videos."); } break; } } }; // initialization entry point t.init = function () { cfg = new DomStorage("local", "YoutubeTweak"); try { window.addEventListener("keydown", t.hotkey, false); window.wrappedJSObject.ytt = cfg; document.head = document.head || document.getElementsByTagName("head")[0] || document.documentElement; } catch (ex) { } t.main(); }; // main function t.main = function () { var videoId; // video page if (location.pathname === "/watch") { videoId = t.getVideoId(location.search); if (videoId) { t.addWatched(videoId); } } // main page if (location.pathname === "/") { // add the button design t.addStyle(".yt-tweak-button", { "position": "absolute", "top": "16px", "right": "2px", "width": "12px", "height": "12px", "cursor": "pointer", "background": "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAMAAABhq6zVAAAACVBMVEX///9mZmb///+ofUk6AAAAAXRSTlMAQObYZgAAADFJREFUeNpljkEKAEAIAp3+/+jFLYRoTg2KJBEkKmD5Tgv4gEnMJG11JLU9cKcD650HPsQAzejNIlMAAAAASUVORK5CYII=')" }); // add the button design - hover t.addStyle(".yt-tweak-button:hover", { "background": "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAMAAABhq6zVAAAACVBMVEX///8AAP////+g6om+AAAAAXRSTlMAQObYZgAAADFJREFUeNpljkEKAEAIAp3+/+jFLYRoTg2KJBEkKmD5Tgv4gEnMJG11JLU9cKcD650HPsQAzejNIlMAAAAASUVORK5CYII=')" }); // execute the functions and create an interval t.homeFunctions(); setInterval(t.homeFunctions, 3000); } }; // add a video to the watched list t.addWatched = function (videoId) { try { var watched = cfg.get("watched", []); watched.add(videoId); cfg.set("watched", watched.splice(saveAmount)); } catch (ex) { msg(ex); } }; // add a video to the ignored list t.addIgnored = function (videoId) { try { var ignored = cfg.get("ignored", []); ignored.add(videoId); cfg.set("ignored", ignored.splice(saveAmount)); } catch (ex) { msg(ex); } }; // check if a videos was watched t.existsWatched = function (videoId) { try { var watched = cfg.get("watched", []); return watched.exists(videoId); } catch (ex) { msg(ex); return false; } }; // check if a videos was ignored t.existsIgnored = function (videoId) { try { var ignored = cfg.get("ignored", []); return ignored.exists(videoId); } catch (ex) { msg(ex); return false; } }; // clean any whitespaces t.strip = function (string) { string = string.replace(/\s+/g, " "); string = string.replace(/^\s+/g, ""); string = string.replace(/\s+$/g, ""); return string; }; // get the video ID (v argument) t.getVideoId = function (url) { var videoId = url.match(/v=([^&]+)/); if (videoId && videoId.length === 2) { return videoId[1]; } else { return null; } }; // append CSS style t.addStyle = function (cssRule, cssProperties) { var cssProp = [], i; if (t.style === null) { t.style = document.createElement("style"); t.style.id = "YoutubeTweak"; t.style.textContent = ""; document.head.appendChild(t.style); } for (i in cssProperties) { if (cssProperties.hasOwnProperty(i)) { cssProp.push(i + ": " + cssProperties[i] + " !important;"); } } t.style.textContent += cssRule + " {\n\t" + cssProp.join("\n\t") + "\n}" + "\n\n"; }; // used for the inverval timer t.homeFunctions = function () { t.addIgnoreButton(); t.expandLists(); t.deleteVideos(); // t.deletePlaylists(); // t.deleteListDescriptions(); // t.deleteListItems(); // t.deleteLists(); // t.deleteMainListItems(); }; // generate a function for one button t.addIgnoredHandler = function (videoId) { return function () { t.addIgnored(videoId); if (this.className === "yt-tweak-button") { this.parentNode.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode.parentNode); } }; }; // add a button t.addIgnoreButton = function () { var videoSnap, i, videoId, button; videoSnap = document.evaluate("//div[contains(@class,'feed-page')]/ul/li/div[contains(@class,'feed-item-container')]/div[contains(@class,'feed-item-outer')]/div[contains(@class,'feed-item-main')]/div/div/h4/a[contains(@class,'title') and not(@button)]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); for (i = 0; i < videoSnap.snapshotLength; i++) { button = document.createElement("div"); button.classList.add("yt-tweak-button"); videoSnap.snapshotItem(i).parentNode.parentNode.parentNode.parentNode.appendChild(button); videoSnap.snapshotItem(i).setAttribute("button", "yes"); videoId = t.getVideoId(videoSnap.snapshotItem(i).href); if (videoId !== null && typeof (videoId) === "string") { button.addEventListener("click", t.addIgnoredHandler(videoId), false); } } }; // try to delete all video on the page t.deleteVideos = function () { var videoSnap, i, videoId; videoSnap = document.evaluate("//div[contains(@class,'feed-page')]/ul/li/div[contains(@class,'feed-item-container')]/div[contains(@class,'feed-item-outer')]/div[contains(@class,'feed-item-main')]/div/div/h4/a[contains(@class,'title')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); for (i = 0; i < videoSnap.snapshotLength; i++) { videoId = t.getVideoId(videoSnap.snapshotItem(i).href); if (videoId !== null && typeof (videoId) === "string") { t.deleteVideo((t.existsWatched(videoId) && cfg.get("removewatched", true) === true) || (t.existsIgnored(videoId) && cfg.get("removeignored", true)), videoId); } } }; // delete one video on the page t.deleteVideo = function (deleted, videoId) { if (deleted === true) { var videoSnap, node, container, i; videoSnap = document.evaluate("//div[contains(@class,'feed-page')]/ul/li/div[contains(@class,'feed-item-container')]/div[contains(@class,'feed-item-outer')]/div[contains(@class,'feed-item-main')]/div/div/h4/a[contains(@class,'title') and contains(@href,'v=" + videoId + "')]/../../../..", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); for (i = 0; i < videoSnap.snapshotLength; i++) { node = videoSnap.snapshotItem(i).parentNode.parentNode.parentNode; container = node.parentNode.parentNode; node.parentNode.removeChild(node); if (container.firstElementChild.childElementCount === 0) { // console.log("deleting empty container..."); container.parentNode.removeChild(container); } // videoSnap.snapshotItem(i).parentNode.parentNode.parentNode.parentNode.removeChild(videoSnap.snapshotItem(i).parentNode.parentNode.parentNode); } } }; /* // delete playlists - these are useless as everything is ALREADY listed t.deletePlaylists = function () { var snapPlaylists, item, i; snapPlaylists = document.evaluate("//div[contains(@class,'feed-item-content-playlist')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); for (i = 0; i < snapPlaylists.snapshotLength; i++) { item = snapPlaylists.snapshotItem(i); item.parentNode.removeChild(item); } snapPlaylists = document.evaluate("//div[contains(@class,'feed-item-main')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); for (i = 0; i < snapPlaylists.snapshotLength; i++) { item = snapPlaylists.snapshotItem(i); if (item.childElementCount === 2 || item.childElementCount === 1) { item.parentNode.removeChild(item); } } }; // delete list descriptions t.deleteListDescriptions = function () { var snapListDesc, item, i; snapListDesc = document.evaluate("//div[contains(@class,'feed-item-description')]/div", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); for (i = 0; i < snapListDesc.snapshotLength; i++) { item = snapListDesc.snapshotItem(i); if (item.children.length === 0) { item.parentNode.parentNode.removeChild(item.parentNode); } } }; // delete all remaining trash elements t.deleteListItems = function () { var snapListItems, item, i; snapListItems = document.evaluate("//div[contains(@class,'feed-page')]/ul/li/div/div", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); for (i = 0; i < snapListItems.snapshotLength; i++) { item = snapListItems.snapshotItem(i); if (item.children.length === 0) { item.parentNode.parentNode.parentNode.removeChild(item.parentNode.parentNode); } } }; // delete remaining list elements t.deleteLists = function () { var snapListItems, item, i; snapListItems = document.evaluate("//div[contains(@class,'feed-page')]/ul", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); for (i = 0; i < snapListItems.snapshotLength; i++) { item = snapListItems.snapshotItem(i); if (item.children.length === 0) { item.parentNode.parentNode.removeChild(item.parentNode); } } }; // delete remaining main list elements t.deleteMainListItems = function () { var snapMainListItems, item, i; snapMainListItems = document.evaluate("//li[contains(@class,'feed-item-container')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); for (i = 0; i < snapMainListItems.snapshotLength; i++) { item = snapMainListItems.snapshotItem(i); if (!/watch([^"]+)v=([^&]+)&/i.test(item.innerHTML)) { item.parentNode.removeChild(item); } } }; */ // auto expand the lists ONCE t.expandLists = function () { var spanSnap, item, i; spanSnap = document.evaluate("//a[contains(@class,'show-more') and not(@done)]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); for (i = 0; i < spanSnap.snapshotLength; i++) { item = spanSnap.snapshotItem(i); try { item.click(); } catch (exA) {} try { item.wrappedJSObject.click(); } catch (exB) {} item.setAttribute("done", "yes"); } }; // execute the script t.init(); }; // filter out and errors try { // only run on the specified domain if (/www\.youtube\.com/i.test(location.host) && window.top === window.self) { // only run on the main and video pages if (location.pathname === "/" || location.pathname === "/watch") { // create a new instance of the core yt = new YoutubeTweak(); } } } catch (ex) { msg(ex); } }());

Mozilla add on,User script,Grease Monkey Script, greasemonkey userscripts, updater userscripts mafia wars userscripts mafia wars autoplayer userscripts mafia wars wall userscripts scripts userscripts travian greasemonkey greasemonkey download greasemonkey facebook greasemonkey tutorial greasemonkey youtube greasemonkey travian greasemonkey chrome greasemonkey mafia wars greasemonkey mafia wars autoplayer
Sunday, February 26, 2012
Youtube Tweak
Subscribe to:
Post Comments (Atom)
0 comments:
Post a Comment