GameCATs Highlighting

Highlights stuff, I dunno.

当前为 2016-01-21 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name GameCATs Highlighting
  3. // @version 2.0.15
  4. // @author Metallia - Formerly known as King of Cats
  5. // @namespace Cats
  6. // @description Highlights stuff, I dunno.
  7. // @include http://www.gamefaqs.com/*
  8. // @grant GM_getValue
  9. // @grant GM_setValue
  10. // @grant GM_deleteValue
  11. // ==/UserScript==
  12.  
  13. // css guys, look for ".gamecats-highlight" for anything I've added a background colour to, or ".gamecats-text" for text colour changes, or just the "friend" class GameFAQs itself uses for their own highlighting.
  14. // Also, to be more specific:
  15. // .gamecats-highlight-message-tr
  16. // .gamecats-highlight-message-td
  17. // .gamecats-highlight-topic-tr
  18. // .gamecats-highlight-topic-td
  19. // .gamecats-text-tr
  20. // .gamecats-text-td
  21. // .gamecats-text-a
  22. // .gamecats-autocontrast-black
  23. // .gamecats-autocontrast-white
  24.  
  25. // First run check, fill in some settings. Also fill in one list if they try to save with none. >_>
  26. if (!GM_getValue("numberOfLists") || GM_getValue("numberOfLists") == 0) {
  27. GM_setValue("numberOfLists",1);
  28. GM_setValue("useColouredCustomCSS",false);
  29. GM_setValue("caseInsensitive",true);
  30. GM_setValue("styleGroupAsTag",false);
  31. GM_setValue("settingsLinkLocation",2);
  32. GM_setValue("Main Settings","Script Author|Metallia|#B266FF|auto|true,false,true,false,false,true,false,false,false,false,false,false,false,false,false");
  33. GM_setValue("version","2.0.15");
  34. }
  35.  
  36. // Attach a link to the settings page on GameFAQs.
  37. var userInbox = document.getElementsByClassName("user_inbox");
  38. if (userInbox[0] != null) {
  39. if (GM_getValue("settingsLinkLocation","unset") === 0 || GM_getValue("settingsLinkLocation","unset") === 2) {
  40. var settingsLink = document.createElement('a');
  41. settingsLink.setAttribute("href","#HighlightSettings");
  42. settingsLink.addEventListener('click',function() {prepSettings();},true);
  43. settingsLink.textContent = "Highlight Settings";
  44. var userLink = userInbox[0].childNodes;
  45. for (var i = 0; i < userLink.length; i++) {
  46. if ((userLink[i].className||"").indexOf("welcome") != -1) {
  47. userLink[i].parentNode.insertBefore(settingsLink,userLink[i].nextSibling);
  48. userLink[i].parentNode.insertBefore(document.createTextNode(" "),userLink[i].nextSibling);
  49. break;
  50. }
  51. }
  52. }
  53. }
  54. if (document.location.href.match(/(^[^#]*)/)[0] === "http://www.gamefaqs.com/user") {
  55. if (GM_getValue("settingsLinkLocation","unset") === 1 || GM_getValue("settingsLinkLocation","unset") === 2) {
  56. var myAccountTable = document.getElementsByTagName("tbody")[2];
  57. var settingsTR = document.createElement('tr');
  58. var settingsTD = document.createElement('td');
  59. var settingsLink = document.createElement('a');
  60. settingsLink.setAttribute("href","#HighlightSettings");
  61. settingsLink.addEventListener('click',function() {prepSettings();},true);
  62. settingsLink.textContent = "GameCATs";
  63. myAccountTable.appendChild(settingsTR);
  64. settingsTR.appendChild(settingsTD);
  65. settingsTD.appendChild(settingsLink);
  66. }
  67. }
  68.  
  69. var version = GM_getValue("version").split(".");
  70. var theme = document.getElementsByTagName("body")[0].getAttribute("class");
  71.  
  72. // Settings to get filled in by getSettings()
  73. var storedNumberOfLists = new Array();
  74. var storedListNames = new Array();
  75. var storedUsernames = new Array();
  76. var storedHighlightColours = new Array();
  77. var storedHighlightTextColours = new Array();
  78. var storedActionHighlightTopic = new Array();
  79. var storedActionIgnoreTopic = new Array();
  80. var storedActionHighlightPost = new Array();
  81. var storedActionIgnorePost = new Array();
  82. var storedActionTagTopic = new Array();
  83. var storedActionTagPost = new Array();
  84. var storedActionHighlightTopicContent = new Array();
  85. var storedActionIgnoreTopicContent = new Array();
  86. var storedActionHighlightPostContent = new Array();
  87. var storedActionIgnorePostContent = new Array();
  88. var storedActionAllowStacking = new Array();
  89. var storedActionHighlightAdmin = new Array();
  90. var storedActionHighlightMod = new Array();
  91. var storedActionHighlightVIP = new Array();
  92. var storedActionHighlightTC = new Array();
  93. var storedCaseInsensitive = new Array();
  94. var storedUseColouredCustomCSSSetting = new Array();
  95. var storedStyleGroupAsTagSetting = new Array();
  96.  
  97. // Highlight functions
  98.  
  99. function compareVersion (testVersion,exact) {
  100. testVersion = testVersion.split(".");
  101. if (exact) {
  102. return ((testVersion[0] == version[0]) && (testVersion[1] == version[1]) && (testVersion[2] == version[2]));
  103. } else {
  104. if (version[0] < testVersion[0]) {
  105. return true;
  106. } else if (version[0] == testVersion[0]) {
  107. if (version[1] < testVersion[1]) {
  108. return true;
  109. } else if (version[1] == testVersion[1]) {
  110. if (version[2] < testVersion[2]) {
  111. return true;
  112. } else {
  113. return false;
  114. }
  115. } else {
  116. return false;
  117. }
  118. } else {
  119. return false;
  120. }
  121. }
  122. }
  123.  
  124. function getSettings () {
  125. storedNumberOfLists = GM_getValue("numberOfLists");
  126. var allOfTheThings = GM_getValue("Main Settings");
  127. var fullList = allOfTheThings.split("^");
  128. var splitListItems = new Array();
  129. var usernames = new Array();
  130. var splitActions = new Array();
  131. for (var i = 0; i < storedNumberOfLists; i++) {
  132. splitListItems = fullList[i].split("|");
  133. splitActions[i] = splitListItems[4].split(",");
  134. storedListNames[i] = splitListItems[0];
  135. storedUsernames[i] = splitListItems[1].split(",");
  136. storedHighlightColours[i] = splitListItems[2];
  137. storedHighlightTextColours[i] = splitListItems[3];
  138. // These look kinda funky, but I'm trading in the stored "true" and "false" strings for actual booleans.
  139. storedActionHighlightTopic[i] = (splitActions[i][0] == "true");
  140. storedActionIgnoreTopic[i] = (splitActions[i][1] == "true");
  141. storedActionHighlightPost[i] = (splitActions[i][2] == "true");
  142. storedActionIgnorePost[i] = (splitActions[i][3] == "true");
  143. storedActionTagTopic[i] = (splitActions[i][4] == "true");
  144. storedActionTagPost[i] = (splitActions[i][5] == "true");
  145. storedActionHighlightTopicContent[i] = (splitActions[i][6] == "true");
  146. storedActionIgnoreTopicContent[i] = (splitActions[i][7] == "true");
  147. storedActionHighlightPostContent[i] = (splitActions[i][8] == "true");
  148. storedActionIgnorePostContent[i] = (splitActions[i][9] == "true");
  149. storedActionAllowStacking[i] = (splitActions[i][10] == "true");
  150. storedActionHighlightAdmin[i] = (splitActions[i][11] == "true");
  151. storedActionHighlightMod[i] = (splitActions[i][12] == "true");
  152. storedActionHighlightVIP[i] = (splitActions[i][13] == "true");
  153. storedActionHighlightTC[i] = (splitActions[i][14] == "true");
  154. }
  155. storedCaseInsensitive = GM_getValue("caseInsensitive");
  156. storedUseColouredCustomCSSSetting = GM_getValue("useColouredCustomCSS");
  157. storedStyleGroupAsTagSetting = GM_getValue("styleGroupAsTag");
  158. }
  159.  
  160. if (compareVersion("0.8.0")) {
  161. GM_deleteValue("useChromeSettings");
  162. }
  163. if (compareVersion("0.9.0")) {
  164. GM_deleteValue("respectTags");
  165. }
  166. if (compareVersion("1.2.3")) {
  167. GM_setValue("settingsLinkLocation",2);
  168. }
  169.  
  170. getSettings();
  171.  
  172. GM_setValue("version","2.0.15");
  173.  
  174. // The settings page save button and right click menu prime the data for storage first, then recall this function with a new origin to actually store it.
  175. function saveSettings (origin,username,listIndex,addOrRemove) {
  176. var smashedUsernames;
  177. var smashedActions;
  178. var smashedFullList = new Array();
  179. var smashedAllOfTheThings = new Array();
  180. if (origin == "import") {
  181. var importField = document.getElementById("exportImportField");
  182. var importString = importField.value;
  183. if (importString.split("|").length <= 3) {
  184. if (!confirm("This data seems malformed and may break your settings.\nImport data anyway?")) {
  185. throw "Abort settings import.";
  186. }
  187. }
  188. GM_setValue("Main Settings",importString);
  189. GM_setValue("numberOfLists",importString.split("^").length);
  190. }
  191. if (origin == "internal") {
  192. for (var i = 0; i < storedNumberOfLists; i++) {
  193. smashedUsernames = storedUsernames[i].join(",");
  194. smashedActions = storedActionHighlightTopic[i]+","+storedActionIgnoreTopic[i]+","+storedActionHighlightPost[i]+","+storedActionIgnorePost[i]+","+storedActionTagTopic[i]+","+storedActionTagPost[i]+","+storedActionHighlightTopicContent[i]+","+storedActionIgnoreTopicContent[i]+","+storedActionHighlightPostContent[i]+","+storedActionIgnorePostContent[i]+","+storedActionAllowStacking[i]+","+storedActionHighlightAdmin[i]+","+storedActionHighlightMod[i]+","+storedActionHighlightVIP[i]+","+storedActionHighlightTC[i];
  195. smashedFullList[i] = storedListNames[i]+"|"+smashedUsernames+"|"+storedHighlightColours[i]+"|"+storedHighlightTextColours[i]+"|"+smashedActions;
  196. }
  197. smashedAllOfTheThings = smashedFullList.join("^");
  198. GM_setValue("Main Settings",smashedAllOfTheThings);
  199. var importField = document.getElementById("exportImportField");
  200. if (importField){
  201. importField.setAttribute('value',smashedAllOfTheThings);
  202. }
  203. }
  204. if (origin == "rightclickmenu") {
  205. if (addOrRemove == "add") {
  206. storedUsernames[listIndex][storedUsernames[listIndex].length] = username;
  207. }
  208. if (addOrRemove == "remove") {
  209. storedUsernames[listIndex].splice(storedUsernames[listIndex].indexOf(username),1);
  210. }
  211. saveSettings("internal");
  212. }
  213. if (origin == "settingspage") {
  214. var lists = document.evaluate('//div', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  215. var actionLists = document.evaluate('//input[@type="checkbox"]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  216. var realLists = 0;
  217. for (var i = 0; i < lists.snapshotLength; i++) {
  218. if (lists.snapshotItem(i).getAttribute("class") !== "container") {
  219. continue; // Fuck you, Chrome >_>
  220. }
  221. storedListNames[realLists] = lists.snapshotItem(i).getElementsByClassName("listnameFields")[0].value;
  222. storedHighlightColours[realLists] = lists.snapshotItem(i).getElementsByClassName("colourFields")[0].value;
  223. storedHighlightTextColours[realLists] = lists.snapshotItem(i).getElementsByClassName("textColourFields")[0].value;
  224. storedUsernames[realLists] = lists.snapshotItem(i).getElementsByClassName("usernameFields")[0].value.replace(/, /g,",").split(",");
  225. storedActionHighlightTopic[realLists] = actionLists.snapshotItem(realLists*15).checked;
  226. storedActionIgnoreTopic[realLists] = actionLists.snapshotItem(realLists*15+1).checked;
  227. storedActionHighlightPost[realLists] = actionLists.snapshotItem(realLists*15+2).checked;
  228. storedActionIgnorePost[realLists] = actionLists.snapshotItem(realLists*15+3).checked;
  229. storedActionTagTopic[realLists] = actionLists.snapshotItem(realLists*15+4).checked;
  230. storedActionTagPost[realLists] = actionLists.snapshotItem(realLists*15+5).checked;
  231. storedActionHighlightTopicContent[realLists] = actionLists.snapshotItem(realLists*15+6).checked;
  232. storedActionIgnoreTopicContent[realLists] = actionLists.snapshotItem(realLists*15+7).checked;
  233. storedActionHighlightPostContent[realLists] = actionLists.snapshotItem(realLists*15+8).checked;
  234. storedActionIgnorePostContent[realLists] = actionLists.snapshotItem(realLists*15+9).checked;
  235. storedActionAllowStacking[realLists] = actionLists.snapshotItem(realLists*15+10).checked;
  236. storedActionHighlightAdmin[realLists] = actionLists.snapshotItem(realLists*15+11).checked;
  237. storedActionHighlightMod[realLists] = actionLists.snapshotItem(realLists*15+12).checked;
  238. storedActionHighlightVIP[realLists] = actionLists.snapshotItem(realLists*15+13).checked;
  239. storedActionHighlightTC[realLists] = actionLists.snapshotItem(realLists*15+14).checked;
  240. realLists++;
  241. }
  242. GM_setValue("numberOfLists",realLists);
  243. // Straggler settings not part of a loop
  244. GM_setValue("caseInsensitive",document.getElementById("caseInsensitiveToggle").checked);
  245. GM_setValue("useColouredCustomCSS",document.getElementById("customCSSToggle").checked);
  246. GM_setValue("settingsLinkLocation",parseInt(document.getElementById("settingsLinkLocation").value));
  247. GM_setValue("styleGroupAsTag",document.getElementById("styleGroupAsTagToggle").checked);
  248. saveSettings("internal");
  249. }
  250. }
  251.  
  252. function makeInsensitive (voodoo) {
  253. if (storedCaseInsensitive) {
  254. return voodoo.toLowerCase();
  255. } else {
  256. return voodoo;
  257. }
  258. }
  259.  
  260. // Always returns in rgba, prefilling an alpha of '1' if none was present.
  261. // Accepts #RRGGBB, rgba(r,g,b,a), or rgb(r,g,b).
  262. function decimalColour (colour, returnAs) {
  263. // The usual #RRGGBB you expect to deal with from user input.
  264. if (colour.substring(0,1) == "#") {
  265. if (returnAs === "style") {
  266. return ("rgba("+parseInt(colour.substring(1,3),16)+","+parseInt(colour.substring(3,5),16)+","+parseInt(colour.substring(5,7),16)+",1)");
  267. } else if (returnAs === "testvalue") {
  268. return true;
  269. } else {
  270. return [parseInt(colour.substring(1,3),16),parseInt(colour.substring(3,5),16),parseInt(colour.substring(5,7),16),1];
  271. }
  272. } else {
  273. // And now for when rgba(r,g,b,a) and rgb(r,g,b) decide to show up, like when pulling the colour directly out of the DOM. >_>
  274. if (colour.substring(0,4) == "rgba") {
  275. var numbersOnly = colour.substring(5,colour.length-1).replace(/, /g,",").split(",");
  276. if (returnAs === "style") {
  277. return ("rgba("+numbersOnly[0]+","+numbersOnly[1]+","+numbersOnly[2]+","+numbersOnly[3]+")");
  278. } else if (returnAs === "testvalue") {
  279. return true;
  280. } else {
  281. return numbersOnly;
  282. }
  283. } else if (colour.substring(0,4) == "rgb(") {
  284. var numbersOnly = colour.substring(4,colour.length-1).replace(/, /g,",").split(",");
  285. if (returnAs === "style") {
  286. return ("rgba("+numbersOnly[0]+","+numbersOnly[1]+","+numbersOnly[2]+",1)");
  287. } else if (returnAs === "testvalue") {
  288. return true;
  289. } else {
  290. numbersOnly[3] = 1;
  291. return numbersOnly;
  292. }
  293. } else if (returnAs === "testvalue") {
  294. return false;
  295. }
  296. }
  297. }
  298.  
  299. function autoContrast (pageType,colour,usernameNode) {
  300. var backgroundColour = decimalColour(colour);
  301. if (!decimalColour(colour,"testvalue")) {
  302. return false;
  303. }
  304. //todo: Check new site colours, update switch values. These are probably wrong.
  305. switch (theme) {
  306. case "red": var themeColour = decimalColour("#7E2525"); break;
  307. case "green": var themeColour = decimalColour("#669E2E"); break;
  308. case "orange": var themeColour = decimalColour("#834121"); break;
  309. case "purple": var themeColour = decimalColour("#330066"); break;
  310. case "cloudy": var themeColour = decimalColour("#192457"); break;
  311. case "sepia": var themeColour = decimalColour("#6C4013"); break;
  312. case "dark-blue": var themeColour = decimalColour("#A1AFF7"); break;
  313. case "dark-red": var themeColour = decimalColour("#F9B8B8"); break;
  314. case "dark-green": var themeColour = decimalColour("#CCF7A1"); break;
  315. case "dark-orange": var themeColour = decimalColour("#FFCCB3"); break;
  316. case "dark-purple": var themeColour = decimalColour("#E5CCFF"); break;
  317. case "grayscale": var themeColour = decimalColour("#404040"); break;
  318. case "cottoncandy": var themeColour = decimalColour("#FF0000"); break;
  319. default: var themeColour = decimalColour("#3449B2");
  320. }
  321. if (storedUseColouredCustomCSSSetting) {
  322. themeColour = decimalColour(window.getComputedStyle(usernameNode).getPropertyValue("color"));
  323. }
  324. // http://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html
  325. // http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
  326. var lumiCustom = (0.2126*backgroundColour[0] + 0.7152*backgroundColour[1] + 0.0722*backgroundColour[2])/256;
  327. var lumiDefault =(0.2126*themeColour[0] + 0.7152*themeColour[1] + 0.0722*themeColour[2])/256;
  328. if (lumiCustom >= lumiDefault) {
  329. var contrastRatio = (lumiCustom + 0.05) / (lumiDefault + 0.05);
  330. } else {
  331. var contrastRatio = (lumiDefault + 0.05) / (lumiCustom + 0.05);
  332. }
  333. // If the contrast is awful, we need to replace the text colour.
  334. var themeBrightness = ((themeColour[0]*299) + (themeColour[1]*587) + (themeColour[2]*114)) / 255000;
  335. if ((contrastRatio <= 3.5) || ((contrastRatio > 3.5) && (lumiCustom <= 0.03) && (themeBrightness <= 0.5))) {
  336. // http://stackoverflow.com/a/9664560
  337. var brightness = ((backgroundColour[0]*299) + (backgroundColour[1]*587) + (backgroundColour[2]*114)) / 255000;
  338. // First return is "do we even need to attach styles to text?", second is link colour, and third is plain text.
  339. // I make links "brighter" than the plain text it's next to using the alpha channel.
  340. if (brightness >= 0.5) {
  341. return([true,"rgba(0,0,0,0.8)","rgba(0,0,0,1)","gamecats-autocontrast-black"]);
  342. } else {
  343. return([true,"rgba(256,256,256,1)","rgba(256,256,256,0.8)","gamecats-autocontrast-white"]);
  344. }
  345. } else {
  346. return([false]);
  347. }
  348. }
  349.  
  350. function textHighlight (pageType,tr,usernameNode,colour,textColour,currentStyles) {
  351. // Don't do anything if the field was left blank.
  352. if (textColour !== "") {
  353. if (pageType == "messagelist") {
  354. var postInfo = tr.childNodes[0].childNodes[0];
  355. } else {
  356. var postInfo = tr;
  357. }
  358. var plainTextColour = textColour;
  359. var postInfoLinks = postInfo.getElementsByTagName("a");
  360. var postInfoSpans = postInfo.getElementsByTagName("span");
  361. var catchResults = new Array();
  362. // Check for auto and break out early if we decide we don't need it.
  363. if (textColour == "auto" || textColour == "automatic" || textColour == "automagic" ) {
  364. catchResults = autoContrast(pageType,colour,usernameNode);
  365. if (catchResults[0]) {
  366. textColour = catchResults[1];
  367. plainTextColour = catchResults[2];
  368. } else {
  369. return(false);
  370. }
  371. }
  372. postInfo.setAttribute("class",(postInfo.getAttribute("class")||"")+" gamecats-text gamecats-text-tr "+(catchResults[3]||""));
  373. // If people are stacking styles, we need to replace text colours without blowing up the existing CSS.
  374. var isStyled = false;
  375. for (var i = 0; i < currentStyles.length; i++) {
  376. if (currentStyles[i].indexOf(" color:") != -1) {
  377. isStyled = true;
  378. currentStyles[i] = " color:"+plainTextColour+"!important;";
  379. postInfo.setAttribute("style",currentStyles.join(";"));
  380. break;
  381. }
  382. }
  383. // And if there was no text colour already, just toss one on at the end.
  384. if (!isStyled) {
  385. postInfo.setAttribute("style",(postInfo.getAttribute("style")||"")+" color:"+plainTextColour+"!important;");
  386. }
  387. for (var i = 0; i < postInfoLinks.length; i++) {
  388. if ((postInfoLinks[i].parentNode.nodeName != "LI") && (postInfoLinks[i].parentNode.nodeName != "FORM")) {
  389. postInfoLinks[i].setAttribute("class",(postInfoLinks[i].getAttribute("class")||"")+" gamecats-text gamecats-text-a "+(catchResults[3]||""));
  390. postInfoLinks[i].setAttribute("style","color:"+textColour+"!important;");
  391. }
  392. }
  393. for (var i = 0; i < postInfoSpans.length; i++) {
  394. if ((postInfoSpans[i].getAttribute("class")||"").indexOf("tag") == -1) {
  395. postInfoSpans[i].setAttribute("class",(postInfoSpans[i].getAttribute("class")||"")+" gamecats-text gamecats-text-span "+(catchResults[3]||""));
  396. postInfoSpans[i].setAttribute("style","color:"+textColour+"!important;");
  397. }
  398. }
  399. }
  400. }
  401.  
  402. function highlight (mode,pageType,usernameNode,listName,colour,textColour,topicHighlight,topicIgnore,messageHighlight,messageIgnore,topicListName,messageListName,topicContentHighlight,topicContentIgnore,postContentHighlight,postContentIgnore,allowStacking) {
  403. if (decimalColour(colour,"testvalue")) {
  404. var appendType = "background-color:";
  405. } else {
  406. var appendType = "background-image:";
  407. }
  408. if (pageType == "topiclist") {
  409. var tr = usernameNode.parentNode.parentNode;
  410. if (usernameNode.parentNode.nodeName == "SPAN") { // Stickies still don't have spans
  411. tr = tr.parentNode;
  412. }
  413. var td = tr.childNodes;
  414. if (((tr.getAttribute("class").indexOf("gamecats-highlight") == -1) || (allowStacking)) && ((topicHighlight && !topicIgnore) || (mode == "contentMatch" && topicContentHighlight && !topicContentIgnore))) {
  415. var currentStyles = (tr.getAttribute("style")||"").split(";");
  416. var isStyled = false;
  417. if (allowStacking) {
  418. for (var i = 0; i < currentStyles.length; i++) {
  419. if (currentStyles[i].indexOf(appendType) != -1) {
  420. isStyled = true;
  421. currentStyles[i] = appendType+colour+", "+currentStyles[i].substring(17);
  422. tr.setAttribute("style",currentStyles.join(";"));
  423. break;
  424. }
  425. }
  426. }
  427. if (!isStyled) {
  428. tr.setAttribute("style",(tr.getAttribute("style")||"")+appendType+colour+";");
  429. currentStyles = (tr.getAttribute("style")||"").split(";");
  430. }
  431. tr.setAttribute("class",(tr.getAttribute("class")||"")+" friend gamecats-highlight gamecats-highlight-topic-tr")
  432. textHighlight(pageType,tr,usernameNode,colour,textColour,currentStyles);
  433. for (var i = 0; i < td.length; i++) {
  434. td[i].setAttribute("style","background-color: transparent; background-image: none;");
  435. td[i].setAttribute("class",(td[i].getAttribute("class")||"")+" friend gamecats-highlight gamecats-highlight-topic-td")
  436. }
  437. }
  438. if (topicListName) {
  439. if (usernameNode.parentNode.nodeName == "SPAN") { // Stickies don't have spans
  440. var existingList = usernameNode.parentNode.nextSibling;
  441. if (existingList) {
  442. existingList.textContent = " "+listName+existingList.textContent;
  443. } else {
  444. var newList = usernameNode.parentNode.parentNode.appendChild(document.createTextNode(" "+listName));
  445. }
  446. } else {
  447. var existingList = usernameNode.nextSibling;
  448. if (existingList) {
  449. existingList.textContent = " "+listName+existingList.textContent;
  450. } else {
  451. var newList = usernameNode.parentNode.appendChild(document.createTextNode(" "+listName));
  452. }
  453. }
  454.  
  455. }
  456. if (((mode == "usernameMatch" || mode == "tagMatch") && topicIgnore) || (mode == "contentMatch" && topicContentIgnore)) {
  457. tr.parentNode.removeChild(tr);
  458. }
  459. }
  460. if (pageType == "messagelist") {
  461. // Adding group names
  462. if (messageListName) {
  463. var existingList = usernameNode.parentNode.parentNode.nextSibling;
  464. if (!storedStyleGroupAsTagSetting) {
  465. if (existingList) {
  466. existingList.textContent = " "+listName+existingList.textContent;
  467. } else {
  468. var newListSpan = usernameNode.parentNode.parentNode.appendChild(document.createElement("span"));
  469. newListSpan.setAttribute("class","user_info");
  470. var newList = newListSpan.appendChild(document.createTextNode(" "+listName));
  471. }
  472. } else {
  473. var newTagSpan = usernameNode.parentNode.parentNode.parentNode.insertBefore(document.createElement("span"),usernameNode.parentNode.parentNode.nextSibling);
  474. var whitespace = usernameNode.parentNode.parentNode.parentNode.insertBefore(document.createTextNode(" "),usernameNode.parentNode.parentNode.nextSibling);
  475. newTagSpan.textContent = listName;
  476. newTagSpan.setAttribute("class","tag newbeta");
  477. }
  478. }
  479. var tr = usernameNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode;
  480. var div = tr.childNodes[0].childNodes[0];
  481. if ((((tr.getAttribute("class")||"").indexOf("gamecats-highlight") == -1) || (allowStacking)) && (((mode == "usernameMatch" || mode == "tagMatch") && messageHighlight && !messageIgnore) || (mode == "contentMatch" && postContentHighlight && !postContentIgnore))) {
  482. var currentStyles = (div.getAttribute("style")||"").split(";");
  483. var isStyled = false;
  484. if (allowStacking) {
  485. for (var i = 0; i < currentStyles.length; i++) {
  486. if (currentStyles[i].indexOf(appendType) != -1) {
  487. isStyled = true;
  488. currentStyles[i] = appendType+colour+", "+currentStyles[i].substring(17);
  489. div.setAttribute("style",currentStyles.join(";"));
  490. break;
  491. }
  492. }
  493. }
  494. if (!isStyled) {
  495. div.setAttribute("style",(div.getAttribute("style")||"")+appendType+colour+";");
  496. currentStyles = (tr.getAttribute("style")||"").split(";");
  497. }
  498. tr.setAttribute("class",(tr.getAttribute("class")||"")+" friend gamecats-highlight gamecats-highlight-message-tr");
  499. div.setAttribute("class",(div.getAttribute("class")||"")+" friend gamecats-highlight gamecats-highlight-message-div");
  500. textHighlight(pageType,tr,usernameNode,colour,textColour,currentStyles);
  501. }
  502. if (((mode == "usernameMatch" || mode == "tagMatch") && messageIgnore) || (mode == "contentMatch" && postContentIgnore)) {
  503. if (tr.parentNode) {
  504. tr.parentNode.removeChild(tr);
  505. }
  506. }
  507. }
  508. }
  509.  
  510. // Finding usernames, looking for tags, etc
  511. var pageType;
  512. var authorTDs;
  513. var titlePostContent;
  514. var userTagsContent;
  515. var topicList = document.evaluate('//table[contains(@class,"board topics tlist newbeta")]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
  516. if (topicList !== null) {
  517. authorTDs = document.evaluate('//td[contains(@class,"tauthor")]//a', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  518. pageType = "topiclist";
  519. }
  520.  
  521. var messageList = document.evaluate('//table[contains(@class,"board message")]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
  522. if (messageList !== null) {
  523. authorTDs = document.evaluate('//td[contains(@class,"msg")]//div[@class="post_author"]//b', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  524. pageType = "messagelist";
  525. }
  526.  
  527. if (topicList !== null || messageList !== null) {
  528. for (var k = 0; k < authorTDs.snapshotLength; k++) {
  529. authorTDs.snapshotItem(k).isAdmin = false;
  530. authorTDs.snapshotItem(k).isMod = false;
  531. authorTDs.snapshotItem(k).isVIP = false;
  532. authorTDs.snapshotItem(k).isTC = false;
  533. // Content highlight setup
  534. titlePostContent = authorTDs.snapshotItem(k);
  535. while (titlePostContent.nodeName != "TR") {
  536. titlePostContent = titlePostContent.parentNode;
  537. }
  538. if (pageType == "topiclist") {
  539. titlePostContent = titlePostContent.getElementsByTagName("td")[1].textContent;
  540. } else {
  541. titlePostContent = titlePostContent.childNodes[0].childNodes[1].textContent;
  542. }
  543. // Tag highlight setup
  544. userTagsContent = authorTDs.snapshotItem(k);
  545. if (pageType == "messagelist") {
  546. while (userTagsContent.getAttribute("class") != "msg_infobox") {
  547. userTagsContent = userTagsContent.parentNode;
  548. }
  549. userTagsContent = userTagsContent.getElementsByClassName("user_info")[0];
  550. if (userTagsContent) {
  551. userTagsContent = userTagsContent.textContent;
  552. }
  553. // Make sure we don't forget the first post in a topic, since it doesn't get the (Topic Creator) tag
  554. if ((k == 0) || (k == authorTDs.snapshotLength-1)) {
  555. var anchors = authorTDs.snapshotItem(k).parentNode.parentNode.parentNode.parentNode.getElementsByTagName("a");
  556. if (anchors[0].getAttribute("name") == "1") {
  557. authorTDs.snapshotItem(k).isTC = true;
  558. }
  559. }
  560. } else {
  561. while (userTagsContent.nodeName != "TD") {
  562. userTagsContent = userTagsContent.parentNode;
  563. }
  564. if (userTagsContent.childNodes[1]) {
  565. userTagsContent = userTagsContent.childNodes[1].textContent;
  566. }
  567. }
  568. if (typeof userTagsContent == "string") {
  569. if ((userTagsContent.indexOf("(A)") != -1) || (userTagsContent.indexOf("(Admin)") != -1)) {
  570. authorTDs.snapshotItem(k).isAdmin = true;
  571. }
  572. if ((userTagsContent.indexOf("(M)") != -1) || (userTagsContent.indexOf("(Moderator)") != -1) || (userTagsContent.indexOf("(Lead Moderator)") != -1)) {
  573. authorTDs.snapshotItem(k).isMod = true;
  574. }
  575. if ((userTagsContent.indexOf("(V)") != -1) || (userTagsContent.indexOf("(VIP)") != -1)) { // Not sure if these are the right strings to be looking for, haven't found a VIP to compare against.
  576. authorTDs.snapshotItem(k).isVIP = true;
  577. }
  578. if (userTagsContent.indexOf("(Topic Creator)") != -1) {
  579. authorTDs.snapshotItem(k).isTC = true;
  580. }
  581. }
  582. // Normal stuff
  583. for (var i = 0; i < storedNumberOfLists; i++) {
  584. for (var j = 0; j < storedUsernames[i].length; j++) {
  585. // Standard username match check
  586. if ((pageType == "topiclist" && (storedActionHighlightTopic[i] || storedActionIgnoreTopic[i])) || (pageType != "topiclist" && (storedActionHighlightPost[i] || storedActionIgnorePost[i]))) {
  587. if (authorTDs.snapshotItem(k).textContent == storedUsernames[i][j]) {
  588. highlight("usernameMatch",pageType,authorTDs.snapshotItem(k),storedListNames[i],storedHighlightColours[i],storedHighlightTextColours[i],storedActionHighlightTopic[i], storedActionIgnoreTopic[i], storedActionHighlightPost[i], storedActionIgnorePost[i], storedActionTagTopic[i], storedActionTagPost[i], storedActionHighlightTopicContent[i], storedActionIgnoreTopicContent[i], storedActionHighlightPostContent[i], storedActionIgnorePostContent[i], storedActionAllowStacking[i]);
  589. }
  590. }
  591. // Content-based highlighting check
  592. if ((pageType == "topiclist" && (storedActionHighlightTopicContent[i] || storedActionIgnoreTopicContent[i])) || (pageType != "topiclist" && (storedActionHighlightPostContent[i] || storedActionIgnorePostContent[i]))) {
  593. if (makeInsensitive(titlePostContent).indexOf(makeInsensitive(storedUsernames[i][j])) != -1) {
  594. highlight("contentMatch",pageType,authorTDs.snapshotItem(k),storedListNames[i],storedHighlightColours[i],storedHighlightTextColours[i],storedActionHighlightTopic[i], storedActionIgnoreTopic[i], storedActionHighlightPost[i], storedActionIgnorePost[i], storedActionTagTopic[i], storedActionTagPost[i], storedActionHighlightTopicContent[i], storedActionIgnoreTopicContent[i], storedActionHighlightPostContent[i], storedActionIgnorePostContent[i], storedActionAllowStacking[i]);
  595. }
  596. }
  597. // Tag checks, admin, tc, etc.
  598. if ((storedActionHighlightAdmin[i] && authorTDs.snapshotItem(k).isAdmin) || (storedActionHighlightMod[i] && authorTDs.snapshotItem(k).isMod) || (storedActionHighlightVIP[i] && authorTDs.snapshotItem(k).isVIP) || (storedActionHighlightTC[i] && authorTDs.snapshotItem(k).isTC)) {
  599. highlight("tagMatch",pageType,authorTDs.snapshotItem(k),storedListNames[i],storedHighlightColours[i],storedHighlightTextColours[i],storedActionHighlightTopic[i], storedActionIgnoreTopic[i], storedActionHighlightPost[i], storedActionIgnorePost[i], storedActionTagTopic[i], storedActionTagPost[i], storedActionHighlightTopicContent[i], storedActionIgnoreTopicContent[i], storedActionHighlightPostContent[i], storedActionIgnorePostContent[i], storedActionAllowStacking[i]);
  600. }
  601. // Setting up for the right click menu
  602. authorTDs.snapshotItem(k).setAttribute("contextmenu", "gamecats-menu");
  603. authorTDs.snapshotItem(k).addEventListener("contextmenu", readyMenu, false);
  604. }
  605. }
  606. }
  607. }
  608.  
  609. /*******************\
  610. * Right click menu! *
  611. \*******************/
  612.  
  613. function readyMenu (rightClick) {
  614. getSettings();
  615. // Killing old menu entries so the list doesn't pile up or refuse to refresh with new content
  616. var oldMenu = document.getElementById("gamecats-menu");
  617. if (oldMenu) {
  618. oldMenu.parentNode.removeChild(oldMenu);
  619. }
  620. var mainMenu = document.body.appendChild(document.createElement("menu"));
  621. var mainMenuLabel = mainMenu.appendChild(document.createElement("menu"));
  622. mainMenu.setAttribute("id","gamecats-menu");
  623. mainMenu.setAttribute("type","context");
  624. mainMenuLabel.setAttribute("label","GameCATs Highlighting");
  625. var node = rightClick.target;
  626. var clickedUsername = node.textContent;
  627. var menuItems = new Array();
  628. for (var i = 0; i < storedNumberOfLists; i++) {
  629. menuItems[i] = document.createElement("menuitem");
  630. menuItems[i].setAttribute("label",storedListNames[i]);
  631. menuItems[i].setAttribute("type","checkbox");
  632. menuItems[i].setAttribute("value",i);
  633. mainMenuLabel.appendChild(menuItems[i]);
  634. // Check the box if already listed, and use the "remove" option
  635. if (storedUsernames[i].indexOf(clickedUsername) != -1) {
  636. menuItems[i].setAttribute("checked","true");
  637. menuItems[i].addEventListener("click", function() {saveSettings("rightclickmenu",clickedUsername,this.getAttribute("value"),"remove");}, false);
  638. } else {
  639. menuItems[i].addEventListener("click", function() {saveSettings("rightclickmenu",clickedUsername,this.getAttribute("value"),"add");}, false);
  640. }
  641. }
  642. }
  643.  
  644. /*********************************\
  645. * Time to create a settings page! *
  646. \*********************************/
  647.  
  648. function createSettingsPage () {
  649. // Styyyyyle!
  650. var style = document.createElement("style");
  651. style.textContent = '.container { clear:both; } .priorityButtons, .deleteButtons { display: block; } .usernameFields { height: 160px; width: 447px; } span {float: left;} span:nth-child(2) {clear: left;} label.actionLabels:nth-child(2):after {content: "Highlight/Ignore in Topic List\\00000A"; white-space: pre;} label.actionLabels:nth-child(4):after {content: "Highlight/Ignore in Message List\\00000A"; white-space: pre;} label.actionLabels:nth-child(6):after {content: "Add group name in Topic/Message List\\00000A"; white-space: pre;} label.actionLabels:nth-child(8):after {content: "Highlight/Ignore content in Topic List\\00000A"; white-space: pre;} label.actionLabels:nth-child(10):after {content: "Highlight/Ignore content in Message List\\00000A"; white-space: pre;} label.actionLabels:nth-child(11):after {content: "Allow stacking\\00000A"; white-space: pre;} label.actionLabels:nth-child(15):after {content: "Target Admins/Mods/VIPs/TCs\\00000A"; white-space: pre;} label.caseInsensitiveToggle, label.customCSSToggle, label.settingsLinkLocation { clear:both; display: block;} label.caseInsensitiveToggle:after {content: "Ignore case sensitivity on content matches";} label.customCSSToggle:after {content: "Using CSS with custom colours";} label.styleGroupAsTagToggle:after {content: "Style groups as GameFAQs tags";} label.settingsLinkLocation:before {content: "Settings link location: "} .exportImportLabel:before {content: "\\00000A Import/Export: "; white-space: pre;}';
  652. document.getElementsByTagName("head")[0].appendChild(style);
  653. // Creating all the variables I'll need for the upcoming loop.
  654. var body = document.getElementsByTagName("body")[0];
  655. var container = new Array();
  656. var listname = new Array();
  657. var listnameFields = new Array();
  658. var username = new Array();
  659. var usernameFields = new Array();
  660. var colour = new Array();
  661. var colourFields = new Array();
  662. var textColour = new Array();
  663. var textColourFields = new Array();
  664. var action = new Array();
  665. var actionFields = new Array();
  666. var labels = new Array();
  667. var deleteButtons = new Array();
  668. var priorityButtons = new Array();
  669. var spans = new Array();
  670. // Creating a bunch of input fields for each highlight list.
  671. for (var i = 0; i < storedNumberOfLists; i++) {
  672. // Wrap each entry in its own div, for easy location of children and deletion.
  673. container[i] = document.createElement('div');
  674. container[i].setAttribute('id','container'+i);
  675. container[i].setAttribute('class','container');
  676. body.appendChild(container[i]);
  677. // Pairing a few other things in spans for the sake of styling.
  678. spans[i,0] = document.createElement('span');
  679. spans[i,1] = document.createElement('span');
  680. spans[i,2] = document.createElement('span');
  681. spans[i,3] = document.createElement('span');
  682. container[i].appendChild(spans[i,0]);
  683. container[i].appendChild(spans[i,1]);
  684. container[i].appendChild(spans[i,2]);
  685. container[i].appendChild(spans[i,3]);
  686. // List name, for user organizition or if you choose to let the name of said list show next to usernames.
  687. listnameFields[i] = document.createElement('input');
  688. listnameFields[i].setAttribute('type','text');
  689. listnameFields[i].setAttribute('id','listnameFields'+i);
  690. listnameFields[i].setAttribute('class','listnameFields');
  691. listnameFields[i].setAttribute('placeholder','Group Name');
  692. listnameFields[i].setAttribute('value',storedListNames[i]);
  693. spans[i,0].appendChild(listnameFields[i]);
  694. // The colour to change the background to when a username is matched with one on the list.
  695. colourFields[i] = document.createElement('input');
  696. colourFields[i].setAttribute('type','text');
  697. colourFields[i].setAttribute('id','colourFields'+i);
  698. colourFields[i].setAttribute('class','colourFields');
  699. colourFields[i].setAttribute('placeholder','Background Colour');
  700. colourFields[i].setAttribute('value',storedHighlightColours[i]);
  701. spans[i,0].appendChild(colourFields[i]);
  702. // The colour to change text to when a username is matched with one on the list.
  703. textColourFields[i] = document.createElement('input');
  704. textColourFields[i].setAttribute('type','text');
  705. textColourFields[i].setAttribute('id','textColourFields'+i);
  706. textColourFields[i].setAttribute('class','textColourFields');
  707. textColourFields[i].setAttribute('placeholder','Text Colour (optional)');
  708. textColourFields[i].setAttribute('value',storedHighlightTextColours[i]);
  709. spans[i,0].appendChild(textColourFields[i]);
  710. // Username lists.
  711. usernameFields[i] = document.createElement('textarea');
  712. usernameFields[i].textContent = storedUsernames[i].join(",");
  713. usernameFields[i].setAttribute('id','usernameFields'+i);
  714. usernameFields[i].setAttribute('class','usernameFields');
  715. usernameFields[i].setAttribute('placeholder','Usernames and/or post content to match, case sensitive.');
  716. spans[i,1].appendChild(usernameFields[i]);
  717. // Actions to perform when we find a match, or special matching conditions
  718. for (var j = 0; j < 15; j++) {
  719. labels[i*15+j] = document.createElement('label');
  720. labels[i*15+j].setAttribute('class','actionLabels');
  721. actionFields[i*15+j] = document.createElement('input');
  722. actionFields[i*15+j].setAttribute('type','checkbox');
  723. actionFields[i*15+j].setAttribute('id','actionFields'+(i*15+j));
  724. actionFields[i*15+j].setAttribute('class','actionFields');
  725. spans[i,2].appendChild(labels[i*15+j]);
  726. labels[i*15+j].appendChild(actionFields[i*15+j]);
  727. }
  728. // Pre-check the boxes only if the setting is already present.
  729. if (storedActionHighlightTopic[i] === true) {
  730. actionFields[i*15].setAttribute('checked','');
  731. }
  732. if (storedActionIgnoreTopic[i] === true) {
  733. actionFields[i*15+1].setAttribute('checked','');
  734. }
  735. if (storedActionHighlightPost[i] === true) {
  736. actionFields[i*15+2].setAttribute('checked','');
  737. }
  738. if (storedActionIgnorePost[i] === true) {
  739. actionFields[i*15+3].setAttribute('checked','');
  740. }
  741. if (storedActionTagTopic[i] === true) {
  742. actionFields[i*15+4].setAttribute('checked','');
  743. }
  744. if (storedActionTagPost[i] === true) {
  745. actionFields[i*15+5].setAttribute('checked','');
  746. }
  747. if (storedActionHighlightTopicContent[i] === true) {
  748. actionFields[i*15+6].setAttribute('checked','');
  749. }
  750. if (storedActionIgnoreTopicContent[i] === true) {
  751. actionFields[i*15+7].setAttribute('checked','');
  752. }
  753. if (storedActionHighlightPostContent[i] === true) {
  754. actionFields[i*15+8].setAttribute('checked','');
  755. }
  756. if (storedActionIgnorePostContent[i] === true) {
  757. actionFields[i*15+9].setAttribute('checked','');
  758. }
  759. if (storedActionAllowStacking[i] === true) {
  760. actionFields[i*15+10].setAttribute('checked','');
  761. }
  762. if (storedActionHighlightAdmin[i] === true) {
  763. actionFields[i*15+11].setAttribute('checked','');
  764. }
  765. if (storedActionHighlightMod[i] === true) {
  766. actionFields[i*15+12].setAttribute('checked','');
  767. }
  768. if (storedActionHighlightVIP[i] === true) {
  769. actionFields[i*15+13].setAttribute('checked','');
  770. }
  771. if (storedActionHighlightTC[i] === true) {
  772. actionFields[i*15+14].setAttribute('checked','');
  773. }
  774. // Priority buttons, to move this div to the top.
  775. priorityButtons[i] = document.createElement('input');
  776. priorityButtons[i].setAttribute('id','priorityButtons'+i);
  777. priorityButtons[i].setAttribute('class','priorityButtons');
  778. priorityButtons[i].setAttribute('type','button');
  779. priorityButtons[i].setAttribute('value','Send To Top');
  780. priorityButtons[i].addEventListener('click',function() {this.parentNode.parentNode.parentNode.insertBefore(this.parentNode.parentNode,this.parentNode.parentNode.parentNode.childNodes[0]);},true);
  781. spans[i,3].appendChild(priorityButtons[i]);
  782. // Delete buttons, to trash the whole containing div.
  783. deleteButtons[i] = document.createElement('input');
  784. deleteButtons[i].setAttribute('id','deleteButtons'+i);
  785. deleteButtons[i].setAttribute('class','deleteButtons');
  786. deleteButtons[i].setAttribute('type','button');
  787. deleteButtons[i].setAttribute('value','Delete');
  788. deleteButtons[i].addEventListener('click',function() {this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode);},true);
  789. spans[i,3].appendChild(deleteButtons[i]);
  790. }
  791. // Done with all the looping junk, now for the ever-important "save settings" and "new list" buttons.
  792. function newList() {
  793. GM_setValue("numberOfLists",GM_getValue("numberOfLists")+1);
  794. GM_setValue("Main Settings",GM_getValue("Main Settings")+"^||||false,false,false,false,false,false,false,false,false,false,false");
  795. // The anchor set here gets watched on page load to automatically reopen the settings page.
  796. window.location.href = window.location.href.split("#")[0]+"#ReloadHighlightSettings";
  797. location.reload();
  798. }
  799. var caseInsensitiveToggle = [document.createElement('label'),document.createElement('input')];
  800. caseInsensitiveToggle[1].setAttribute('type','checkbox');
  801. caseInsensitiveToggle[1].setAttribute('id','caseInsensitiveToggle');
  802. caseInsensitiveToggle[0].setAttribute('class','caseInsensitiveToggle');
  803. caseInsensitiveToggle[1].setAttribute('class','caseInsensitiveToggle');
  804. if (storedCaseInsensitive == true) {
  805. caseInsensitiveToggle[1].setAttribute('checked','');
  806. }
  807. body.appendChild(caseInsensitiveToggle[0]);
  808. caseInsensitiveToggle[0].appendChild(caseInsensitiveToggle[1]);
  809. var customCSSToggle = [document.createElement('label'),document.createElement('input')];
  810. customCSSToggle[1].setAttribute('type','checkbox');
  811. customCSSToggle[1].setAttribute('id','customCSSToggle');
  812. customCSSToggle[0].setAttribute('class','customCSSToggle');
  813. customCSSToggle[1].setAttribute('class','customCSSToggle');
  814. if (storedUseColouredCustomCSSSetting == true) {
  815. customCSSToggle[1].setAttribute('checked','');
  816. }
  817. body.appendChild(customCSSToggle[0]);
  818. customCSSToggle[0].appendChild(customCSSToggle[1]);
  819. var styleGroupAsTagToggle = [document.createElement('label'),document.createElement('input')];
  820. styleGroupAsTagToggle[1].setAttribute('type','checkbox');
  821. styleGroupAsTagToggle[1].setAttribute('id','styleGroupAsTagToggle');
  822. styleGroupAsTagToggle[0].setAttribute('class','styleGroupAsTagToggle');
  823. styleGroupAsTagToggle[1].setAttribute('class','styleGroupAsTagToggle');
  824. if (storedStyleGroupAsTagSetting == true) {
  825. styleGroupAsTagToggle[1].setAttribute('checked','');
  826. }
  827. body.appendChild(styleGroupAsTagToggle[0]);
  828. styleGroupAsTagToggle[0].appendChild(styleGroupAsTagToggle[1]);
  829. var settingsLinkLocationDropdown = [document.createElement('label'),document.createElement('select')];
  830. var settingsLinkOptions = [document.createElement('option'),document.createElement('option'),document.createElement('option')];
  831. settingsLinkLocationDropdown[1].setAttribute('id','settingsLinkLocation');
  832. settingsLinkLocationDropdown[0].setAttribute('class','settingsLinkLocation');
  833. settingsLinkLocationDropdown[1].setAttribute('class','settingsLinkLocation');
  834. settingsLinkOptions[0].setAttribute('id','header');
  835. settingsLinkOptions[0].setAttribute('value',0);
  836. settingsLinkOptions[0].textContent = 'Header';
  837. settingsLinkOptions[1].setAttribute('id','accountSettings');
  838. settingsLinkOptions[1].setAttribute('value',1);
  839. settingsLinkOptions[1].textContent = 'Account Settings';
  840. settingsLinkOptions[2].setAttribute('id','both');
  841. settingsLinkOptions[2].setAttribute('value',2);
  842. settingsLinkOptions[2].textContent = 'Both';
  843. body.appendChild(settingsLinkLocationDropdown[0]);
  844. settingsLinkLocationDropdown[0].appendChild(settingsLinkLocationDropdown[1]);
  845. settingsLinkLocationDropdown[1].appendChild(settingsLinkOptions[0]);
  846. settingsLinkLocationDropdown[1].appendChild(settingsLinkOptions[1]);
  847. settingsLinkLocationDropdown[1].appendChild(settingsLinkOptions[2]);
  848. settingsLinkOptions[GM_getValue("settingsLinkLocation")].selected = true;
  849. var newListButton = document.createElement('input');
  850. newListButton.setAttribute('id','newListButton');
  851. newListButton.setAttribute('class','newListButton');
  852. newListButton.setAttribute('type','button');
  853. newListButton.setAttribute('value','New Highlighting List');
  854. body.appendChild(newListButton);
  855. newListButton.addEventListener('click',newList,true);
  856. var saveSettingsButton = document.createElement('input');
  857. saveSettingsButton.setAttribute('id','saveSettingsButton');
  858. saveSettingsButton.setAttribute('class','saveSettingsButton');
  859. saveSettingsButton.setAttribute('type','button');
  860. saveSettingsButton.setAttribute('value','Save Settings');
  861. body.appendChild(saveSettingsButton);
  862. saveSettingsButton.addEventListener('click',function() {var here = this;saveSettings("settingspage");here.setAttribute("value","Saved!");setTimeout(function(){here.setAttribute("value","Save Settings")},1000);},true);
  863. var exitButton = document.createElement('input');
  864. exitButton.setAttribute('id','exitButton');
  865. exitButton.setAttribute('class','exitButton');
  866. exitButton.setAttribute('type','button');
  867. exitButton.setAttribute('value','Exit');
  868. body.appendChild(exitButton);
  869. exitButton.addEventListener('click',function() {window.scrollTo(0,0); window.location.href = window.location.href.split("#")[0];},true);
  870. var exportImportLabel = document.createElement('label');
  871. exportImportLabel.setAttribute('id','exportImportLabel');
  872. exportImportLabel.setAttribute('class','exportImportLabel');
  873. var exportImportField = document.createElement('input');
  874. exportImportField.setAttribute('id','exportImportField');
  875. exportImportField.setAttribute('class','exportImportField');
  876. exportImportField.setAttribute('type','text');
  877. body.appendChild(exportImportLabel);
  878. exportImportLabel.appendChild(exportImportField);
  879. var importButton = document.createElement('input');
  880. importButton.setAttribute('id','importButton');
  881. importButton.setAttribute('class','importButton');
  882. importButton.setAttribute('type','button');
  883. importButton.setAttribute('value','Import');
  884. body.appendChild(importButton);
  885. importButton.addEventListener('click',function() {var here = this;saveSettings("import");here.setAttribute("value","Imported!");setTimeout(function(){window.location.href = window.location.href.split("#")[0]+"#ReloadHighlightSettings"; location.reload();},300);},true);
  886. if (window.location.href.split("#")[1] == "ReloadHighlightSettings") {
  887. window.location.href = window.location.href.split("#")[0]+"#HighlightSettings";
  888. window.scrollTo(0,document.body.scrollHeight);
  889. }
  890. }
  891.  
  892. function prepSettings () {
  893. var gfaqsBody = document.getElementsByTagName("body")[0];
  894. var gfaqsHead = document.getElementsByTagName("head")[0];
  895. var killMe = gfaqsBody.childNodes;
  896. var killMeToo = gfaqsHead.childNodes;
  897. for (var i = killMe.length-1; i >= 0; i--) {
  898. gfaqsBody.removeChild(killMe[i]);
  899. }
  900. for (var i = killMeToo.length-1; i >= 0; i--) {
  901. gfaqsHead.removeChild(killMeToo[i]);
  902. }
  903. var title = gfaqsHead.appendChild(document.createElement("title"));
  904. title.textContent = "Highlight Settings";
  905. createSettingsPage();
  906. }
  907.  
  908. if (window.location.href.split("#")[1] == "ReloadHighlightSettings") {
  909. prepSettings();
  910. }