GameCATs Highlighting

Highlights stuff, I dunno.

当前为 2014-05-16 提交的版本,查看 最新版本

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