您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
.win enhancement suite - stable version
// ==UserScript== // @name WES // @namespace none // @version 0.1.2.4 // @description .win enhancement suite - stable version // @author melvin // @include https://communities.win/* // @include https://consumeproduct.win/* // @include https://gavinmcinnes.win/* // @include https://kotakuinaction.win/* // @include https://kotakuinaction2.win/* // @include https://omegacanada.win/* // @include https://patriots.win/* // @include https://weekendgunnit.win/* // @include https://greatawakening.win/* // @include https://ip2always.win/* // @include https://tuckercarlson.win/* // @include https://conspiracies.win/* // @resource TEST_CSS https://raw.githubusercontent.com/ilovestaples/wes/master/wes/css/settingscss.css // @grant GM.setValue // @grant GM.getValue // @grant GM_xmlhttpRequest // @grant GM_getResourceText // @grant GM_addStyle // @require https://code.jquery.com/jquery-3.5.1.min.js // @connect api.imgur.com // ==/UserScript== (function() { 'use strict'; console.log("WES " + GM.info.script.version); /************************ 0. Setup ************************/ var wes = { params: { expandMedia : false, enableBookmarks: false, }, expandMedia : function(media){ if(media && media.hasAttribute("data-action")){ media.click(); } $(media).closest('.post').find('.content').first().removeAttr('data-opened'); } } var tags = GM.getValue("tags", "{}").then(function(val) { console.log(val); var userTags = JSON.parse(val); var authors = document.getElementsByClassName("author"); for(var author of authors){ var user = author.innerText.trim(); if(userTags[user]){ var tag = createTag(); tag.id = ""; tag.style.color = userTags[user].color; tag.style.backgroundColor = userTags[user].backgroundColor; tag.textContent = userTags[user].text; author.parentElement.insertBefore(tag, author.nextSibling); tag.addEventListener("click", function(){userTaggerShowForm(this)}); } else { var tagbutton = createTagButton(); author.appendChild(tagbutton); tagbutton.querySelector("button").addEventListener("click", function(e){e.preventDefault(); userTaggerShowForm(this)}); author.addEventListener("mouseover", function(){ try{this.querySelector(".tag-button-container").style.display = "inline";}catch(error){}}); author.addEventListener("mouseout", function(){ try{this.querySelector(".tag-button-container").style.display = "none";}catch(error){}}); } } tags = userTags; }); /************************ 1. General Enhancers ************************/ /************************ 1.1. Create navigation bar ************************/ function generalEnhancerAddNavigationBar() { if(!wes.params.enableBookmarks){ console.log("Navigation bar disabled. Check back in the next update.") return; } var topBarCss = '.tool-bar-link {text-decoration: none;color: white;font-family: sans-serif;font-size: 13px;}.tool-bar-link {color:#fff;-moz-transition: all 0.1s ease-in;-o-transition: all 0.1s ease-in;-webkit-transition: all 0.1s ease-in;transition: all 0.1s ease-in;}.tool-bar-link:hover { color: #ff9d07; text-shadow: 0px 0px 8px #ff9d07;-moz-transition: all 0.1s ease-in;-o-transition: all 0.1s ease-in;-webkit-transition: all 0.1s ease-in; transition: all 0.1s ease-in;}.tool-bar-link:active {color: #ff9d07; text-shadow: 0px 0px 3px #ff9d07;-moz-transition: all 0.1s ease-in;-o-transition: all 0.1s ease-in;-webkit-transition: all 0.1s ease-in; transition: all 0.1s ease-in;}.bar-link{ font-family: sans-serif;font-size: 13px; color: white; text-decoration: none; position: relative;}.bar-link::after{ content: ""; background: white;mix-blend-mode: exclusion; width: calc(90% + 20px); height: 0; position: absolute; bottom: -3px; left: -6px;transition: all .3s cubic-bezier(0.445, 0.05, 0.55, 0.95);}.bar-link:hover::after{height: calc(100% + 8px)}'; var topBarStyle = document.createElement('style'); topBarStyle.className = "style-tag"; document.body.appendChild(topBarStyle); var appendedTopBarStyle = document.querySelector(".style-tag"); if(appendedTopBarStyle){ appendedTopBarStyle.innerHTML = topBarCss; } const winsitesArray = ["patriots", "consumeproduct", "conspiracies", "omegacanada", "kotakuinaction", "kotakuinaction2", "gavinmcinnes", "tuckercarlson", "weekendgunnit", "greatawakening", "ip2always", "communities"]; var topBar = document.createElement('div'); topBar.className = "top-bar" topBar.style.height = "30px"; topBar.style.backgroundColor = "black"; topBar.style.width = "auto"; topBar.style.opacity = 0.5; topBar.style.display = "flex"; topBar.style.alignItems = "center"; topBar.style.position = "absolute"; topBar.style.zIndex = 5; var linklist = document.createElement('ul'); linklist.style.listStyle = "none"; for (var i = 0; i < winsitesArray.length; i++) { addWhiteSpaceToList(linklist); var newli = document.createElement('li'); newli.style.display = "inline"; newli.style.color = "white"; newli.style.padding = "5px"; var newlink = document.createElement('a'); newlink.href = "https://" + winsitesArray[i] + ".win/"; newlink.innerHTML = winsitesArray[i]; newlink.className = "bar-link"; newlink.padding = "10px" newli.appendChild(newlink); linklist.appendChild(newli); addWhiteSpaceToList(linklist); if (i < winsitesArray.length - 1) { addDividerToList(linklist) } } topBar.appendChild(linklist); var wrapper = document.getElementsByClassName("wrapper"); var header = document.getElementsByClassName("header"); if(wrapper[0] && header[0]){ wrapper[0].insertBefore(topBar, header[0]); } var themeSwitcher = document.querySelector(".theme-switcher"); if(themeSwitcher){ themeSwitcher.style.zIndex = 1; } } /************************ 1.2 Post/comment point redirection ************************/ function generalEnhancerAddPointRedirection(){ var navuser = document.querySelector(".nav-user.active"); if(navuser){ var username = navuser.children[0].children[0].text; var postKarma = document.createElement('a'); var commentKarma = document.createElement('a'); postKarma.href = "https://" + window.location.hostname +"/u/" + username + "/?type=post"; commentKarma.href = "https://" + window.location.hostname +"/u/" + username + "/?type=comment"; var pointsText = navuser.children[0].childNodes[2]; var pointsTextContent = pointsText.textContent; var postKarmaText = pointsTextContent.substring(pointsTextContent.indexOf("(") + 1, pointsTextContent.indexOf("•") - 1); var commentKarmaText = pointsTextContent.substring(pointsTextContent.indexOf("•") + 2, pointsTextContent.indexOf(")")); postKarma.innerHTML = postKarmaText; postKarma.title = "submitted" commentKarma.innerHTML = commentKarmaText; commentKarma.title = "comments"; var sp = document.createElement('span'); var text1 = document.createElement('text'); var text2 = document.createElement('text'); var text3 = document.createElement('text'); text1.textContent = "("; text2.textContent = " • "; text3.textContent = ")"; sp.appendChild(text1); sp.appendChild(postKarma); sp.appendChild(text2); sp.appendChild(commentKarma); sp.appendChild(text3); navuser.children[0].insertBefore(sp, pointsText); navuser.children[0].removeChild(pointsText); } } /************************ 1.3 Settings ************************/ function displaySettings(){ var overlay = document.getElementById("overlay"); overlay.style.display = "flex"; overlay.style.zIndex = "999"; var menu = document.getElementById("wes-settings-menu"); menu.style.display = "block"; menu.style.zIndex = "1000"; loadTagsTable(); } function hideSettingsOut(){ if (!$('#wes-settings-menu').is(':hover')) { hideSettings(); } } function hideSettings(){ var overlay = document.getElementById("overlay"); overlay.style.display = "none"; overlay.style.zIndex = "-999"; var menu = document.getElementById("wes-settings-menu"); menu.style.display = "none"; menu.style.zIndex = "-1000"; unloadTagsTable(); } function showGeneralSettings(){ var sections = document.body.querySelectorAll(".section-container"); for(var section of sections){section.style.display = "none";} document.getElementById("settings-general-sc").style.display = "block"; } function showTagSettings(){ var sections = document.body.querySelectorAll(".section-container"); for(var section of sections){section.style.display = "none";} document.getElementById("settings-tags-sc").style.display = "block"; } function addSettings(){ var overlay = document.createElement("div"); overlay.id = "overlay"; overlay.style.position = "fixed"; overlay.style.display = "none"; overlay.style.zIndex = "-999"; overlay.style.width = "100%"; overlay.style.height = "100%"; overlay.style.top = "0"; overlay.style.left = "0"; overlay.style.right = "0"; overlay.style.bottom = "0"; overlay.style.backgroundColor = "rgba(0,0,0,0.5)"; document.body.appendChild(overlay); var settingsMenu = document.createElement("div"); settingsMenu.id = "wes-settings-menu"; settingsMenu.style.display = "none"; settingsMenu.style.zIndex = "-1000"; settingsMenu.style.width = "900px"; settingsMenu.style.height = "600px"; settingsMenu.style.backgroundColor = "#444a4f"; overlay.appendChild(settingsMenu); var settingsCSS = document.createElement("style"); settingsCSS.innerHTML = 'dialog {padding: 10px;}nav {padding: 10px; display: flex;justify-content: space-between;}.sections-list {color: white;font-size: small}.credits {color: white;font-size: small;display: flex;}.section-container {padding: 10px;}fieldset {border: 1px solid;border-radius: 3px;padding: 0.35em 0.625em;margin: 0px 2px;border-color: gray;}legend {color: white;padding: 1px;font-size: smaller;}.svg-inline--fa.fa-times.fa-w-11.close {cursor: pointer;}#utTable {border-collapse: collapse;border: 1px double gray;font-size: smaller;}td {border: 1px double gray;padding: 3px;}.settings-button:hover {text-decoration: underline;}.section-container {height: 750px;overflow: auto;}'; var settingsMainHTML = '<div id="wes-settings" class="dialog"> <nav> <div class="sections-list"><a class="tab-general settings-button" href="javascript:;">General</a> | <a class="tab-tags settings-button" href="javascript:;">Tagged Users</a> </div> <div class="credits"> <a class="settings-button" href="https://github.com/ilovestaples/wes/" target="_blank">WES</a> | <a class="settings-button" id="wes-menu-version" href="https://github.com/ilovestaples/wes/blob/master/CHANGELOG.md" target="_blank">version_number</a> | <a class="settings-button" href="https://gitreports.com/issue/ilovestaples/wes" target="_blank">Issues</a> | <span id="settings-close" style="cursor: pointer;" class="settings-button" title="Close"><span class="fa fa-times close"></span></span> </div> </nav> <div id="settings-general-sc" class="section-container"> <section class="section-advanced"> <fieldset> <legend>General Settings</legend> <span style="font-size: smaller; color: white;">In future updates, user customizable settings will be here.</span> </fieldset> </section> </div> <div id="settings-tags-sc" class="section-container"> <section class="section-advanced"> <fieldset> <legend>Tagged Users</legend> <table id="utTable" style="width:100%"> </table> </fieldset> </section> </div></div>'; const my_css = GM_getResourceText("TEST_CSS"); GM_addStyle(my_css); document.body.appendChild(settingsCSS); settingsMenu.innerHTML = settingsMainHTML; document.getElementById("wes-menu-version").innerHTML = GM.info.script.version; document.getElementById("settings-tags-sc").style.display = "none"; document.getElementById("settings-tags-sc").style.overflow = "auto"; document.getElementById("settings-tags-sc").style.height = "500px"; document.body.querySelector(".tab-general").addEventListener("click", showGeneralSettings); document.body.querySelector(".tab-tags").addEventListener("click", showTagSettings); document.getElementById("settings-close").addEventListener("click", hideSettings); } function settingsButton(){ var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svg.setAttributeNS(null, "aria-hidden", true); svg.setAttributeNS(null, "focusable", false); svg.setAttributeNS(null, "preserveAspectRatio", "xMidYMid meet"); svg.style = "vertical-align: -0.3em;-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg); cursor: pointer;"; svg.setAttributeNS(null, "class", "delete-tag-button"); svg.setAttributeNS(null, "width", "1.0em"); svg.setAttributeNS(null, "height", "1.0em"); svg.setAttributeNS(null, "viewBox", "0 0 512 512"); var path1 = document.createElementNS("http://www.w3.org/2000/svg", "path"); path1.setAttributeNS(null, "fill","currentColor"); path1.setAttributeNS(null, "d","M507.73 109.1c-2.24-9.03-13.54-12.09-20.12-5.51l-74.36 74.36l-67.88-11.31l-11.31-67.88l74.36-74.36c6.62-6.62 3.43-17.9-5.66-20.16c-47.38-11.74-99.55.91-136.58 37.93c-39.64 39.64-50.55 97.1-34.05 147.2L18.74 402.76c-24.99 24.99-24.99 65.51 0 90.5c24.99 24.99 65.51 24.99 90.5 0l213.21-213.21c50.12 16.71 107.47 5.68 147.37-34.22c37.07-37.07 49.7-89.32 37.91-136.73zM64 472c-13.25 0-24-10.75-24-24c0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24z"); var label = document.createElement("label"); label.className = "settings-button-label"; var button = document.createElement("button"); button.style.display = "none"; var container = document.createElement("span"); container.className = "settings-button-container"; container.style.display = "block"; svg.appendChild(path1); label.appendChild(svg); label.appendChild(button); container.appendChild(label); return container; } function generalEnhancerAddSettingsButton(){ var navuser = document.querySelector(".nav-user.active"); if(navuser){ addSettings(); var overlay = document.getElementById("overlay"); overlay.addEventListener("click", hideSettingsOut); var dropdown = document.body.querySelector(".dropdown-content"); var link = document.createElement("a"); link.setAttribute("href", "javascript:;"); link.innerHTML = "WES 👨🌾"; link.addEventListener("click", displaySettings); dropdown.insertBefore(link, dropdown.lastElementChild); } } /************************ 2. Main Page Enhancers ************************/ /************************ 2.1. Create tools bar ************************/ function mainPageEnhancerAddToolBar(){ var container = document.querySelector(".container"); var wrapperHome = document.querySelector(".wrapper.home"); if(wrapperHome && container){ var tools_bar = document.createElement('div'); tools_bar.className = "top-bar" tools_bar.style.height = "30px"; tools_bar.style.backgroundColor = "black"; tools_bar.style.width = "auto"; tools_bar.style.opacity = 0.5; tools_bar.style.display = "flex"; tools_bar.style.alignItems = "center"; tools_bar.style.justifyContent = "center" var toolslist = document.createElement('ul'); toolslist.style.listStyle = "none"; var newli = document.createElement('li'); newli.style.display = "inline"; newli.style.color = "white"; var newlink = document.createElement('a'); newlink.href = "#"; newlink.innerHTML = "expand content"; newlink.className = "tool-bar-link"; newlink.padding = "10px"; newlink.id = "expand-media"; newli.appendChild(newlink); toolslist.appendChild(newli); tools_bar.appendChild(toolslist); wrapperHome.insertBefore(tools_bar, container); /************************ 2.1.1 expand media ************************/ var expandMediaButton = document.getElementById('expand-media'); expandMediaButton.onclick = function(){ var thu = document.getElementsByClassName("thumb"); var len = thu.length; for(var i = 0; i < len /*- 1*/ ; i++){ wes.expandMedia(thu[i]); } wes.params.expandMedia = !wes.params.expandMedia; } } } /************************ 2.2 Automatically expand content ************************/ function mainPageEnhancerAutoExpandMedia(){ //if im on a main page, expand (or not) content in next pages automatically var postList = document.querySelector(".post-list");//maybe find another way of checking if im on a main page if(postList){ const plmoConfig = { attributes: false, childList: true, subtree: false }; const plmoCallback = function(mutationsList, observer) { if(wes.params.expandMedia){ for(let mutation of mutationsList){ for(let node of mutation.addedNodes){ var media = node.querySelector(".thumb"); wes.expandMedia(media); } } } } const postListObserver = new MutationObserver(plmoCallback); postListObserver.observe(postList, plmoConfig); } } /*************** 2.3 Add Tag Buttons on Infinite Scroll ****************/ function mainPageEnhancerAddTagButtons(){ //if im on a main page, expand (or not) content in next pages automatically var postList = document.querySelector(".post-list");//maybe find another way of checking if im on a main page if(postList){ const plmoConfig = { attributes: false, childList: true, subtree: false }; const plmoCallback = function(mutationsList, observer) { for(let mutation of mutationsList){ for(let node of mutation.addedNodes){ var author = node.querySelector(".author"); //refactor this some day var user = author.innerText.trim(); if(tags[user]){ var tag = createTag(); tag.id = ""; tag.style.color = tags[user].color; tag.style.backgroundColor = tags[user].backgroundColor; tag.textContent = tags[user].text; author.parentElement.insertBefore(tag, author.nextSibling); tag.addEventListener("click", function(){userTaggerShowForm(this)}); } else { var tagbutton = createTagButton(); author.appendChild(tagbutton); tagbutton.querySelector("button").addEventListener("click", function(){userTaggerShowForm(this)}); author.addEventListener("mouseover", function(){ try{this.querySelector(".tag-button-container").style.display = "inline";}catch(error){}}); author.addEventListener("mouseout", function(){ try{this.querySelector(".tag-button-container").style.display = "none";}catch(error){}}); } } } } const postListObserver = new MutationObserver(plmoCallback); postListObserver.observe(postList, plmoConfig); } } /************************ 3. Comments Enhancers ************************/ /************************ 3.1. Automatic Quotes ************************/ //return True if a mutated object exists, its class is _className and its mutation type is _mutationType function objMutated(m, _className, _mutationType){ return m.target.className && (!m.target.className.toString().localeCompare(_className)) && m.type === _mutationType; } function isMessage(m){ return (!m.target.parentElement.className.toString().localeCompare("message")) || (!m.target.parentElement.parentElement.className.toString().localeCompare("message")); } function getSelectionText() { var text = ""; if (window.getSelection) { text = window.getSelection().toString(); } else if (document.selection && document.selection.type != "Control") { text = document.selection.createRange().text; } text = text.split("\r\n"); while(text.indexOf("") > -1){ text.splice(text.indexOf(""), 1); } return text; } function commentsEnhancerAddAutomaticQuotes(){ //save selected text before replying var selectedText = ""; document.body.onmouseup = function(){ selectedText = getSelectionText(); } //make a MutationObserver for comments const moConfig = { attributes: true, childList: true, subtree: true }; const moCallback = function(mutationsList, observer) { for(let mutation of mutationsList){ //add expandos when editing a comment if(objMutated(mutation, "content", "childList")){ if(!mutation.target.querySelector(".inline-expand-content-button")){ singleCommentExpandMedia(mutation.target); } } //add expandos when replying to a post or comment if(objMutated(mutation, "comment", "childList")){ var child = mutation.addedNodes[0]; try{ if(!child.querySelector(".inline-expand-content-button")){ singleCommentExpandMedia(child.querySelector(".content")); } }catch (error) {console.log(error)} } //autoquotes var commentLines = ""; var textarea = ""; var replyFormAdded = objMutated(mutation, "body", "childList"); var replyFormShown = objMutated(mutation, "form reply active", "attributes"); //if its the first time the reply button was clicked: if(replyFormAdded){ if(isMessage(mutation)){ commentLines = mutation.target.querySelector('.content').children; } else { commentLines = mutation.target.querySelector('.rendered').children;} } //if im expanding the reply form if(replyFormShown){ if(isMessage(mutation)){ commentLines = mutation.target.parentElement.querySelector('.content').children; } else { commentLines = mutation.target.parentElement.querySelector('.rendered').children;} } if(replyFormAdded || replyFormShown){ textarea = mutation.target.querySelector("textarea"); for(let line of selectedText){ for(let commentLine of commentLines){ if(commentLine.innerText.includes(line)){ textarea.value += "> " + line + "\n\n"; } } } //keep this functionality in the 'reply' button for as long as the comment box is being displayed mutation.target.parentElement.querySelector('a[data-action="reply"]').onclick = function(){ var selectedTextReplyOnClick = getSelectionText(); var textareaReplyOnClick = this.parentElement.parentElement.querySelector("textarea"); var commentLinesReplyOnClick = ""; if(isMessage(mutation)){ commentLinesReplyOnClick = this.parentElement.parentElement.querySelector('.content').children; } else{ commentLinesReplyOnClick = this.parentElement.parentElement.querySelector('.rendered').children; } try { for(let line of selectedTextReplyOnClick){ for(let commentLine of commentLinesReplyOnClick){ if(commentLine.innerText.includes(line)){ textareaReplyOnClick.value += "> " + line + "\n\n"; } } } } catch (error){ console.log(error); } } } //if im hitting cancel, reset the textbox if(objMutated(mutation, "form reply", "attributes")){ textarea = mutation.target.querySelector("textarea"); textarea.value = ""; mutation.target.parentElement.querySelector('a[data-action="reply"]').onclick = ""; } } }; const commentsObserver = new MutationObserver(moCallback); var comments = document.getElementsByClassName("comment"); for (var j = 0; j < comments.length; j++) { comments[j].onmousedown = function(){ commentsObserver.observe(this, moConfig); } } const messagesObserver = new MutationObserver(moCallback); //TODO: Use a different config and callback. var messagesToObserve = document.getElementsByClassName("message"); console.log(messagesToObserve); for (var k = 0; k < messagesToObserve.length; k++){ messagesToObserve[k].onmousedown = function(){ messagesObserver.observe(this, moConfig); } } /* expando related code, move somewhere else*/ /*make a mutations observer for the comment list*/ const moConfig_cl = { attributes: true, childList: true, subtree: true }; const moCallback_cl = function(mutationsList, observer) { for(let mutation of mutationsList){ var childListMutation = mutation.target.className && (!mutation.target.className.toString().localeCompare("comment-list")) && mutation.type === 'childList'; if (childListMutation){ var addedNodes = mutation.addedNodes; if(!addedNodes[0].className.toString().localeCompare("comment")){ singleCommentExpandMedia(addedNodes[0].querySelector(".content")); } } } } const commentListObserver = new MutationObserver(moCallback_cl); var commentList = document.body.querySelector(".comment-list"); commentListObserver.observe(commentList, moConfig_cl); } /************************ 3.2. Expand Content in Comments ************************/ var mediaLinkDictionary = {}; /* type checks*/ function isExpandable(link){ return isImage(link.href) || isVideoFile(link.href) || isTweet(link.href) || isYoutubeLink(link.href) || isImgurAlbum(link.href) || isImgurGallery(link.href) || isStreamable(link.href) || isBitchute(link.href) || isBannedVideo(link.href) || isMAGAVideo(link.href) || isLBRYVideo(link.href) || isOdyseeVideo(link.href); } function isImage(url){ var imageExtensions = [".jpg",".jpeg",".png",".gif",".webp"]; var length = imageExtensions.length; for(var i = 0; i < length; i++){ if(url.includes(imageExtensions[i])){ return true; } } return false; } function isVideoFile(url){ var videoExtensions = [".mp4",".webm"]; var length = videoExtensions.length; for(var i = 0; i < length; i++){ if(url.includes(videoExtensions[i])){ return true; } } return false; } function isTweet(url){ return !url.search("(https:\/\/twitter.com\/.*?\/(status)\/)"); } function isYoutubeLink(url){ var ytregexp = /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/\s]{11})/gi; return url.search(ytregexp) >= 0; } function isImgurAlbum(url){ var imgurAlbumRegExp = /imgur.com\/a\/.{0,20}/; return url.search(imgurAlbumRegExp) >= 0; } function isImgurGallery(url){ var imgurGalleryRegExp = /imgur.com\/gallery\/.{0,20}/; return url.search(imgurGalleryRegExp) >= 0; } function isStreamable(url){ var streamableRegex = /https:\/\/streamable\.com\/.*/; return url.search(streamableRegex) >= 0; } function isBitchute(url){ var bitchuteRegex = /https:\/\/(www.)*bitchute\.com\/video\/.*/; return url.search(bitchuteRegex) >= 0; } function isBannedVideo(url){ var bannedVideoRegex = /https:\/\/banned\.video\/watch\?.*/; return url.search(bannedVideoRegex) >= 0; } function isMAGAVideo(url){ var MAGAVideoRegex = /https:\/\/video\.maga\.host\/videos\/watch\/.*/; return url.search(MAGAVideoRegex) >= 0; } function isLBRYVideo(url){ var LBRYVideoRegex = /https:\/\/lbry\.tv\/@.*\:.*\/.*/; return url.search(LBRYVideoRegex) >= 0; } function isOdyseeVideo(url){ var OdyseeVideoRegex = /https:\/\/odysee\.com\/@.*\:.*\/.*/; return url.search(OdyseeVideoRegex) >= 0; } function getYoutubeId(url){ var ID = ''; url = url.replace(/(>|<)/gi,'').split(/(vi\/|v=|\/v\/|youtu\.be\/|\/embed\/)/); if(url[2] !== undefined) { ID = url[2].split(/[^0-9a-z_\-]/i); ID = ID[0]; } else { ID = url; } return ID; } /* imgur */ function alterImgurAlbumInterface(imgurAlbumMain, albumData) { console.log(albumData); if(albumData.data.title){imgurAlbumMain.querySelector(".expando-imgur-album-title").innerHTML = '\"' + albumData.data.title + '\"';} imgurAlbumMain.querySelector(".expando-imgur-album-size").innerHTML = albumData.data.images_count; imgurAlbumMain.querySelector(".expando-imgur-album-image-number").innerHTML = 1; var imgurAlbumImageLinks = []; for(var media of albumData.data.images){ imgurAlbumImageLinks.push(media.link); } var imgurAlbumContent = imgurAlbumMain.querySelector(".expando-imgur-album-content"); if(isImage(imgurAlbumImageLinks[0])){ imgurAlbumContent.appendChild(createImageElement(imgurAlbumImageLinks[0])); } else if(isVideoFile(imgurAlbumImageLinks[0])){ imgurAlbumContent.appendChild(createVideoElement(imgurAlbumImageLinks[0])); } var index = 0; var buttons = imgurAlbumMain.querySelectorAll("button"); buttons[0].onclick = function(){ if(index > 0){ var link = imgurAlbumImageLinks[--index]; } else{ index = imgurAlbumImageLinks.length-1; link = imgurAlbumImageLinks[index]; this.innerHTML = "Previous"; buttons[1].innerHTML = "First"; } if(index < imgurAlbumImageLinks.length-1){buttons[1].innerHTML = "Next";} var media = undefined; if(isImage(link)){media = createImageElement(link);} else if(isVideoFile(link)){media = createVideoElement(link);} imgurAlbumMain.querySelector(".expando-imgur-album-image-number").innerHTML = index + 1; imgurAlbumContent.removeChild(imgurAlbumContent.firstElementChild); imgurAlbumMain.querySelector(".expando-imgur-album-content").appendChild(media); if(index == 0){ this.innerHTML = "Last"; } } buttons[1].onclick = function(){ if(index < imgurAlbumImageLinks.length-1){ var link = imgurAlbumImageLinks[++index]; } else{ index = 0; link = imgurAlbumImageLinks[index]; this.innerHTML = "Next"; buttons[0].innerHTML = "Last"; } if(index > 0){buttons[0].innerHTML = "Previous";} var media = undefined; if(isImage(link)){media = createImageElement(link);} else if(isVideoFile(link)){media = createVideoElement(link);} imgurAlbumMain.querySelector(".expando-imgur-album-image-number").innerHTML = index + 1; imgurAlbumContent.removeChild(imgurAlbumContent.firstElementChild); imgurAlbumMain.querySelector(".expando-imgur-album-content").appendChild(media); if(index == imgurAlbumImageLinks.length-1){ this.innerHTML = "First"; } } } function expandoImgurAlbumInterfaceCss(){ var imgurAlbumInterfaceCss = document.createElement("style"); imgurAlbumInterfaceCss.innerHTML = ".expandoNavigationBtn { display: inline-block; text-align: center; text-decoration: none; margin: 1px 0; border: solid 1px transparent; border-radius: 4px; padding: 0.2em 0.2em; color: #ffffff; background-color: black;}.expandoNavigationBtn:active { transform: translateY(1px); filter: saturate(150%);}.expandoNavigationBtn:hover { color: black; border-color: currentColor; background-color: white;}.expandoNavigationBtn:focus { outline: none;}.expandoNavigationBtn { outline: none;}.expandoNavigationBtn::-moz-focus-inner { border: none;}"; document.body.appendChild(imgurAlbumInterfaceCss); } function expandoImgurAlbumCreateImage(url){ var img = document.createElement("img"); img.src = url; img.style.maxWidth = "1000px"; return img; } function createImgurAlbumInterface(){ var baseName = "expando-imgur-album"; var expandoImgurAlbumMain = document.createElement("div"); expandoImgurAlbumMain.id = "expando-imgur-album-main"; var expandoImgurAlbumControls = document.createElement("div"); var expandoImgurAlbumTitle = document.createElement("div"); expandoImgurAlbumTitle.className = "expando-imgur-album-title"; var expandoImgurAlbumSize = document.createElement("div"); var expandoImgurInlineAlbumSize = document.createElement("span"); expandoImgurInlineAlbumSize.className = baseName + "-size"; var expandoImgurInlineAlbumImageNumber = document.createElement("span"); expandoImgurInlineAlbumImageNumber.className = baseName + "-image-number"; var expandoImgurAlbumContent = document.createElement("div"); expandoImgurAlbumContent.className = "expando-imgur-album-content"; var expandoImgurPreviousButton = document.createElement("button"); expandoImgurPreviousButton.innerHTML = "Last"; expandoImgurPreviousButton.className = "expandoNavigationBtn"; var expandoImgurNextButton = document.createElement("button"); expandoImgurNextButton.innerHTML = "Next"; expandoImgurNextButton.className = "expandoNavigationBtn"; //expandoImgurAlbumSize.appendChild(document.createTextNode("Showing ")); expandoImgurAlbumSize.appendChild(expandoImgurInlineAlbumImageNumber); expandoImgurAlbumSize.appendChild(document.createTextNode(" of ")); expandoImgurAlbumSize.appendChild(expandoImgurInlineAlbumSize); expandoImgurAlbumControls.appendChild(expandoImgurPreviousButton); expandoImgurAlbumControls.appendChild(expandoImgurNextButton); expandoImgurAlbumMain.appendChild(expandoImgurAlbumTitle); expandoImgurAlbumMain.appendChild(expandoImgurAlbumSize); expandoImgurAlbumMain.appendChild(expandoImgurAlbumControls); expandoImgurAlbumMain.appendChild(expandoImgurAlbumContent); return expandoImgurAlbumMain; } /* create media */ function createImageElement(src){ var media = document.createElement("img"); media.src = src; return media; } function createVideoElement(src){ var media = document.createElement("video"); media.src = src; var extlength = media.src.length - media.src.lastIndexOf(".") - 1; var type = media.src.slice(-extlength); media.setAttribute("type", "video/" + type); media.setAttribute("controls",""); return media; } function createTweetElement(src){ var tweetlink = document.createElement("a"); tweetlink.href = src; var media = document.createElement("blockquote"); media.className = "twitter-tweet"; media.appendChild(tweetlink); return media; } function createNullElement(src){ return null; } /* finishers */ function twitterWidget(src, div){ var scr = document.createElement("script"); scr.id = "tweet-script"; scr.charset = "utf-8"; scr.src= "https://platform.twitter.com/widgets.js"; scr.async = true; document.body.appendChild(scr); } function youtubeWidget(src, div){ var videoId = getYoutubeId(src); if(src.includes("t=")){ var split = src.split("="); var startTime = split[split.length-1].split("s")[0]; videoId += "?start=" + startTime; } var obj = {"video": {"value": "<iframe title='YouTube video player' type=\"text/html\" width='640' height='390' src='https://www.youtube.com/embed/" + videoId + "' frameborder='0' allowFullScreen></iframe>"}}; $("#"+div.id).html(obj.video.value); } function imgurAlbumGalleryFinisher(src, div){ var album = mediaLinkDictionary[src]; if(album.data.images_count > 2){ expandoImgurAlbumInterfaceCss(); alterImgurAlbumInterface(div, album); } } function streamableWidget(src, div){ var split = src.split("/"); var videoid = split[split.length-1]; var obj = {"video": {"value": "<div style='width: 100%; height: 0px; position: relative; padding-bottom: 56.25%;'><iframe class='streamable-embed' src='https://streamable.com/o/" + videoid + "' frameborder='0' scrolling='no' style='width: 100%; height: 100%; position: absolute;' allowfullscreen></iframe></div>"}}; $("#"+div.id).html(obj.video.value); } function bitchuteWidget(src, div){ var split = src.split("/"); var videoid = ""; var last = split[split.length-1]; if(last.length > 0) {videoid = last} else {videoid = split[split.length-2];} var obj = {"video": {"value": "<iframe title='Bitchute video player' type=\"text/html\" width='640' height='390' src='https://www.bitchute.com/embed/" + videoid + "' frameborder='0' allowFullScreen></iframe>"}}; $("#"+div.id).html(obj.video.value); } function bannedVideoWidget(src, div){ var split = src.split("="); var videoid = split[split.length-1]; var obj = {"video": {"value": "<iframe title='Infowars video player' type=\"text/html\" width='640' height='390' src='https://api.banned.video/embed/" + videoid + "' frameborder='0' allowFullScreen></iframe>"}}; $("#"+div.id).html(obj.video.value); } function MAGAVideoWidget(src, div){ var split = src.split("/"); var videoid = split[split.length-1]; var obj = {"video": {"value": "<iframe width='560' height='315' sandbox='allow-same-origin allow-scripts allow-popups' src='https://video.maga.host/videos/embed/" + videoid + "' frameborder='0' allowfullscreen></iframe>"}}; $("#"+div.id).html(obj.video.value); } function LBRYVideoWidget(src, div){ var split = src.split("/"); var videoid = split[split.length-1]; var obj = {"video": {"value": "<iframe id='lbry-iframe' width='560' height='315' src='https://lbry.tv/$/embed/" + videoid + "' allowfullscreen></iframe>"}}; $("#"+div.id).html(obj.video.value); } function OdyseeVideoWidget(src, div){ var split = src.split("/"); var videoid = split[split.length-1]; var obj = {"video": {"value": "<iframe id='lbry-iframe' width='560' height='315' src='https://odysee.com/$/embed/" + videoid + "' allowfullscreen></iframe>"}}; $("#"+div.id).html(obj.video.value); } function noop (){} function expandMedia(node){ var div = document.createElement("div"); div.style = "resize: both"; div.id = "id" + Math.random().toString(16).slice(2); node.setAttribute("data-media-id", div.id); var mediaSource = node.getAttribute("data-media-source"); var mediaType = node.getAttribute("data-media-type"); var media = expandos[mediaType].createMedia(mediaSource); /*fix this some day*/ if(!mediaType.localeCompare("imgurAlbum") || !mediaType.localeCompare("imgurGallery")){ var albumHash = mediaSource.split("/"); albumHash = albumHash[albumHash.length-1]; var apiUrl = "https://api.imgur.com/3/album/"; var albumData = mediaLinkDictionary[mediaSource]; if(!mediaType.localeCompare("imgurGallery")){apiUrl = "https://api.imgur.com/3/gallery/album/";} if(albumData === undefined){ GM_xmlhttpRequest ( { method: "GET", url: apiUrl + albumHash, headers: { "Authorization": "Client-ID 1d8d9b36339e0e2" }, onload: function (response) { if(response.status === 404){ media = document.createTextNode("404: not found"); if(media){div.appendChild(media);} node.setAttribute("data-media-id", div.id); node.parentElement.insertBefore(div, node.nextSibling); return; } console.log (response.responseText); var reqAlbumData = JSON.parse(response.responseText); mediaLinkDictionary[mediaSource] = reqAlbumData; if(reqAlbumData.data.images_count > 2){ media = createImgurAlbumInterface(); } else{ var singleMedia = reqAlbumData.data.images[0].link; if(isVideoFile(singleMedia)){ media = createVideoElement(singleMedia); } else if(isImage(singleMedia)){ media = createImageElement(singleMedia); } } if(media){div.appendChild(media);} node.setAttribute("data-media-id", div.id); node.parentElement.insertBefore(div, node.nextSibling); if(reqAlbumData.data.images_count > 2){ expandoImgurAlbumInterfaceCss(); alterImgurAlbumInterface(div, reqAlbumData); } } } ); return; } if(albumData.data.images_count > 2){ media = createImgurAlbumInterface(); } else{ var singleMedia = albumData.data.images[0].link; if(isVideoFile(singleMedia)){ media = createVideoElement(singleMedia); } else if(isImage(singleMedia)){ media = createImageElement(singleMedia); } } } if(media){div.appendChild(media);} node.setAttribute("data-media-id", div.id); node.parentElement.insertBefore(div, node.nextSibling); expandos[mediaType].finisher(mediaSource, div); } function contractMedia(node){ var id = node.getAttribute("data-media-id"); var media = document.getElementById(id); node.parentElement.removeChild(media); node.removeAttribute("data-media-id"); } var expandos = { image: { svgwidth: "1.1em", svgheight: "1.1em", svgviewBox: "0 -3 35 35", svgpath: "M10 4H4a2 2 0 0 0-2 2v24a2 2 0 0 0 2 2h28a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2zM8.92 8a3 3 0 1 1-3 3a3 3 0 0 1 3-3zM6 27v-4.1l6-6.08a1 1 0 0 1 1.41 0L16 19.35L8.32 27zm24 0H11.15l6.23-6.23l5.4-5.4a1 1 0 0 1 1.41 0L30 21.18z", createMedia: createImageElement, finisher: noop, }, video: { svgwidth: "1.2em", svgheight: "1.2em", svgviewBox: "0 -3 20 20", svgpath: "M19 15V5c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h13c1.1 0 2-.9 2-2zM8 14V6l6 4z", createMedia: createVideoElement, finisher: noop, }, tweet: { svgwidth: "1.2em", svgheight: "1.2em", svgviewBox: "0 -3 60 60", svgpath: "M60 16l-6 1l4-5l-7 2c-9-10-23 1-19 10C16 24 8 12 8 12s-6 9 4 16l-6-2c0 6 4 10 11 12h-7c4 8 11 8 11 8s-6 5-17 5c33 16 53-14 50-30z", createMedia: createTweetElement, finisher: twitterWidget, }, youtubeVideo: { svgwidth: "1.2em", svgheight: "1.2em", svgviewBox: "0 -3 20 20", svgpath: "M19 15V5c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h13c1.1 0 2-.9 2-2zM8 14V6l6 4z", createMedia: createNullElement, finisher: youtubeWidget, }, imgurAlbum: { svgwidth: "1.1em", svgheight: "1.1em", svgviewBox: "0 -3 35 35", svgpath: "M10 4H4a2 2 0 0 0-2 2v24a2 2 0 0 0 2 2h28a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2zM8.92 8a3 3 0 1 1-3 3a3 3 0 0 1 3-3zM6 27v-4.1l6-6.08a1 1 0 0 1 1.41 0L16 19.35L8.32 27zm24 0H11.15l6.23-6.23l5.4-5.4a1 1 0 0 1 1.41 0L30 21.18z", createMedia: createNullElement, finisher: imgurAlbumGalleryFinisher, }, imgurGallery: { svgwidth: "1.1em", svgheight: "1.1em", svgviewBox: "0 -3 35 35", svgpath: "M10 4H4a2 2 0 0 0-2 2v24a2 2 0 0 0 2 2h28a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2zM8.92 8a3 3 0 1 1-3 3a3 3 0 0 1 3-3zM6 27v-4.1l6-6.08a1 1 0 0 1 1.41 0L16 19.35L8.32 27zm24 0H11.15l6.23-6.23l5.4-5.4a1 1 0 0 1 1.41 0L30 21.18z", createMedia: createNullElement, finisher: imgurAlbumGalleryFinisher, }, streamable: { svgwidth: "1.2em", svgheight: "1.2em", svgviewBox: "0 -3 20 20", svgpath: "M19 15V5c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h13c1.1 0 2-.9 2-2zM8 14V6l6 4z", createMedia: createNullElement, finisher: streamableWidget, }, bitchute: { svgwidth: "1.2em", svgheight: "1.2em", svgviewBox: "0 -3 20 20", svgpath: "M19 15V5c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h13c1.1 0 2-.9 2-2zM8 14V6l6 4z", createMedia: createNullElement, finisher: bitchuteWidget, }, bannedVideo: { svgwidth: "1.2em", svgheight: "1.2em", svgviewBox: "0 -3 20 20", svgpath: "M19 15V5c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h13c1.1 0 2-.9 2-2zM8 14V6l6 4z", createMedia: createNullElement, finisher: bannedVideoWidget, }, MAGAVideo: { svgwidth: "1.2em", svgheight: "1.2em", svgviewBox: "0 -3 20 20", svgpath: "M19 15V5c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h13c1.1 0 2-.9 2-2zM8 14V6l6 4z", createMedia: createNullElement, finisher: MAGAVideoWidget, }, LBRYVideo: { svgwidth: "1.2em", svgheight: "1.2em", svgviewBox: "0 -3 20 20", svgpath: "M19 15V5c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h13c1.1 0 2-.9 2-2zM8 14V6l6 4z", createMedia: createNullElement, finisher: LBRYVideoWidget, }, OdyseeVideo: { svgwidth: "1.2em", svgheight: "1.2em", svgviewBox: "0 -3 20 20", svgpath: "M19 15V5c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h13c1.1 0 2-.9 2-2zM8 14V6l6 4z", createMedia: createNullElement, finisher: OdyseeVideoWidget, } } function getMediaType(url){ if(isImage(url)){return "image";} else if (isVideoFile(url)){return "video";} else if (isTweet(url)){return "tweet";} else if (isYoutubeLink(url)){return "youtubeVideo";} else if (isImgurAlbum(url)){return "imgurAlbum";} else if (isImgurGallery(url)){return "imgurGallery";} else if (isStreamable(url)){return "streamable";} else if (isBitchute(url)){return "bitchute";} else if (isBannedVideo(url)){return "bannedVideo";} else if (isMAGAVideo(url)){return "MAGAVideo";} else if (isLBRYVideo(url)){return "LBRYVideo";} else if (isOdyseeVideo(url)){return "OdyseeVideo";} return "notMedia"; } function createExpandoButton(url){ var type = getMediaType(url); if (!type.localeCompare("notMedia")){return}; var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svg.setAttributeNS(null, "aria-hidden", true); svg.setAttributeNS(null, "focusable", false); svg.setAttributeNS(null, "preserveAspectRatio", "xMidYMid meet"); svg.setAttributeNS(null, "class", "inline-expand-content-button"); svg.setAttributeNS(null, "width", expandos[type].svgwidth); svg.setAttributeNS(null, "height", expandos[type].svgheight); svg.setAttributeNS(null, "viewBox", expandos[type].svgviewBox); svg.style = "-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg); padding-left: 3px; cursor: pointer"; var path = document.createElementNS("http://www.w3.org/2000/svg", "path"); path.setAttributeNS(null, "fill","currentColor"); path.setAttributeNS(null, "d",expandos[type].svgpath); var label = document.createElement("label"); label.className = "expando-checkbox-label"; var checkbox = document.createElement("input"); checkbox.type = "checkbox"; var container = document.createElement("div"); container.className = "expando-checkbox-container"; container.setAttribute("data-media-type", type); container.setAttribute("data-media-source", url); svg.appendChild(path); label.appendChild(svg); label.appendChild(checkbox); container.appendChild(label); checkbox.addEventListener( 'change', function() { if(this.checked) { this.parentElement.querySelector("path").style.fill = "#e7c6ac"; expandMedia(this.parentElement.parentElement); } else { this.parentElement.querySelector("path").style.fill = "currentColor"; contractMedia(this.parentElement.parentElement); } }); return container; } function singleCommentExpandMedia(content){ var links = content.querySelectorAll("a"); for(var link of links){ if(isExpandable(link)){ link.parentElement.insertBefore(createExpandoButton(link.href), link.nextSibling); } } var style = document.createElement("style"); style.innerHTML = ".expando-checkbox-container{display: inline-block}.expando-checkbox-label { display: block; position: relative; padding-left: 0px; margin-bottom: 0px; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;}.expando-checkbox-label input { position: absolute; opacity: 0; cursor: pointer; height: 0; width: 0;}.expando-checkbox-label:hover input { background-color: #ccc;}.expando-checkbox-label input:checked { display: block;}"; document.body.appendChild(style); } function commentsEnhancerExpandMedia(){ var posts = document.getElementsByClassName("content"); for(var post of posts){ var links = post.querySelectorAll("a"); for(var link of links){ if(isExpandable(link)){ link.parentElement.insertBefore(createExpandoButton(link.href), link.nextSibling); } } } var style = document.createElement("style"); style.innerHTML = ".expando-checkbox-container{display: inline-block}.expando-checkbox-label { display: block; position: relative; padding-left: 0px; margin-bottom: 0px; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;}.expando-checkbox-label input { position: absolute; opacity: 0; cursor: pointer; height: 0; width: 0;}.expando-checkbox-label:hover input { background-color: #ccc;}.expando-checkbox-label input:checked { display: block;}"; document.body.appendChild(style); } /************************ MAIN ************************/ generalEnhancerAddNavigationBar(); generalEnhancerAddPointRedirection(); generalEnhancerAddSettingsButton(); mainPageEnhancerAddToolBar(); mainPageEnhancerAutoExpandMedia(); mainPageEnhancerAddTagButtons(); //if im viewing a post: if(document.location.href.search("/p/") > 0){ commentsEnhancerAddAutomaticQuotes(); commentsEnhancerExpandMedia(); } var userPostsOrCommentsRegex = /\/u\/.*\/\?type=(\bpost\b|\bcomment\b)/; var messagesPageRegex = /\/messages/; var userPageRegex = /\/u\/.*/; if(document.location.href.search(userPageRegex) > 0) { commentsEnhancerExpandMedia(); } if (document.location.href.search(messagesPageRegex) > 0){ commentsEnhancerAddAutomaticQuotes(); } /************************ 7. Update notification ************************/ //Thank you: https://codepen.io/takaneichinose/pen/eZoZxv class MessageBox { constructor(id, option) { this.id = id; this.option = option; } show(msg, label = "Close", callback = null) { if (this.id === null || typeof this.id === "undefined") { // if the ID is not set or if the ID is undefined throw "Please set the 'ID' of the message box container."; } if (msg === "" || typeof msg === "undefined" || msg === null) { // If the 'msg' parameter is not set, throw an error throw "The 'msg' parameter is empty."; } if (typeof label === "undefined" || label === null) { // Of the label is undefined, or if it is null label = "Close"; } let option = this.option; let msgboxArea = document.querySelector(this.id); let msgboxBox = document.createElement("DIV"); let msgboxContent = document.createElement("DIV"); let msgboxClose = document.createElement("A"); if (msgboxArea === null) { // If there is no Message Box container found. throw "The Message Box container is not found."; } // Content area of the message box msgboxContent.classList.add("msgbox-content"); msgboxContent.innerHTML = msg; // Close button of the message box msgboxClose.classList.add("msgbox-close"); msgboxClose.setAttribute("href", "#"); msgboxClose.innerText = label; // Container of the Message Box element msgboxBox.classList.add("msgbox-box"); msgboxBox.appendChild(msgboxContent); if (option.hideCloseButton === false || typeof option.hideCloseButton === "undefined") { // If the hideCloseButton flag is false, or if it is undefined // Append the close button to the container msgboxBox.appendChild(msgboxClose); } msgboxArea.appendChild(msgboxBox); msgboxClose.addEventListener("click", (evt) => { evt.preventDefault(); if (msgboxBox.classList.contains("msgbox-box-hide")) { // If the message box already have 'msgbox-box-hide' class // This is to avoid the appearance of exception if the close // button is clicked multiple times or clicked while hiding. return; } this.hide(msgboxBox, callback); }); if (option.closeTime > 0) { this.msgboxTimeout = setTimeout(() => { this.hide(msgboxBox, callback); }, option.closeTime); } } hide(msgboxBox, callback) { if (msgboxBox !== null) { // If the Message Box is not yet closed msgboxBox.classList.add("msgbox-box-hide"); } msgboxBox.addEventListener("transitionend", () => { if (msgboxBox !== null) { // If the Message Box is not yet closed msgboxBox.parentNode.removeChild(msgboxBox); clearTimeout(this.msgboxTimeout); if (callback !== null) { // If the callback parameter is not null callback(); } } }); } } // Creation of Message Box class, and the sample usage let msgboxbox = new MessageBox("#msgbox-area", { closeTime: 7000, hideCloseButton: false }); var version = GM.getValue("wes_version"); version.then(function(result) { var compareVersions = GM.info.script.version.localeCompare(result); if(compareVersions){ var notificationCss = '.msgbox-area { max-height: 100%; position: fixed; bottom: 15px; left: 20px; right: 20px;}.msgbox-area .msgbox-box { font-size: inherit; color: #ffffff; background-color: rgba(0, 0, 0, 0.8); padding: 18px 20px; margin: 0 0 15px; display: flex; align-items: center; position: relative; justify-content: space-between; border-radius: 12px; box-shadow: 0 10px 15px rgba(0, 0, 0, 0.65); transition: opacity 300ms ease-in;}.msgbox-area .msgbox-box.msgbox-box-hide { opacity: 0;}.msgbox-area .msgbox-box:last-child { margin: 0;}.msgbox-area .msgbox-content { flex-shrink: 1;}.msgbox-area .msgbox-close { color: #ffffff; font-weight: bold; text-decoration: none; margin: 0 0 0 20px; flex-grow: 0; flex-shrink: 0; position: relative; transition: text-shadow 225ms ease-out;}.msgbox-area .msgbox-close:hover { text-shadow: 0 0 3px #efefef;}@media (min-width: 481px) and (max-width: 767px) { .msgbox-area { left: 80px; right: 80px; }}@media (min-width: 768px) { .msgbox-area { width: 480px; height: 0; top: 15px; left: auto; right: 15px; }}.msgbox-area { font-size: 16px;}.msgbox-message-container { text-align: center; width: 100vw; height: 100vh; padding: 20px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; flex-direction: column;}.msgbox-message-container h1, .msgbox-message-container h3 { margin: 10px 20px;}.msgbox-message-container p { margin: 5px 20px;}.msgbox-message-button { font-size: 18px; font-weight: bold; font-family: inherit; color: white; background-color: #1476ff; width: 250px; border: solid 2px #005de0; padding: 10px 20px; cursor: pointer; outline: none; box-shadow: 0 5px #005de0; transition: background-color 100ms ease-out, box-shadow 100ms ease-out, transform 100ms ease-out;}.msgbox-message-button:hover, .msgbox-message-button:focus, .msgbox-message-button:active { background-color: #2e85ff;}.msgbox-message-button:active { background-color: #0068fa; box-shadow: 0 0 #005de0; transform: translateY(5px);} .msgbox-link { color: #007BA7; text-decoration: none;}.msgbox-link:hover { text-decoration: underline;}.msgbox-link:active { color: black;}.msgbox-link:visited { color: #007BA7;}'; var notificationStyle = document.createElement("style"); notificationStyle.id = "notification-style"; document.body.appendChild(notificationStyle); var appendedNotificationStyle = document.getElementById("notification-style"); if(appendedNotificationStyle){ appendedNotificationStyle.innerHTML = notificationCss; } var messageBoxArea = document.createElement("div"); messageBoxArea.id = "msgbox-area"; messageBoxArea.className = "msgbox-area"; document.body.appendChild(messageBoxArea); var message = "WES has been updated to <a class=\"msgbox-link\" href=\"https://github.com/ilovestaples/wes/blob/master/CHANGELOG.md\" target=\"_blank\">version " + GM.info.script.version + "</a>"; msgboxbox.show(message, null); GM.setValue("wes_version",GM.info.script.version); } }); /************************ User Tagger *******************************/ var taggerDialogStyle = document.createElement("style"); taggerDialogStyle.innerHTML = '.userTagger-dialog {display: flex;flex-direction: column;width: 350px;background-color: white;font-family: sans-serif;font-size: 12px;padding: 2px;}.userTagger-dialog-header {height: 40px;font-size: larger;display: flex;align-items: center;justify-content: space-between;font-weight: bold;background-color: ghostwhite;}.userTagger-dialog-header-container {display: flex;justify-content: space-between;width: 350px;}.userTagger-header-user-container {display: flex;justify-content: space-between;padding-left: 4px;}#userTagger-header-user-username {padding-left: 4px;max-width: 250px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;display: inline-block;}.userTagger-header-controls-container {display: flex;justify-content: space-between;}.userTagger-dialog-controls-container {border: 1px red solid;display: flex;justify-content: space-between;}.WESDialogContents{ padding: 5px;}.fieldPair {display: flex;align-items: center;padding: 4px 0px 4px 0px;}.fieldPair-label {width: 85px;}.fieldPair-text {min-width: 240px;float: left;}.wes-usertagger-footer {display: flex;justify-content: space-between;align-content: center;align-items: center;}.userTag {padding: 0 4px;border: 1px solid #c7c7c7;border-radius: 3px;font-size: .9em;max-width: 150px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;display: inline-block;vertical-align: text-bottom;line-height: normal;margin: 0px 2px 0px 2px;cursor: pointer;}'; document.body.appendChild(taggerDialogStyle); function userTaggerShowForm(obj){ var pos = cumulativeOffset(obj.parentElement); var user = obj.closest(".author"); if(!user){user = obj.parentElement.querySelector(".author");} user = user.textContent.trim(); var formMarkup = document.createElement("div"); formMarkup.innerHTML = '<div class="userTagger-dialog" style="position: absolute; top: ' +pos.top+'px; left: '+pos.left+'px; z-index:10"> <h3 class="userTagger-dialog-header"> <div class="userTagger-dialog-header-container"> <div class="userTagger-header-user-container"> <svg aria-hidden="true" focusable="false" preserveAspectRatio="xMidYMid meet" cursor="pointer" style="vertical-align: -0.275em; transform: rotate(360deg);" class="tag-button" width="1.2em" height="1.2em" viewBox="0 0 24 24"> <g transform="translate(24 0) scale(-1 1)"> <g fill="none"> <path fill="#538cc6" fill-rule="evenodd" clip-rule="evenodd" d="M2 8v8a1 1 0 0 0 1 1h13.62a1 1 0 0 0 .76-.35l3.428-4a1 1 0 0 0 0-1.3l-3.428-4a1 1 0 0 0-.76-.35H3a1 1 0 0 0-1 1zM0 8v8a3 3 0 0 0 3 3h13.62a3 3 0 0 0 2.278-1.048l3.428-4a3 3 0 0 0 0-3.904l-3.428-4A3 3 0 0 0 16.62 5H3a3 3 0 0 0-3 3z"></path> <path fill="#538cc6" fill-rule="evenodd" clip-rule="evenodd" d="M15 13a1 1 0 1 0 0-2a1 1 0 0 0 0 2zm0 2a3 3 0 1 0 0-6a3 3 0 0 0 0 6z"></path> </g> </g> </svg> <span id="userTagger-header-user-username">user</span> </div> <div class="userTagger-header-controls-container"> <span class="tag-button-container" style="padding-left: 2px;"> <label class="tag-button-label"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"> </svg> <button id="tagDialogIgnoreUser" style="display: none;"></button> </label> </span> <span class="tag-button-container" style="padding-left: 2px;"> <label class="tag-button-label" title="close"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" cursor="pointer" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"> <path d="M6 2h12a4 4 0 0 1 4 4v12a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4V6a4 4 0 0 1 4-4zm0 2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2H6zm7.414 8l2.829 2.828a1 1 0 0 1-1.415 1.415L12 13.414l-2.828 2.829a1 1 0 1 1-1.415-1.415L10.586 12L7.757 9.172a1 1 0 0 1 1.415-1.415L12 10.586l2.828-2.829a1 1 0 0 1 1.415 1.415L13.414 12z" fill="#538cc6"/> <rect x="0" y="0" width="24" height="24" fill="rgba(0, 0, 0, 0)" /> </svg> <button id="tagDialogClose" style="display: none;"></button> </label> </span> </div> </div> </h3> <div data-hover-element="1" class="WESHoverBody WESDialogContents"> <form id="userTaggerToolTip"> <div class="fieldPair"><label class="fieldPair-label" for="userTaggerText">Text</label><input class="fieldPair-text" type="text" id="userTaggerText" value=""></div> <div class="fieldPair"> <label class="fieldPair-label" for="userTaggerColor">Color</label> <select id="userTaggerColor"> <option style="color: inherit; background-color: none" value="none">none</option> <option style="color: black; background-color: aqua" value="aqua">aqua</option> <option style="color: white; background-color: black" value="black">black</option> <option style="color: white; background-color: blue" value="blue">blue</option> <option style="color: white; background-color: cornflowerblue" value="cornflowerblue">cornflowerblue</option> <option style="color: white; background-color: fuchsia" value="fuchsia">fuchsia</option> <option style="color: white; background-color: gray" value="gray">gray</option> <option style="color: white; background-color: green" value="green">green</option> <option style="color: black; background-color: lime" value="lime">lime</option> <option style="color: white; background-color: maroon" value="maroon">maroon</option> <option style="color: white; background-color: navy" value="navy">navy</option> <option style="color: white; background-color: olive" value="olive">olive</option> <option style="color: white; background-color: orange" value="orange">orange</option> <option style="color: white; background-color: orangered" value="orangered">orangered</option> <option style="color: black; background-color: pink" value="pink">pink</option> <option style="color: white; background-color: purple" value="purple">purple</option> <option style="color: white; background-color: red" value="red">red</option> <option style="color: black; background-color: silver" value="silver">silver</option> <option style="color: white; background-color: teal" value="teal">teal</option> <option style="color: black; background-color: white" value="white">white</option> <option style="color: black; background-color: yellow" value="yellow">yellow</option> </select> </div> <div class="fieldPair" style="flex-wrap: wrap"><label class="fieldPair-label" for="userTaggerPreview">Preview</label><span id="userTaggerPreview"><span class="RESUserTag"><a id="userTagPreview" class="userTag" title="set a tag" href="javascript:void 0"> </a></span></span></div> <div class="wes-usertagger-footer"><span id="view-tagged-users" style=" color:blue; cursor: pointer">View tagged users</span><input type="button" id="userTaggerSave" value="✓ save tag" formaction=""></div> </form> </div></div>'; var formJS = document.createElement("script"); formJS.innerHTML = 'var userTaggerCloseButton = document.body.querySelector("#tagDialogClose");userTaggerCloseButton.addEventListener("click", destroyDialog);var userTaggerText = document.body.querySelector("#userTaggerText");userTaggerText.addEventListener("input", updateTagPreview);var colorSelector = document.body.querySelector("#userTaggerColor");colorSelector.addEventListener("input", updateTagPreview);var saveButton = document.body.querySelector("#userTaggerSave");saveButton.addEventListener("click", saveTag);function createTag() { var tag = document.createElement("span"); tag.className = "userTag"; tag.id = "userTagPreview"; return tag;}function updateTagPreview(e) { console.log(e); if (e.target.id.localeCompare("userTaggerText") === 0) { if (e.target.textLength == 1) { var preview = document.body.querySelector("#userTaggerPreview"); var tagPreview = preview.querySelector(".userTag"); var tagPreviewNew = createTag(); var tagPreviewParent = tagPreview.parentElement; tagPreviewParent.appendChild(tagPreviewNew); tagPreviewParent.removeChild(tagPreview); tagPreviewNew.style.color = colorSelector.selectedOptions[0].style.color; tagPreviewNew.style.backgroundColor = colorSelector.selectedOptions[0].style.backgroundColor; } document.body.querySelector("#userTagPreview").textContent = e.target.value; } else if (e.target.id.localeCompare("userTaggerColor") === 0) { var preview = document.body.querySelector("#userTagPreview"); console.log(e.target.selectedOptions[0].style.color); console.log(e.target.selectedOptions[0].style.backgroundColor); console.log(preview); preview.style.color = e.target.selectedOptions[0].style.color; preview.style.backgroundColor = e.target.selectedOptions[0].style.backgroundColor; }}function saveTag(){ console.log("tag saved"); destroyDialog();}function destroyDialog(){ var dialog = document.querySelector(".userTagger-dialog"); dialog.parentElement.removeChild(dialog);}'; document.body.appendChild(formMarkup); document.getElementById("userTagger-header-user-username").innerHTML = user; if(tags[user]){ var formTagTextInput = document.getElementById("userTaggerText"); formTagTextInput.value = tags[user].text; var formTagColorSelect = document.getElementById("userTaggerColor"); formTagColorSelect.value = tags[user].backgroundColor; var preview = document.getElementById("userTagPreview"); preview.innerText = tags[user].text; preview.style.color = tags[user].color; preview.style.backgroundColor = tags[user].backgroundColor; } formjs(); } /*Tagger dialog code*/ function createTag() { var tag = document.createElement("span"); tag.className = "userTag"; tag.id = "userTagPreview"; return tag; } function updateTagPreview(e) { var colorSelector = document.body.querySelector("#userTaggerColor"); if (e.target.id.localeCompare("userTaggerText") === 0) { if (e.target.textLength == 1) { var preview = document.body.querySelector("#userTaggerPreview"); var tagPreview = preview.querySelector(".userTag"); var tagPreviewNew = createTag(); var tagPreviewParent = tagPreview.parentElement; tagPreviewParent.appendChild(tagPreviewNew); tagPreviewParent.removeChild(tagPreview); tagPreviewNew.style.color = colorSelector.selectedOptions[0].style.color; tagPreviewNew.style.backgroundColor = colorSelector.selectedOptions[0].style.backgroundColor; } document.body.querySelector("#userTagPreview").textContent = e.target.value; } else if (e.target.id.localeCompare("userTaggerColor") === 0) { var rdpreview = document.body.querySelector("#userTagPreview"); rdpreview.style.color = e.target.selectedOptions[0].style.color; rdpreview.style.backgroundColor = e.target.selectedOptions[0].style.backgroundColor; } } /*SAVE HANDLER*/ function saveTag(){ var user = document.body.querySelector("#userTagger-header-user-username").innerText.trim(); var utc = document.body.querySelector("#userTaggerColor"); var tagData = { color : utc.selectedOptions[0].style.color, backgroundColor : utc.selectedOptions[0].style.backgroundColor, text : document.body.querySelector("#userTagPreview").textContent } if(!tags[user]){ console.log("tag doesnt exist"); var authors = document.body.querySelectorAll(".author"); for(var author of authors){ if(!author.innerText.trim().localeCompare(user)){ var tbc = author.querySelector(".tag-button-container"); author.removeChild(tbc); var tag = createTag(); tag.id = ""; tag.style.color = tagData.color; tag.style.backgroundColor = tagData.backgroundColor; tag.textContent = tagData.text; author.parentElement.insertBefore(tag, author.nextSibling); tag.addEventListener("click", function(){userTaggerShowForm(this)}); } } } tags[user] = tagData; GM.setValue("tags",JSON.stringify(tags)); destroyDialog(); //if user already had a tag, refresh it var allTags = document.body.querySelectorAll(".userTag"); for(var tag of allTags){ if(!tag.previousSibling.innerText.trim().localeCompare(user)){ tag.style.color = tags[user].color; tag.style.backgroundColor = tags[user].backgroundColor; tag.innerText = tags[user].text; } } } function destroyDialog(){ var dialog = document.querySelector(".userTagger-dialog"); dialog.parentElement.removeChild(dialog); } function formjs(){ var userTaggerCloseButton = document.body.querySelector("#tagDialogClose"); userTaggerCloseButton.addEventListener("click", destroyDialog); var userTaggerText = document.body.querySelector("#userTaggerText"); userTaggerText.addEventListener("input", updateTagPreview); var colorSelector = document.body.querySelector("#userTaggerColor"); colorSelector.addEventListener("input", updateTagPreview); var viewTaggedUsers = document.getElementById("view-tagged-users"); viewTaggedUsers.addEventListener("click", viewTaggedUsers_f); /*SAVE*/ var saveButton = document.body.querySelector("#userTaggerSave"); saveButton.addEventListener("click", saveTag); } function viewTaggedUsers_f(){ displaySettings(); showTagSettings(); } /*End tagger dialog code*/ function cumulativeOffset(element) { var top = 0, left = 0; do { top += element.offsetTop || 0; left += element.offsetLeft || 0; element = element.offsetParent; } while(element); return { top: top, left: left + 15 }; }; function createTagButton(){ var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svg.setAttributeNS(null, "aria-hidden", true); svg.setAttributeNS(null, "focusable", false); svg.setAttributeNS(null, "preserveAspectRatio", "xMidYMid meet"); svg.style = "vertical-align: -0.0em;-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg); cursor: pointer; padding-left: 3px"; svg.setAttributeNS(null, "class", "tag-button"); svg.setAttributeNS(null, "width", "1.4em"); svg.setAttributeNS(null, "height", "0.9em"); svg.setAttributeNS(null, "viewBox", "5 3 16 16"); var path1 = document.createElementNS("http://www.w3.org/2000/svg", "path"); path1.setAttributeNS(null, "fill","#369"); path1.setAttributeNS(null, "fill-rule","evenodd"); path1.setAttributeNS(null, "clip-rule","evenodd"); path1.setAttributeNS(null, "d","M2 8v8a1 1 0 0 0 1 1h13.62a1 1 0 0 0 .76-.35l3.428-4a1 1 0 0 0 0-1.3l-3.428-4a1 1 0 0 0-.76-.35H3a1 1 0 0 0-1 1zM0 8v8a3 3 0 0 0 3 3h13.62a3 3 0 0 0 2.278-1.048l3.428-4a3 3 0 0 0 0-3.904l-3.428-4A3 3 0 0 0 16.62 5H3a3 3 0 0 0-3 3z"); var path2 = document.createElementNS("http://www.w3.org/2000/svg", "path"); path2.setAttributeNS(null, "fill","#369"); path2.setAttributeNS(null, "fill-rule","evenodd"); path2.setAttributeNS(null, "clip-rule","evenodd"); path2.setAttributeNS(null, "d","M15 13a1 1 0 1 0 0-2a1 1 0 0 0 0 2zm0 2a3 3 0 1 0 0-6a3 3 0 0 0 0 6z"); var g1 = document.createElementNS("http://www.w3.org/2000/svg", "g"); g1.setAttributeNS(null, "transform","translate(24 0) scale(-1 1)"); var g2 = document.createElementNS("http://www.w3.org/2000/svg", "g"); g2.setAttributeNS(null, "fill","none"); var label = document.createElement("label"); label.className = "tag-button-label"; var button = document.createElement("button"); button.style.display = "none"; var container = document.createElement("span"); container.className = "tag-button-container"; container.style.display = "none"; g2.appendChild(path1); g2.appendChild(path2); g1.appendChild(g2); svg.appendChild(g1); label.appendChild(svg); label.appendChild(button); container.appendChild(label); return container; } function loadTagsTable(){ GM.getValue("tags", "{}").then(function(val) { var userTags = JSON.parse(val); var taggedUsersTable = document.getElementById("utTable"); var thead = document.createElement("thead"); var thUser = document.createElement("th"); thUser.innerHTML = "User"; thUser.style.color = "white"; thUser.style.width = "45%"; var thTag = document.createElement("th"); thTag.innerHTML = "Tag"; thTag.style.color = "white"; thTag.style.width = "45%"; var thActions = document.createElement("th"); thActions.innerHTML = "Actions"; thActions.style.color = "white"; thead.appendChild(thUser); thead.appendChild(thTag); thead.appendChild(thActions); taggedUsersTable.appendChild(thead); for (var key in userTags) { if (userTags.hasOwnProperty(key)) { var row = taggedUsersTable.insertRow(0); var userCell = row.insertCell(-1); var userText = document.createElement("span"); userText.innerText = key.toString(); userText.style.color = "white"; userCell.appendChild(userText); var tag = createTag(); tag.id = ""; tag.style.color = userTags[key].color; tag.style.backgroundColor = userTags[key].backgroundColor; tag.textContent = userTags[key].text; tag.addEventListener("click", function(){userTaggerShowFormTable(this)}); var tagCell = row.insertCell(-1); tagCell.appendChild(tag); var deleteButton = deleteTagButton(); deleteButton.querySelector("button").addEventListener("click", function(){deleteTag(this);}); var actionsCell = row.insertCell(-1); actionsCell.appendChild(deleteButton); /*var editButton = editTagButton(); editButton.querySelector("button").addEventListener("click", function(){userTaggerShowFormTable(this)}); actionsCell.appendChild(editButton);*/ actionsCell.style = "text-align: center;"; } } }); } function unloadTagsTable(){ var table = document.getElementById("utTable"); while (table.lastElementChild) { table.removeChild(table.lastElementChild); } } function deleteTag(obj){ if(confirm("Do you wish to delete this tag?")){ var user = obj.closest("tr").querySelector("span").innerText; delete tags[user]; GM.setValue("tags",JSON.stringify(tags)); var tr = obj.closest("tr"); obj.closest("tbody").removeChild(tr); var authors = document.body.querySelectorAll(".author"); for(var author of authors){ if(!author.innerText.trim().localeCompare(user)){ var tag = author.nextSibling; var tagButton = createTagButton(); author.parentElement.removeChild(tag); author.appendChild(tagButton); tagButton.querySelector("button").addEventListener("click", function(){userTaggerShowForm(this)}); } } } } function userTaggerShowFormTable(obj){ var currentDialog = document.body.querySelector(".userTagger-dialog"); if(currentDialog){currentDialog.parentElement.removeChild(currentDialog);} var div = document.getElementById("settings-tags-sc"); var pos = cumulativeOffset(obj.closest("tr").querySelector(".userTag")); var postop = pos.top - div.scrollTop; var user = obj.closest("tr").querySelector("span").innerText; var formMarkup = document.createElement("div"); //formMarkup.innerHTML = '<div class="userTagger-dialog" style="position: absolute; inset: ' +postop+'px auto auto '+pos.left+'px;"> <h3 class="userTagger-dialog-header"> <div class="userTagger-dialog-header-container"> <div class="userTagger-header-user-container"> <svg aria-hidden="true" focusable="false" preserveAspectRatio="xMidYMid meet" cursor="pointer" style="vertical-align: -0.275em; transform: rotate(360deg);" class="tag-button" width="1.2em" height="1.2em" viewBox="0 0 24 24"> <g transform="translate(24 0) scale(-1 1)"> <g fill="none"> <path fill="#538cc6" fill-rule="evenodd" clip-rule="evenodd" d="M2 8v8a1 1 0 0 0 1 1h13.62a1 1 0 0 0 .76-.35l3.428-4a1 1 0 0 0 0-1.3l-3.428-4a1 1 0 0 0-.76-.35H3a1 1 0 0 0-1 1zM0 8v8a3 3 0 0 0 3 3h13.62a3 3 0 0 0 2.278-1.048l3.428-4a3 3 0 0 0 0-3.904l-3.428-4A3 3 0 0 0 16.62 5H3a3 3 0 0 0-3 3z"></path> <path fill="#538cc6" fill-rule="evenodd" clip-rule="evenodd" d="M15 13a1 1 0 1 0 0-2a1 1 0 0 0 0 2zm0 2a3 3 0 1 0 0-6a3 3 0 0 0 0 6z"></path> </g> </g> </svg> <span id="userTagger-header-user-username">user</span> </div> <div class="userTagger-header-controls-container"> <span class="tag-button-container" style="padding-left: 2px;"> <label class="tag-button-label"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"> </svg> <button id="tagDialogIgnoreUser" style="display: none;"></button> </label> </span> <span class="tag-button-container" style="padding-left: 2px;"> <label class="tag-button-label" title="close"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" cursor="pointer" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"> <path d="M6 2h12a4 4 0 0 1 4 4v12a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4V6a4 4 0 0 1 4-4zm0 2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2H6zm7.414 8l2.829 2.828a1 1 0 0 1-1.415 1.415L12 13.414l-2.828 2.829a1 1 0 1 1-1.415-1.415L10.586 12L7.757 9.172a1 1 0 0 1 1.415-1.415L12 10.586l2.828-2.829a1 1 0 0 1 1.415 1.415L13.414 12z" fill="#538cc6"/> <rect x="0" y="0" width="24" height="24" fill="rgba(0, 0, 0, 0)" /> </svg> <button id="tagDialogClose" style="display: none;"></button> </label> </span> </div> </div> </h3> <div data-hover-element="1" class="WESHoverBody WESDialogContents"> <form id="userTaggerToolTip"> <div class="fieldPair"><label class="fieldPair-label" for="userTaggerText">Text</label><input class="fieldPair-text" type="text" id="userTaggerText" value=""></div> <div class="fieldPair"> <label class="fieldPair-label" for="userTaggerColor">Color</label> <select id="userTaggerColor"> <option style="color: inherit; background-color: none" value="none">none</option> <option style="color: black; background-color: aqua" value="aqua">aqua</option> <option style="color: white; background-color: black" value="black">black</option> <option style="color: white; background-color: blue" value="blue">blue</option> <option style="color: white; background-color: cornflowerblue" value="cornflowerblue">cornflowerblue</option> <option style="color: white; background-color: fuchsia" value="fuchsia">fuchsia</option> <option style="color: white; background-color: gray" value="gray">gray</option> <option style="color: white; background-color: green" value="green">green</option> <option style="color: black; background-color: lime" value="lime">lime</option> <option style="color: white; background-color: maroon" value="maroon">maroon</option> <option style="color: white; background-color: navy" value="navy">navy</option> <option style="color: white; background-color: olive" value="olive">olive</option> <option style="color: white; background-color: orange" value="orange">orange</option> <option style="color: white; background-color: orangered" value="orangered">orangered</option> <option style="color: black; background-color: pink" value="pink">pink</option> <option style="color: white; background-color: purple" value="purple">purple</option> <option style="color: white; background-color: red" value="red">red</option> <option style="color: black; background-color: silver" value="silver">silver</option> <option style="color: white; background-color: teal" value="teal">teal</option> <option style="color: black; background-color: white" value="white">white</option> <option style="color: black; background-color: yellow" value="yellow">yellow</option> </select> </div> <div class="fieldPair" style="flex-wrap: wrap"><label class="fieldPair-label" for="userTaggerPreview">Preview</label><span id="userTaggerPreview"><span class="RESUserTag"><a id="userTagPreview" class="userTag" title="set a tag" href="javascript:void 0"> </a></span></span></div> <div class="wes-usertagger-footer"><input type="button" id="userTaggerSave" value="✓ save tag" formaction=""></div> </form> </div></div>'; formMarkup.innerHTML = '<div class="userTagger-dialog" style="position: absolute; top: ' +postop+'px; left: '+pos.left+'px;"> <h3 class="userTagger-dialog-header"> <div class="userTagger-dialog-header-container"> <div class="userTagger-header-user-container"> <svg aria-hidden="true" focusable="false" preserveAspectRatio="xMidYMid meet" cursor="pointer" style="vertical-align: -0.275em; transform: rotate(360deg);" class="tag-button" width="1.2em" height="1.2em" viewBox="0 0 24 24"> <g transform="translate(24 0) scale(-1 1)"> <g fill="none"> <path fill="#538cc6" fill-rule="evenodd" clip-rule="evenodd" d="M2 8v8a1 1 0 0 0 1 1h13.62a1 1 0 0 0 .76-.35l3.428-4a1 1 0 0 0 0-1.3l-3.428-4a1 1 0 0 0-.76-.35H3a1 1 0 0 0-1 1zM0 8v8a3 3 0 0 0 3 3h13.62a3 3 0 0 0 2.278-1.048l3.428-4a3 3 0 0 0 0-3.904l-3.428-4A3 3 0 0 0 16.62 5H3a3 3 0 0 0-3 3z"></path> <path fill="#538cc6" fill-rule="evenodd" clip-rule="evenodd" d="M15 13a1 1 0 1 0 0-2a1 1 0 0 0 0 2zm0 2a3 3 0 1 0 0-6a3 3 0 0 0 0 6z"></path> </g> </g> </svg> <span id="userTagger-header-user-username">user</span> </div> <div class="userTagger-header-controls-container"> <span class="tag-button-container" style="padding-left: 2px;"> <label class="tag-button-label"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"> </svg> <button id="tagDialogIgnoreUser" style="display: none;"></button> </label> </span> <span class="tag-button-container" style="padding-left: 2px;"> <label class="tag-button-label" title="close"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" cursor="pointer" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"> <path d="M6 2h12a4 4 0 0 1 4 4v12a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4V6a4 4 0 0 1 4-4zm0 2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2H6zm7.414 8l2.829 2.828a1 1 0 0 1-1.415 1.415L12 13.414l-2.828 2.829a1 1 0 1 1-1.415-1.415L10.586 12L7.757 9.172a1 1 0 0 1 1.415-1.415L12 10.586l2.828-2.829a1 1 0 0 1 1.415 1.415L13.414 12z" fill="#538cc6"/> <rect x="0" y="0" width="24" height="24" fill="rgba(0, 0, 0, 0)" /> </svg> <button id="tagDialogClose" style="display: none;"></button> </label> </span> </div> </div> </h3> <div data-hover-element="1" class="WESHoverBody WESDialogContents"> <form id="userTaggerToolTip"> <div class="fieldPair"><label class="fieldPair-label" for="userTaggerText">Text</label><input class="fieldPair-text" type="text" id="userTaggerText" value=""></div> <div class="fieldPair"> <label class="fieldPair-label" for="userTaggerColor">Color</label> <select id="userTaggerColor"> <option style="color: inherit; background-color: none" value="none">none</option> <option style="color: black; background-color: aqua" value="aqua">aqua</option> <option style="color: white; background-color: black" value="black">black</option> <option style="color: white; background-color: blue" value="blue">blue</option> <option style="color: white; background-color: cornflowerblue" value="cornflowerblue">cornflowerblue</option> <option style="color: white; background-color: fuchsia" value="fuchsia">fuchsia</option> <option style="color: white; background-color: gray" value="gray">gray</option> <option style="color: white; background-color: green" value="green">green</option> <option style="color: black; background-color: lime" value="lime">lime</option> <option style="color: white; background-color: maroon" value="maroon">maroon</option> <option style="color: white; background-color: navy" value="navy">navy</option> <option style="color: white; background-color: olive" value="olive">olive</option> <option style="color: white; background-color: orange" value="orange">orange</option> <option style="color: white; background-color: orangered" value="orangered">orangered</option> <option style="color: black; background-color: pink" value="pink">pink</option> <option style="color: white; background-color: purple" value="purple">purple</option> <option style="color: white; background-color: red" value="red">red</option> <option style="color: black; background-color: silver" value="silver">silver</option> <option style="color: white; background-color: teal" value="teal">teal</option> <option style="color: black; background-color: white" value="white">white</option> <option style="color: black; background-color: yellow" value="yellow">yellow</option> </select> </div> <div class="fieldPair" style="flex-wrap: wrap"><label class="fieldPair-label" for="userTaggerPreview">Preview</label><span id="userTaggerPreview"><span class="RESUserTag"><a id="userTagPreview" class="userTag" title="set a tag" href="javascript:void 0"> </a></span></span></div> <div class="wes-usertagger-footer"><input type="button" id="userTaggerSave" value="✓ save tag" formaction=""></div> </form> </div></div>'; document.body.appendChild(formMarkup); document.body.querySelector(".userTagger-dialog").style.zIndex = 1001; console.log(user); var headerName = document.getElementById("userTagger-header-user-username"); headerName.textContent = user; console.log(document.getElementById("userTagger-header-user-username")); if(tags[user]){ var formTagTextInput = document.getElementById("userTaggerText"); formTagTextInput.value = tags[user].text; var formTagColorSelect = document.getElementById("userTaggerColor"); formTagColorSelect.value = tags[user].backgroundColor; var preview = document.getElementById("userTagPreview"); preview.innerText = tags[user].text; preview.style.color = tags[user].color; preview.style.backgroundColor = tags[user].backgroundColor; } formjsTable(); } function formjsTable(){ var userTaggerCloseButton = document.body.querySelector("#tagDialogClose"); userTaggerCloseButton.addEventListener("click", destroyDialog); var userTaggerText = document.body.querySelector("#userTaggerText"); userTaggerText.addEventListener("input", updateTagPreview); var colorSelector = document.body.querySelector("#userTaggerColor"); colorSelector.addEventListener("input", updateTagPreview); /*SAVE*/ var saveButton = document.body.querySelector("#userTaggerSave"); saveButton.addEventListener("click", saveTagTable); } function saveTagTable(){ var user = document.body.querySelector("#userTagger-header-user-username").innerText.trim(); var utc = document.body.querySelector("#userTaggerColor"); var tagData = { color : utc.selectedOptions[0].style.color, backgroundColor : utc.selectedOptions[0].style.backgroundColor, text : document.body.querySelector("#userTagPreview").textContent } if(!tags[user]){ console.log("tag doesnt exist"); var authors = document.body.querySelectorAll(".author"); for(var author of authors){ if(!author.innerText.trim().localeCompare(user)){ var tbc = author.querySelector(".tag-button-container"); author.removeChild(tbc); var tag = createTag(); tag.id = ""; tag.style.color = tagData.color; tag.style.backgroundColor = tagData.backgroundColor; tag.textContent = tagData.text; author.parentElement.insertBefore(tag, author.nextSibling); tag.addEventListener("click", function(){userTaggerShowForm(this)}); } } } tags[user] = tagData; GM.setValue("tags",JSON.stringify(tags)); destroyDialog(); //if user already had a tag, refresh it var allTags = document.body.querySelector(".container").querySelectorAll(".userTag"); for(var tag of allTags){ if(!tag.previousSibling.innerText.trim().localeCompare(user)){ tag.style.color = tags[user].color; tag.style.backgroundColor = tags[user].backgroundColor; tag.innerText = tags[user].text; } } unloadTagsTable(); loadTagsTable(); } function darkThemeOn(){ return !document.body.className.localeCompare("theme-dark"); } function pickThemeColor(){ return (darkThemeOn() ? 'white' : 'black'); } function deleteTagButton(){ var icon = document.createElement("span"); icon.innerHTML = '<i class="fas fa-times" style=" font-size:large ;color: white; cursor: pointer" title="Remove Tag"></i>'; var label = document.createElement("label"); label.className = "delete-tag-button-label"; var button = document.createElement("button"); button.style.display = "none"; var container = document.createElement("span"); container.className = "delete-tag-button-container"; container.style.display = "visible"; container.style.paddingRight = "5px"; label.appendChild(icon); label.appendChild(button); container.appendChild(label); return container; } /************************ 8.2 Misc functions ************************/ //appends a white space to a list function addWhiteSpaceToList(list){ var space = document.createElement('li'); space.style.display = "inline"; space.style.color = "white"; space.innerHTML = " " list.appendChild(space); } //appends a pipe '|' to a list function addDividerToList(list){ var divider = document.createElement('li'); divider.style.display = "inline"; divider.style.color = "white"; divider.innerHTML = "|"; list.appendChild(divider); } })();