您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
This script provides a UI that allows you to make and share themes for mTurk.com
// ==UserScript== // @name mTurkThemes // @namespace http://ericfraze.com // @version 1.2 // @description This script provides a UI that allows you to make and share themes for mTurk.com // @match https://www.mturk.com/* // @resource cssfile https://magnilucent.github.io/mTurk-Themes/css/style.css?version=71234123 // @resource colpickcssfile https://magnilucent.github.io/mTurk-Themes/css/colpick.css?version=17 // @grant GM_addStyle // @grant GM_getResourceText // @grant GM_setClipboard // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @copyright 2014+, Eric Fraze // @require http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js // @require https://greasyfork.org/scripts/1562-colpick-color-picker/code/colpick%20Color%20Picker.js?version=3858 // ==/UserScript== // Add color picker CSS GM_addStyle(GM_getResourceText("colpickcssfile")); // The CSS used to apply the themes var CSSText; // Holds all the current color states var variables; // Groups the variables by color value var colorGroups; // Name of current theme var currentTheme; // Hiddden "theme" that holds the unsaved changes of a theme // TODO: Make sure no one can name a name 'unsavedTheme'. var unsavedTheme = "unsavedTheme"; // The version of the script on last save var savedVariableVersion; // The version of the script on last save var currentVariableVersion = 5; // List of all themes installed var themeNames; // Get last save script version savedVariableVersion = GM_getValue('savedVariableVersion', -1); // Check to see if there is a current theme. If not, this is probably the first run. if (GM_getValue('mturk-current-theme', -1) === -1){ // Set to default theme if there is no current theme. currentTheme = "Default"; }else{ // Get the current theme name. currentTheme = GM_getValue('mturk-current-theme'); } // Load theme names if (GM_getValue('mturk-theme-names', -1) === -1){ themeNames = ['Default']; }else{ themeNames = JSON.parse(GM_getValue("mturk-theme-names")); } /***************************************** * Load current theme ******************************************/ // Set variables to defaults resetVariables(); // Apply the theme applyTheme(currentTheme); // Wait for DOM to load $(document).ready(function() { // Add the text used to open the panel $("#user_name_field").after(' | <span id="mturkthemeoptions" class="header_links">Theme Options</span>'); // Add the mTurkTheme panel $("body").append('<div id="mturktheme" class=""></div>'); // Add the toolbar (import/save/undo buttons, ect) addToolbar(); // Add the wrapper for the color list $("#mturktheme").append('<div class="color-list-wrapper"></div>'); // Make the color picker plugin apply on "DOMNodeInserted" bindColorPicker(); // Refresh the color list refreshList(); }); // Toolbar has the buttons and theme select function addToolbar(){ $("#mturktheme").append('<div class="toolbar"></div>'); $("#mturktheme .toolbar").append('<div title="New theme" class="icon add"></div>'); $("#mturktheme .toolbar").append('<select class="theme-select"></select>'); $("#mturktheme .toolbar").append('<div title="Import theme" class="icon import"></div>'); $("#mturktheme .toolbar").append('<div title="Export theme" class="icon export"></div>'); $("#mturktheme .toolbar").append('<div title="Hide" class="icon close"></div>'); $("#mturktheme .toolbar").append('<div title="Save theme" class="icon save"></div>'); $("#mturktheme .toolbar").append('<div title="Revert to last save" class="icon revert"></div>'); updateThemeList(); } // Update the theme list in the toolbar function updateThemeList() { var unsavedFlag = ""; $("#mturktheme .toolbar .theme-select").empty(); for (var i in themeNames){ if ( (themeNames[i] == currentTheme) && (GM_getValue('mturk-theme-data-' + unsavedTheme, -1) !== -1) ) unsavedFlag = "*"; else unsavedFlag = ""; $("#mturktheme .toolbar .theme-select").append('<option value="' + themeNames[i] + '">' + unsavedFlag + themeNames[i] + unsavedFlag +'</option>'); } $("#mturktheme .toolbar .theme-select").val(currentTheme); } // Binds the color picker to each new color list element function bindColorPicker() { // Dynamically binds the color picker to each new color list item $("#mturktheme .color-list-wrapper").bind('DOMNodeInserted', function() { // Binds the colorpicker to a list item $("#mturktheme .variable-group-wrapper .color").colpick({ // Sets the color of the color picker to the list item's color onBeforeShow:function() { var oldColor; // Returns an RBG version of the background oldColor = $(this).css('background-color'); // Single out the three colors oldColor = oldColor.replace("rgb(", "").replace(")",""); // Make an array of the colors oldColor = oldColor.split(", "); // This function requires an object to be passed, so send one over. $(this).colpickSetColor( { 'r':oldColor[0], 'g':oldColor[1], 'b':oldColor[2] } ); }, // Changes the color in the CSS and applies the changes onSubmit:function(hsb,hex,rgb,el) { var oldColor, variableName; // Hides the color picker $(el).colpickHide(); // Using the browser to make the old and new colors the same text value, then comparing them $("#mturkthemeoptions").css("border-color", "#" + hex); if ( $(el).css('background-color') != $("#mturkthemeoptions").css("border-color") ) { // Check if the list item is a single item or a group item if ($(el).parent('.variable-color').length) { // Single items have the variable name as their name variableName = $(el).attr('name'); // Need to get the color dynamically oldColor = variables[getPropertyIndex(variableName)][1]; // Change the CSS setProperty(variableName, oldColor, "#" + hex); // Old code that updated the list item. May use this again when RefreshList is updated. //$(this).css('background-color', newColor); }else{ // Group items have the color value as their name oldColor = $(el).attr('name'); // Changes the CSS of the entire group setGroupProperty(oldColor, "#" + hex); // Old code that updated the list item. May use this again when RefreshList is updated. //$('#mturktheme .color[style="background-color: ' + color + ';"]').css('background-color', newColor); //$(this).parent().children(".header").text(newColor); } // Adds the CSS to the page applyCSS(); // Refreshes the color list refreshList(); // Saves unsaved changes // Seems ironic but they need to be saved so they persist through page loads. saveTheme(unsavedTheme); // Update the theme list to add the unsaved marker updateThemeList(); } } }); }); } $("#mturktheme .variable-color").live('mouseenter', function () { var color = $(this).find(".color"); // Single items have the variable name as their name variableName = $(color).attr('name'); // Need to get the color dynamically oldColor = variables[getPropertyIndex(variableName)][1]; // Change the CSS setProperty(variableName, null, "red"); // Adds the CSS to the page applyCSS(); }); $("#mturktheme .variable-color").live('mouseleave', function () { var color = $(this).find(".color"); // Single items have the variable name as their name variableName = $(color).attr('name'); // Need to get the color dynamically oldColor = variables[getPropertyIndex(variableName)][1]; // Change the CSS setProperty(variableName, null, oldColor); // Adds the CSS to the page applyCSS(); }); // Clicking the text makes mTurkTheme slide $("#mturkthemeoptions").live('click', function () { $("#mturktheme").addClass("active"); }); // Expand group list items $("#mturktheme .variable-group .expand").live('click', function () { $(this).parents(".variable-group-wrapper").toggleClass("active"); }); // Add a theme $("#mturktheme .toolbar .add").live('click', function () { var themeName = prompt("Enter the theme name:"); addTheme(themeName); }); // Import a theme $("#mturktheme .toolbar .import").live('click', function () { // Get the stringified variables var newTheme = prompt("Paste in the theme!"); // Make sure the user didn't cancel. if (newTheme != null) { // Reset variables to defaults resetVariables(); // Load variables from stringified variables variables = JSON.parse(newTheme); // Load changes in unsaved theme so they can be reverted saveTheme(unsavedTheme); // Apply the changes // applyTheme will detect the unsaved changes and load theme applyTheme(currentTheme); // Refresh the color list refreshList(); // Update the theme list to add the unsaved marker updateThemeList(); } }); // Switch themes when they are selected in the dropdown box $("#mturktheme .toolbar .theme-select").live('change', function () { // Delete unsaved changes deleteTheme(unsavedTheme); // Get the theme name currentTheme = $("#mturktheme .toolbar .theme-select :selected").attr('value'); // Set the current theme GM_setValue('mturk-current-theme', currentTheme); // Apply the theme applyTheme(currentTheme); // Refresh color list refreshList(); // Update the theme list to add the unsaved marker updateThemeList(); }); // Export a theme $("#mturktheme .toolbar .export").live('click', function () { // Set the stringified variables to the clipboard GM_setClipboard(JSON.stringify(variables)); alert("Theme copied to clipboard. Pastebin and share!"); }); // Revert to last save $("#mturktheme .toolbar .revert").live('click', function () { // Delete unsaved changes deleteTheme(unsavedTheme); // Apply last save applyTheme(currentTheme) // Refresh color list refreshList(); // Update the theme list to add the unsaved marker updateThemeList(); }); // Save theme $("#mturktheme .toolbar .save").live('click', function () { saveTheme(currentTheme); deleteTheme(unsavedTheme); // Update the theme list to add the unsaved marker updateThemeList(); }); // Close the panel $("#mturktheme .toolbar .close").live('click', function () { $("#mturktheme").removeClass("active"); }); function resetVariables() { // All of the color variables variables = [ ["hit-capsule-title-color", ""], ["hit-capsule-title-hover-color", ""], ["hit-capsule-title-visited-color", ""], ["hit-capsule-link-right-color", ""], ["hit-capsule-link-right-hover-color", ""], ["hit-capsule-link-right-visited-color", ""], ["hit-capsule-field-title-color", ""], ["hit-capsule-field-text-color", ""], ["header-link-color", ""], ["subtab-text-color", ""], ["separator-text-color", ""], ["searchbar-text-color", ""], ["whatis-link-color", ""], ["dashboard-and-workerID-text-color", ""], ["if-you-re-not-text-color", ""], ["link-default-color", ""], ["link-default-hover-color", ""], ["link-default-visited-color", ""], ["show-earnings-details-text-color", ""], ["button-background-color", ""], ["button-border-color", ""], ["button-text-color", ""], ["tab-text-color", ""], ["tab-background-color-inactive", ""], ["tab-border-color-inactive", ""], ["tab-background-color-active", ""], ["tab-border-color-active", ""], ["page-background-color", ""], ["tab-text-color-active", ""], ["page-header-background-color", ""], ["page-header-border-color", ""], ["default-text-color", ""], ["search-go-button-background-color", ""], ["search-go-button-border-color", ""], ["search-go-button-text-color", ""], ["table-body-background-color", ""], ["table-header-background-color", ""], ["table-header-text-color", ""], ["table-body-border-color", ""], ["table-list-text-color", ""], ["table-list-header-background-color", ""], ["table-list-header-text-color", ""], ["table-list-row-even-background-color", ""], ["table-list-row-border-color", ""], ["table-list-row-odd-background-color", ""], ["table-link-color", ""], ["sort-button-text-color", ""], ["hit-border-color", ""], ["hit-header-unqualified-background-color", ""], ["hit-body-unqualified-background-color", ""], ["hit-header-qualified-background-color", ""], ["hit-body-qualified-background-color", ""], ["page-footer-background-color", ""], ["footer-text-color", ""], ["footer-link-text-color", ""], ["details-link-text-color", ""], ]; // Used to dynamically group the list items colorGroups = []; } // Returns the style element that holds the theme function getStyle() { // Find the correct style element by looking for my comment return $( "style:contains('/* mTurk Theme */')" ); } // Applies CSSText to the style element function applyCSS() { // Replace the text of the style element getStyle().text(CSSText); } // Makes the regex string used to find and change properties in the CSS function findPropertyRegex(variableName, flags) { // Fancy thing lets flags be optiional. flags = typeof flags !== 'undefined' ? flags : 'g'; // Ugh. Regex. I need to escape the escapes here. Crazy. // Select the CSS property by the comment in the line above it. // NOTE: This relies on the property you want to change being the FIRST value // "border: 1px blue solid ;" will change "1px", not "blue" // "border: blue 1px solid;" will change "blue" // Group 1: comment & property // Group 2: property you want to change (I hope!) // Group 3: values after the property // Group 4: the semicolon var regstring = "(.*\\/\\*\\s" + variableName + "\\s\\*\\/\\s+.*:\\s+)(#*[A-Za-z0-9]+)(.*)(;.*)"; // Create the RegEx object return new RegExp(regstring, flags); } // Edits the CSS to set a property function replaceProperty(regex, str, value) { return str.replace(regex, "$1" + value + "$3$4"); } // Finds the index of a property in variables function getPropertyIndex (variableName) { for (var i in variables) { if (variables[i] != null) { if (variableName == variables[i][0]) { return i; } } } return -1; } // Gets a property from the CSS // TODO: I think this function may be pretty unnessary and is slowing down the script // The "variables" variable has the values too as long as its been applied function getProperty(variableName) { // Get the CSS property regex regex = findPropertyRegex(variableName, ''); // Get the groups groups = regex.exec(CSSText); if (groups != null) { // Return the value return groups[2]; }else{ console.log("Couldn't find " + variableName); var i = getPropertyIndex(variableName); delete variables[i]; return -1; } } // Set an individual property to a color function setProperty(variableName, oldColor, newColor) { // Get the CSS property regex regex = findPropertyRegex(variableName); // Replace the color with the one we want. CSSText = replaceProperty(regex, CSSText, newColor); // Update the color grouping if needed if (oldColor !== null) { var index = getPropertyIndex(variableName); variables[index][1] = newColor; if (newColor in colorGroups) { colorGroups[newColor].push(index); }else{ colorGroups[newColor] = []; colorGroups[newColor][0] = index; } var groupIndex = colorGroups[oldColor].indexOf(index); delete colorGroups[oldColor][groupIndex]; } } // Set a group of colors to another color function setGroupProperty (oldColor, newColor) { // Update the color grouping for (var i in colorGroups[oldColor]) { index = colorGroups[oldColor][i]; variableName = variables[index][0]; setProperty(variableName, oldColor, newColor); } delete colorGroups[oldColor]; } // Refreshes the color lust // TODO: Make this only update what is needed instead of closing all color groups. function refreshList () { var savedVariables = getSavedVariables(currentTheme); // Remove the old color pickers $(".colpick").remove(); // Empty the list $("#mturktheme .color-list-wrapper").empty(); // Refill the list for (var color in colorGroups) { var colorGroup = colorGroups[color]; var appendString = ""; var appendColorString = ""; var unsavedChanges = false; for (var ii in colorGroup) { var index = colorGroup[ii]; var variableName = variables[index][0]; var unsavedText = ""; if (savedVariables != -1) { if (color != savedVariables[index][1]){ unsavedChanges = true; unsavedText = " *"; console.log("Unsaved color"); }else{ unsavedText = ""; } } appendColorString += '<div class="variable-color"><div class="content">' + variableName + unsavedText + '</div>' appendColorString += '<div name = "' + variableName + '" class="color" style="background-color: ' + color + ';"></div></div>'; } if (unsavedChanges) { unsavedText = " *"; }else{ unsavedText = ""; } appendString = '<div class = "variable-group-wrapper"><div class="variable-group">'; appendString += '<div class="content">' + color + unsavedText + '</div><div name = "' + color + '" class="color" style="background-color: ' + color + ';"></div>'; appendString += '<div class="expand"></div></div>'; appendString += appendColorString; appendString += '</div>'; $("#mturktheme .color-list-wrapper").append(appendString); } } // Add a theme // TODO: Make sure the theme doesn't exist. // TODO: Set the current theme to the new theme function addTheme(themeName){ // Add the theme name to the array themeNames.push(themeName); // Update the theme list to show the added theme updateThemeList(); // Save the name names in local storage GM_setValue('mturk-theme-names', JSON.stringify( themeNames )); // Save the theme (uses current variables) saveTheme(themeName); } function deleteTheme(themeName) { GM_deleteValue('mturk-theme-data-' + themeName); } function saveTheme(themeName) { GM_setValue('savedVariableVersion', currentVariableVersion); GM_setValue('mturk-theme-data-' + themeName, JSON.stringify(variables)); } function loadTheme(themeName, overrideUnsaved) { if (overrideUnsaved == null) overrideUnsaved = false; // Check for an unsaved theme if ( ( getSavedVariables(unsavedTheme) !== -1 ) && !overrideUnsaved ) { console.log("Loading unsaved theme changes"); variables = getSavedVariables(unsavedTheme); }else{ // Check for an existing theme if (getSavedVariables(themeName) !== -1){ console.log("Loading saved theme"); variables = getSavedVariables(themeName); }else{ // Load the default CSS if all else fails. console.log("Loading default CSS"); CSSToVariables(); } } } function getSavedVariables(themeName) { return JSON.parse(GM_getValue('mturk-theme-data-' + themeName, -1)); } // Apply a theme function applyTheme(themeName) { resetVariables(); currentTheme = themeName; // Get original CSS text CSSText = GM_getResourceText("cssfile"); if (savedVariableVersion != currentVariableVersion){ console.log("New version!"); if (getSavedVariables(themeName) !== -1){ loadTheme(currentTheme, true); VariablesToCSS(); CSSToVariables(); saveTheme(themeName); } if (getSavedVariables(unsavedTheme) !== -1){ loadTheme(currentTheme); VariablesToCSS(); CSSToVariables(); saveTheme(unsavedTheme); } }else{ // Load theme's variables loadTheme(currentTheme); // Applies the variables to the CSS VariablesToCSS(); } // Add the CSS to the page if (getStyle().length){ applyCSS(); }else{ GM_addStyle(CSSText); } } // Applies the variables to the CSS function VariablesToCSS() { var variableName; var color; for (var i in variables) { if (variables[i]) { variableName = variables[i][0]; color = variables[i][1]; if (color == "") { color = getProperty(variableName); } setProperty(variableName, null, color); if (color in colorGroups) { colorGroups[color].push(i); }else{ colorGroups[color] = []; colorGroups[color][0] = i; } } } } // Converts a CSS string to a variable list. function CSSToVariables() { resetVariables(); // Load all the color values. var variableName; var color; for (var i in variables) { variableName = variables[i][0]; color = getProperty(variableName); console.log(variableName + " | " + color); if (color != -1){ variables[i][1] = color; if (color in colorGroups) { colorGroups[color].push(i); }else{ colorGroups[color] = []; colorGroups[color][0] = i; } } } }