您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Saves previously set tag and colour to use again.
当前为
// ==UserScript== // @name Reddit - Remember RES tag action // @description Saves previously set tag and colour to use again. // @author James Skinner <[email protected]> (http://github.com/spiralx) // @namespace http://spiralx.org/ // @version 0.8.0 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAFiAAABYgAWToQQYAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAAF3SURBVDhP1ZI/SAJhGMZN3WpKOAgsKGiIoKWg0K2LXIJWj6DAhpAgKMiW7irBqziHbhYE12sLGtWGKHBx0kHcQrBJXNIz9e35vvsQoj841g9+fHy8z/PyHZzrXzANNbgKF2ASHsOhOYGTUIb3cBSq4hyKa3Ey2GsMeMRvvzALd+AVvIPbcAb+yAq8hBehUOgxnU5TtVol27ap3W5TpVKhVCpFsiw/IHMusstwgOHxeDZM07T7/T5Rr0vUfacBvR7uHWIzwzBayK+zDm8KktFo9FXEifaXiHbnxAXEZKKtqcHSSCTygs6nBYuWZfEhR1eIzjbFBdzsYcma8xKQyWQInXmn6jCeSCQ6fDoEqqqyzxhzqgK/368Xi0UeKJfLpGka5fN5yuVyrEClUonPCoUCSZLE/oMvjGBwqut6q16vU6PRoGw2yxc0m02q1WoUj8fffD5fjGWdyvdMeL3ew2AweKsoynM4HH4KBAKW2+0+wExyIn8Hl+sDt5ENCrpr91QAAAAASUVORK5CYII= // @icon64 data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2029%2025%22%3E%3Cg%20transform=%22translate(1%201)%22%20stroke-width=%221.1%22%20fill-rule=%22evenodd%22%20fill=%22none%22%3E%3Ccircle%20stroke=%22#000%22%20cx=%222.7%22%20r=%222.7%22%20cy=%2210.7%22%20fill=%22#fff%22/%3E%3Ccircle%20stroke=%22#000%22%20cx=%2224.7%22%20r=%222.7%22%20cy=%2210.7%22%20fill=%22#fff%22/%3E%3Cpath%20stroke-linejoin=%22round%22%20stroke=%22#000%22%20stroke-linecap=%22round%22%20d=%22M21.23%201.35L15.83.08l-2%207.28%22/%3E%3Ccircle%20stroke=%22#000%22%20cx=%2223.13%22%20r=%222.13%22%20cy=%222.13%22%20fill=%22#fff%22/%3E%3Cellipse%20cy=%2214.99%22%20rx=%2212.24%22%20ry=%227.99%22%20stroke=%22#000%22%20cx=%2213.24%22%20fill=%22#fff%22/%3E%3Cg%20transform=%22translate(8%2012)%22%3E%3Ccircle%20stroke=%22#FF4500%22%20cx=%221%22%20r=%221.43%22%20cy=%221.43%22%20fill=%22#FF4500%22/%3E%3Ccircle%20stroke=%22#FF4500%22%20cx=%2210%22%20r=%221.43%22%20cy=%221.43%22%20fill=%22#FF4500%22/%3E%3Cpath%20stroke=%22#000%22%20d=%22M1.5%206.23C2.58%207.3%204.3%207.5%205.73%207.5m4.24-1.27C8.9%207.3%207.17%207.5%205.77%207.5%22/%3E%3C/g%3E%3C/g%3E%3C/svg%3E // @match *://*.reddit.com/r/*/comments/* // @match *://*.reddit.com/user/* // @grant unsafeWindow // @run-at document-end // @require https://unpkg.com/jquery@3/dist/jquery.min.js // @require https://greasyfork.org/scripts/370255-console-message/code/consolemessage.js?version=612436 // ==/UserScript== // @require https://greasyfork.org/scripts/10443-datacache-simple-storage-wrapper/code/DataCache%20-%20Simple%20storage%20wrapper.js?version=56961 /* jshint asi: true, esnext: true, laxbreak: true */ /* global jQuery, MutationSummary */ /** ==== 0.8.0 (2018.07.13) ==== * Changed console.message require to use GreasyFork ==== 0.7.0 (2018.02.13) ==== * Changed the rendering of the tag preview to match how RES does it * Moved output to all use console.message ==== 0.6.0 (2018.02.11) ==== * Use unpkg.com for jQuery * Add console.message for logging * Use localstorage to save tags * Use new Tag class to store tag info * Updated ID for text field in tag popup ==== 0.5.1 (2018.02.11) ==== * Update icons to match other Reddit script ==== 0.5.0 (26.08.2017) ==== * Change to simple use of GM_getValue and GM_setValue for storage ==== 0.4.0 (21.08.2017) ==== * Update all other tags correctly when changing a user's tag * Handle removing all other tags when clearing a user's tag ==== 0.3.0 (13.07.2017) ==== * Checks tag link to see if tag set, always overwrites if not * Updates other tags for same user on current page ==== 0.2.1 (27.06.2017) ==== * Changed timeout of field set function to 250ms ==== 0.2.0 (31.05.2017) ==== * Updated jQuery to v3.2.1 * Added timeout before overriding tag/colour fields * Update preview when setting tag/colour */ ; ($ => { 'use strict' const NORMAL = 'font-weight: normal; text-decoration: none; color: black' const ERROR = 'font-weight: bold; color: #f4f' const LINK = 'color: #05f; text-decoration: underline' const BOLD = 'font-weight: bold' const BLUE = [ 'color: #05f', 'color: #000' ] const GREEN = [ 'color: #c1007f', 'color: #000' ] const qval = (v, n) => `${n}=%c${JSON.stringify(v)}%c` const _BOLD = { fontWeight: 'bold' } const _GREEN = { color: '#c1007f' } const _BLUE = { color: '#05f' } // -------------------------------------------------------------------- const bgToTextColorMap = { none: 'inherit', aqua: 'black', black: 'white', blue: 'white', cornflowerblue: 'white', fuchsia: 'white', gray: 'white', green: 'white', lime: 'black', maroon: 'white', navy: 'white', olive: 'white', orange: 'white', orangered: 'white', pink: 'black', purple: 'white', red: 'white', silver: 'black', teal: 'white', white: 'black', yellow: 'black' } // -------------------------------------------------------------------------- $.fn.outer = function() { const elem = this[0] || {} return elem.nodeType === Document.ELEMENT_NODE ? elem.outerHTML : null } console.message.prototype.dump = function(obj) { if (obj && typeof obj.dump === 'function') { obj.dump.call(obj, this) } else if (typeof obj === 'function') { obj(this) } return this } // -------------------------------------------------------------------------- class Tag { constructor(text = '', colour = 'none') { this.text = text this.colour = colour } get css() { const color = bgToTextColorMap[ this.colour ] // + ` !important` const backgroundColor = this.colour === 'none' ? 'transparent' : this.colour return { color, backgroundColor } } buildPreviewTag() { const $a = $(`<a>`, { href: '#', title: this.text }) .addClass(`userTagLink hasTag truncateTag`) .css(this.css) .text(this.text) return $(`<span>`) .addClass('RESUserTag') .append($a) } apply($elem) { return $elem.text(this.text).css(this.css) } equals(other) { return this.text === other.text && this.colour === other.colour } json() { return JSON.stringify(this) } dump(msg) { /* jshint ignore:start */ msg.text(this.text, { ...this.css, fontSize: '0.9em', padding: '0 4px', border: 'solid 1px rgb(199, 199, 199)', borderRadius: 3, }) /* jshint ignore:end */ } } Tag.parse = str => { const { text, colour } = JSON.parse(str) return new Tag(text, colour) } Tag.default = () => new Tag($('.pagename a').text(), 'olive') // -------------------------------------------------------------------------- const tags = JSON.parse(localStorage.getItem('resrem') || '[]').map(v => new Tag(v.text, v.colour)) function getLastTag() { return tags.length > 0 ? tags[0] : Tag.default() } function saveTag(tag) { const idx = tags.findIndex(t => t.equals(tag)) if (idx !== -1) { tags.splice(idx, 1) } tags.unshift(tag) localStorage.setItem('resrem', JSON.stringify(tags)) return tag } const msg = console.message().text('onScriptInit:', _BOLD) tags.forEach(tag => { msg.text(' ').dump(tag) }) msg.print() // -------------------------------------------------------------------------- function onTagModalOpened() { const $tagField = $('#userTaggerText') const $colourField = $('#userTaggerColor') const $previewField = $('#userTaggerPreview') const previousTag = getLastTag() if (previousTag) { $tagField.val(previousTag.text) $colourField.val(previousTag.colour) const $previewTag = previousTag.buildPreviewTag() console.info($previewTag.outer()) $previewField .empty() .append($previewTag) } } // -------------------------------------------------------------------------- function onSaveTag() { const text = $('#userTaggerText').val() const colour = $('#userTaggerColor').val() const user = $('#userTaggerName').val() if (text) { const newTag = saveTag(new Tag(text, colour)) const msg = console.message() .text('onSaveTag:', _BOLD) .text(' ') .dump(newTag) .text('* ') tags.slice(1).forEach(tag => { msg.text(' ').dump(tag) }) msg.print() $(`a.userTagLink[username=${user}]`) .text(newTag.text) .css(newTag.css) .addClass('hasTag') .removeClass('RESUserTagImage') } else { $(`a.userTagLink[username=${user}]`) .text('') .removeAttr('style') .removeClass('hasTag') .addClass('RESUserTagImage') } } // -------------------------------------------------------------------------- $('body') .on('click.resrem', 'a.userTagLink:not(.hasTag)', () => { setTimeout(onTagModalOpened, 250) }) .on('click.resrem', '#userTaggerSave', onSaveTag) /* <div class="RESHover RESHoverInfoCard RESDialogSmall" style="top: 387.918px; left: 215.767px; width: 350px; display: block; opacity: 1;"> <h3 class="RESHoverTitle" data-hover-element="0"> <div> <span class="res-icon"></span> <span>Plan-Six</span> </div> </h3> <div class="RESCloseButton">x</div> <div class="RESHoverBody RESDialogContents" data-hover-element="1"> <form id="userTaggerToolTip"> <div class="fieldPair"> <label class="fieldPair-label" for="userTaggerText">Text</label> <input class="fieldPair-text" type="text" id="userTaggerText"> </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"> <label class="fieldPair-label" for="userTaggerPreview">Preview</label> <span id="userTaggerPreview" style="color: white; background-color: olive;"> <span class="RESUserTag"> <a class="userTagLink hasTag truncateTag" style="background-color: olive; color: white !important;" title="Sexist" href="javascript:void 0">Sexist</a> </span> </span> </div> <a class="userTagLink hasTag truncateTag" style="background-color: olive; color: white !important;" title="Feminist" href="javascript:void 0">Feminist</a> <div class="fieldPair res-usertag-ignore"> <label class="fieldPair-label" for="userTaggerIgnore">Ignore</label> <div id="userTaggerIgnoreContainer" class="toggleButton "> <span class="toggleThumb"></span> <div class="toggleLabel res-icon" data-enabled-text="" data-disabled-text=""></div> <input id="userTaggerIgnore" name="userTaggerIgnore" type="checkbox"> </div> <a class="gearIcon" href="#res:settings/userTagger/hardIgnore" title="RES Settings > User Tagger > hardIgnore"> configure </a> </div> <div class="fieldPair"> <label class="fieldPair-label" for="userTaggerLink"> <span class="userTaggerOpenLink"> <a title="open link" href="javascript:void 0">Source URL</a> </span> </label> <input class="fieldPair-text" type="text" id="userTaggerLink" value="https://www.reddit.com/r/giantbomb/comments/7x251d/all_systems_goku_02/du5fpwr/"> </div> <div class="fieldPair"> <label class="fieldPair-label" for="userTaggerVotesUp" title="Upvotes you have given this redditor">Upvotes</label> <input type="number" style="width: 50px;" id="userTaggerVotesUp" value="0"> </div> <div class="fieldPair"> <label class="fieldPair-label" for="userTaggerVotesDown" title="Downvotes you have given this redditor">Downvotes</label> <input type="number" style="width: 50px;" id="userTaggerVotesDown" value="0"> </div> <div class="res-usertagger-footer"> <a href="/r/dashboard#userTaggerContents" target="_blank" rel="noopener noreferer">View tagged users</a> <input type="submit" id="userTaggerSave" value="✓ save tag"> </div> </form> </div> </div> */ })(jQuery) jQuery.noConflict(true)