1. // ==UserScript==
  2. // @name [TS] Citrus GFork v.1.1.49 Fix by KONF (Marqued) + Decembre fix (New Repos for TSLibrary - Generic (Archive))
  3. // @namespace Descriptif
  4. // @version 1.1.49
  5. // @date 2019-04-18
  6. // @description NOW with version number in Listing!! Advance table view for Greasy Fork. Fixes display bugs. 100 scripts display at a time, favoured user count, remembers last sort order used on Script Listing, "My" Profile Listing, and third Party Listing. Able to distinguish between, Library, Unlisted and Deleted scripts using text icons. Beside FireFox, it now supports Opera and Chrome.
  7. // @author TimidScript
  8. // @homepageURL https://github.com/TimidScript
  9. // @copyright © 2014+ TimidScript, Some Rights Reserved.
  10. // @license https://github.com/TimidScript/UserScripts/blob/master/license.txt
  11. // @include https://greasyfork.org/*
  12. // @require https://greasyfork.org/scripts/439327-tslibrary-generic-archive/code/TSLibrary%20-%20Generic%20(Archive).js
  13. // @require https://greasyfork.org/scripts/19968-tslibrary-generic/code/TSLibrary%20-%20Generic.js
  14. // @resource MonkeyIcon https://i.imgur.com/RqikjW1.jpg
  15. // @resource FontAS https://github.com/TimidScript/UserScripts/raw/master/resources/fonts/FontAwesome.css
  16. // @homeURL https://greasyfork.org/en/scripts/4336
  17. // @grant GM_getValue
  18. // @grant GM_setValue
  19. // @grant GM_deleteValue
  20. // @grant GM_listValues
  21. // @grant GM_xmlhttpRequest
  22. // @grant GM_info
  23. // @grant GM_getMetadata
  24. // @grant GM_registerMenuCommand
  25. // @grant GM_setClipboard
  26. // @grant GM_getResourceURL
  27. // @grant GM_getResourceText
  28. // @icon data:image/png;base64,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
  29. // ==/UserScript==
  30. /* License + Copyright Notice
  31. ********************************************************************************************
  32. License can be found at: https://github.com/TimidScript/UserScripts/blob/master/license.txt
  33. Below is a copy of the license the may not be up-to-date.
  34. Copyright © TimidScript, Some Rights Reserved.
  35. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
  36. following conditions are met:
  37. 1) GPL-3 License is met that does not conflict with the rest of the license (http://www.gnu.org/licenses/gpl-3.0.en.html)
  38. 2) This notice must be included
  39. 3) Due credits and link to original author's homepage (included in this notice).
  40. 4) Notify the original author of redistribution
  41. 5) Clear clarification of the License and Notice to the end user
  42. 6) Do not upload on OpenUserJS.org or any other site that infringes on this license
  43. TimidScript's Homepages: GitHub: https://github.com/TimidScript
  44. GreasyFork: https://greasyfork.org/users/1455
  45. */
  46. /* Information
  47. Suggestions
  48. - Install record similar to OUJS-1
  49. - Highlight your username in the forum
  50. - Highlight your scripts in the forum
  51. Unnecessary, unused Code:
  52. getScriptHTML
  53. getScriptJSON
  54. makeStruct
  55. TODO: Clean up the code
  56. ********************************************************************************************
  57. Version History
  58. ----------------------------------------------
  59. 1.1.49 2019-04-18
  60. - Bugfix for Author data-script-author-name --> data-script-authors.
  61. - Bugfix in search
  62. 1.1.48 2017-03-18
  63. - Bugfix: Fixed code that got broken due Changes in layout
  64. - Add Code search support
  65. 1.1.47 2017-02-03
  66. - Quickfix: Correctly handle libraries page
  67. 1.1.46 2017-02-02
  68. - Changed the styling and layout
  69. - Added library link
  70. 1.1.45.1 2017-01-07
  71. - Quickfix in CSS
  72. 1.1.45 2017-01-07
  73. - Change to the Header background-image
  74. 1.1.44 2016-12-16
  75. - Table view added to feedback listing
  76. - Sort to favourites added
  77. 1.1.43
  78. - BugFix: Relevance when searching was not being supported. Now it is always the default in a search
  79. - BugFix: Search bugs
  80. - BugFix: Image size to fit parent element (script preview)
  81. - BugFix: JSON structure has changed
  82. - Monkey icon is now resource. Should have been years ago
  83. - Changed the styling of the script preview
  84. - Stores version numbers, so no longer does a JSON version call if version is up-to-date.
  85. - Purge all stored script version details if older the 90 days
  86. - Relative date in the discussion
  87. 1.1.42.1 (2016-10-22)
  88. - Hotfix: Settings not being stored as I changed the stored name
  89. 1.1.42 (2016-10-22)
  90. - Depreciated, Obsolete, Defunct and now Unsupported are checked first in description and then version. If it
  91. is present the script is tagged with "No Longer Supported" orange tag to signify that it is no longer maintained.
  92. It is recommended to use the keywords in the script description tag rather than version
  93. - Removed filters and re-implemented the sorting algorithm
  94. - Settings button added again. Can be found near the monkey icon. It toggles between relative date format and standard date format. Default is relative.
  95. - Fixed the numbering of listing which must have gotten broken along the way
  96. - The behaviour of script column sorting is now similar to default
  97. - New script search button that automatically does partial word search to yield more results. Toggle through settings.
  98. - Toggle between standard and relative date format is done through settings.
  99. 1.1.41 (2016-10-14)
  100. - Relative date added
  101. - Removed date format settings
  102. 1.1.40 (2016-10-14)
  103. - Bugfix: When editting post the reply type is now stored
  104. - Added a settings link to change the date format
  105. 1.1.39 (2016-09-03)
  106. - Added Copy button to library page
  107. 1.1.38 (2016-05-27)
  108. - Altered the license
  109. 1.1.37 (2016-05-25)
  110. - Moving to GreasyFork and preparing to remove OUJS files
  111. 1.1.36 (2016-04-10)
  112. - updateURL added
  113. 1.1.35 (2016-04-03)
  114. - Changed license to GPL-3
  115. 1.1.34 (2016-02-27)
  116. - Bug Fix: Displays version number in third party profiles
  117. - Removed toggle For Deleted scripts
  118. - Added discussion even when not logged in
  119. 1.1.33 (2015-10-05)
  120. - Replaced base64 bmp icon with png version
  121. 1.1.32 (2015-07-04)
  122. - Added overflow style to code tag
  123. 1.1.31 (2015-06-27)
  124. - Using URI (base64) for script icon
  125. 1.1.30 (2015-06-08)
  126. - Bug Fix: "Report Bug" and "Review" review button always visible even when there is no need.
  127. 1.1.29 (2015-06-08)
  128. - Using json to populate the table. This allows the extraction of version number.
  129. - Changed the feedback system rating interface. Review by default is hidden.
  130. - Supporting of versions "Obselete", "Depreciated", and "Defunct" similar to the script "OUJS-1"
  131. 1.0.28b (2015-04-04)
  132. - Bug fix to handle site searches
  133. 1.0.27 (2014-12-28)
  134. - Bug fix to changes made in 1.0.25
  135. - Changed the sets into a menu. CSS provided by decembre.
  136. 1.0.26 (2014-12-27)
  137. - pre tag bug fix
  138. 1.0.25 (2014-12-27)
  139. - decembre's request to show favourite sets to script listing
  140. script-list-set
  141. - Bug Fix to support URL local syntax
  142. 1.0.24 (2014-12-06)
  143. - Bug Fix in script paging
  144. - Bug Fix due to changes in url flags. Change sort flag from "fans" to "ratings"
  145. - Add total rating and provided total score also
  146. - Added counter to the number of users that favoured the script, in feedback tab
  147. 1.0.23 (2014-11-29)
  148. - Add styling for forum blockquote tag
  149. - Changes to deal with new GF layout
  150. 1.0.22 (2014-11-07)
  151. - Fix to handle changes in forum URL (localization added)
  152. - Add more fonts colours to the forum to distinguish between different types of usernames/links.
  153. 1.0.21 (2014-10-31)
  154. - Support for Opera now added. Dozen of browsers open causes confusion.
  155. 1.0.20 (2014-10-31)
  156. - Change table header "Fans" to "Score"
  157. - Slight changes to forum CSS
  158. - Support for Opera and Chrome added.
  159. 1.0.19 (2014-10-23)
  160. - Removed sign-out button as it has been added with today's site update
  161. 1.0.18 (2014-10-23)
  162. - Bug fix to accommodate new site changes to the URL syntax (localization added)
  163. 1.0.17 (2014-10-18)
  164. - Changed the framing of images to suite smaller images better
  165. - Credit link now points to my GF profile rather than OUJS
  166. - Added sign-out near the name
  167. - Bug fix: add script table only when need
  168. 1.0.16 (2014-09-29)
  169. - Got rid of the flashing timer
  170. 1.0.15 (2014-09-29)
  171. - Fixed the issue that 1.0.14 supposedly had fixed
  172. - Appreciation notice added
  173. 1.0.14 (2014-09-22)
  174. - Re-fixed profile table sort :?
  175. 1.0.13 (2014-09-19)
  176. - Fix in profile table sort
  177. 1.0.12 (2014-09-19)
  178. - Bug fix in sorting of lists with search. Not using global flag when matching regex
  179. 1.0.11 (2014-09-16)
  180. - Bug fix in search listing introduced in version 1.0.10
  181. 1.0.10 (2014-09-16)
  182. - Bug Fix: Daily installs sort order
  183. - Click on separator to toggle deleted script display
  184. 1.0.9 (2014-09-07)
  185. - Added new CSS for <code> and <pre> elements
  186. 1.0.8 (2014-08-03)
  187. - Author name next to title
  188. 1.0.7 (2014-08-29)
  189. - Added GM_update
  190. - Added script numbers to table
  191. 1.0.6 (2014-08-21)
  192. - Bug Fix for sorting
  193. 1.0.5 (2014-08-21)
  194. - Small CSS fix provided by decembre (https://greasyfork.org/forum/discussion/comment/4182)
  195. 1.0.4 (2014-08-20)
  196. - Bug Fix: Author not being displayed
  197. - Bug Fix: Handle missing elements in user profile
  198. 1.0.3 (2014-08-20)
  199. - Link to my homepage
  200. - By default deleted scripts are hidden now
  201. - Stole some CSS from OUJS ^_^
  202. - Added a frame around images and max-width
  203. - Few small bug fixes
  204. 1.0.2 (2014-08-19)
  205. - Changes to CSS, including smaller font
  206. - Changed the interface
  207. - Added filter on user profile
  208. - Changed the behaviour of column click. If clicked it goes to first page as oppose to remaining on the same page
  209. - Increased number of scripts returned to 100
  210. - Citrified, orangified and crucified the forum. ( ̄ _ゝ ̄)
  211. - Small bug fixes
  212. 1.0.1 (2014-08-18)
  213. - Initial release. Released as good enough. May contain bugs but good for general usage.
  214. **********************************************************************************************/
  215. (function ()
  216. {
  217. var scripts = new Array(),
  218. pathname = decodeURIComponent(document.location.pathname);
  219. TSL.addStyle("OverFlowCode", ".Comment .Message p {overflow-x:auto;}");
  220. TSL.addStyle("FontAwesomeCSS", GM_getResourceText("FontAS"));
  221. OrangifyPage();
  222. if (pathname.match(/(\w|-)+\/forum\/(post|discussion)\//) && document.getElementById("Form_Rating"))
  223. {
  224. TSL.addStyle("", ".choiceButtons {text-align:center; width: 80px;}");
  225. var po = document.querySelector(".PostOptions, .CommentOptions"),
  226. lbl = po.querySelector("label"),
  227. options = po.querySelectorAll(".RadioLabel"),
  228. hld = document.createElement("div"),
  229. btn1 = document.createElement("input"),
  230. btn2 = document.createElement("input");
  231. btn1.className = btn2.className = "choiceButtons Button";
  232. btn1.value = "Report bug"; btn1.style.marginRight = "4px";
  233. btn2.value = "Review";
  234. btn1.onclick = function (e)
  235. {
  236. btn1.style.color = "#2DCD05";
  237. btn2.style.color = "";
  238. options[0].setAttribute("style", "margin-top: 5px !important;");
  239. options[4].removeAttribute("style");
  240. options[1].setAttribute("style", "display: none !important;"); //options[1].style.display = "none !important";
  241. options[2].setAttribute("style", "display: none !important;");
  242. options[3].setAttribute("style", "display: none !important;");
  243. lbl.setAttribute("style", "display: none !important;");
  244. if (e) options[0].click();
  245. }
  246. btn2.onclick = function (e)
  247. {
  248. btn1.style.color = "";
  249. btn2.style.color = "#2DCD05";
  250. options[0].setAttribute("style", "display: none !important;");
  251. options[4].setAttribute("style", "display: none !important;");
  252. options[1].removeAttribute("style");
  253. options[2].removeAttribute("style");
  254. options[3].removeAttribute("style");
  255. lbl.removeAttribute("style");
  256. if (e) options[3].click();
  257. }
  258. hld.appendChild(btn1);
  259. hld.appendChild(btn2);
  260. po.insertBefore(hld, po.firstElementChild);
  261. //for (var i = 0; i < options.length; i++) console.log(options[i].firstElementChild.checked);
  262. if (options[0].firstElementChild.checked || options[4].firstElementChild.checked) btn1.click(false);
  263. else btn2.click(false);
  264. }
  265. else if (pathname.match(/\/[\w-]+\/scripts\/\d+/)) //Script Page
  266. {
  267. TSL.addStyle("", "#script-content {background-color: #F9ECDB; margin: 0; padding-bottom: 5px;} #script-links > li:hover { background-color: yellow; } .current {background-color: #F9ECDB !important;}");
  268. TSL.addStyle("", ".install-link {background-color: #F7A207;} .install-help-link {background-color: #F9C565 !important;} #script-meta {padding-bottom:5px;} #script-feedback-suggestion, #script-meta {padding-left:5px;padding-right:5px;}");
  269. TSL.addStyle("", "#additional-info {padding: 5px 0;} #additional-info, #additional-info > div {background-color: white;} #additional-info > h3 {padding: 5px 0; margin:0;} #additional-info > div.script-author-description {margin: 0 0;}");
  270. TSL.addStyle("", "header:first-child {background-color:white; padding: 5px 10px;}");
  271. TSL.addStyle("", ".fa-sort-alpha-asc[on] {color:blue; background-color: yellow;} .fa-sort-alpha-asc {margin-left: 5px;cursor:pointer; padding: 0 3px;} .fa-sort-alpha-asc:hover {background-color: brown; color: yellow;}");
  272. var notice = document.createElement("div");
  273. notice.textContent = "Show your appreciation to the author by favouring the script and giving positive feedback";
  274. notice.setAttribute("style", "padding: 3px 10px; border-radius: 4px; background-color: yellow; text-align: center;");
  275. if (pathname.match(/\/scripts\/[^\/]+\/feedback/i))
  276. {
  277. el = document.querySelector("#script-content");
  278. if (el) el.insertBefore(notice, el.firstElementChild);
  279. el = document.querySelector(".inline-list");
  280. var count = el.querySelectorAll("li").length;
  281. var users = [];
  282. var els = document.querySelectorAll(".inline-list li");
  283. for (var i = 0; i < els.length; i++)
  284. {
  285. els[i].setAttribute("position", i)
  286. users.push(els[i]);
  287. }
  288. el = document.getElementById("feedback-favoriters");
  289. el.innerHTML += " (<span style='color: #F00;'>" + count + "</span>";
  290. el.innerHTML += '<i class="fa fa-sort-alpha-asc"></i>)';
  291. el.lastElementChild.onclick = function (e)
  292. {
  293. this.enabled = (this.enabled !== true);
  294. GM_setValue("Feedback Sorted", this.enabled);
  295. var il = document.querySelector(".inline-list");
  296. if (this.enabled)
  297. {
  298. this.setAttribute("on", "");
  299. users.sort(function (a, b)
  300. {
  301. if (a.firstElementChild.textContent.toLowerCase() > b.firstElementChild.textContent.toLowerCase()) return 1;
  302. else return -1;
  303. });
  304. for (var i = 0; i < users.length; i++) il.appendChild(users[i]);
  305. }
  306. else
  307. {
  308. this.removeAttribute("on");
  309. users.sort(function (a, b)
  310. {
  311. if (parseInt(a.getAttribute("position")) > parseInt(b.getAttribute("position"))) return 1;
  312. else return -1;
  313. });
  314. for (var i = 0; i < users.length; i++) il.appendChild(users[i]);
  315. }
  316. };
  317. if (GM_getValue("Feedback Sorted", false)) document.querySelector(".fa-sort-alpha-asc").click();
  318. var els = document.querySelectorAll("#discussions > li");
  319. if (GM_getValue("Feedback Table View", false) && els.length > 0)
  320. {
  321. el = document.getElementById("discussions");
  322. var tab = document.createElement("table");
  323. tab.id = "DiscussionsTab";
  324. el.parentElement.insertBefore(tab, el);
  325. TSL.addStyle("FeedbackTable", '#DiscussionsTab {width:100%; border-spacing: 0; border-collapse: collapse;}' //border:1px solid black;
  326. + '#DiscussionsTab tr {border-bottom: 1px solid gray;}'
  327. + '#DiscussionsTab div[class^=discussion] {height: 16px; width: 16px; margin: 0 5px; background-size: height: 16px; width: 16px;}'
  328. + '#DiscussionsTab .discussion-question {background-image: url(/images/circle-blue.png);}'
  329. + '#DiscussionsTab .discussion-alien {background-image: url(/images/circle-alien.png);}'
  330. + '#DiscussionsTab .discussion-good {background-image: url(/images/circle-green.png);}'
  331. + '#DiscussionsTab .discussion-ok {background-image: url(/images/circle-yellow.png);}'
  332. + '#DiscussionsTab .discussion-bad {background-image: url(/images/circle-red.png);}'
  333. + '#discussions {display:none;}'
  334. );
  335. for (var i = 0, l, t, m, r, c, d; i < els.length; i++)
  336. {
  337. l = els[i].querySelectorAll("a"),
  338. t = els[i].querySelectorAll("time"),
  339. m = els[i].innerHTML.match(/<\/a>\s+([^<]+)\s+/g); //Too hard to extract the information for different languages one cannot speak
  340. r = tab.insertRow(-1);
  341. c = r.insertCell(-1);
  342. d = document.createElement("div");
  343. d.className = els[i].className;
  344. c.appendChild(d);
  345. c = r.insertCell(-1);
  346. d = document.createElement("div");
  347. d.appendChild(l[0].cloneNode(true));
  348. c.appendChild(d);
  349. d = document.createElement("div");
  350. d.appendChild(l[1].cloneNode(true));
  351. d.innerHTML += "<span> >> </span>"
  352. d.appendChild(t[0]);
  353. c.appendChild(d);
  354. if (l.length == 3)
  355. {
  356. c = r.insertCell(-1);
  357. d = document.createElement("div");
  358. d.appendChild(l[2].cloneNode(true));
  359. c.appendChild(d);
  360. d = document.createElement("div");
  361. d.appendChild(t[1]);
  362. c.appendChild(d);
  363. }
  364. }
  365. }
  366. }
  367. else
  368. {
  369. var el = document.querySelector("#install-area");
  370. if (el) el.appendChild(notice);
  371. }
  372. }
  373. else if (!/\/scripts\/libraries/.test(location.pathname) && pathname.match(/\/[\w-]+\/scripts/)) //Script Listing
  374. {
  375. console.info("Script Listing");
  376. document.body.setAttribute("PageType", "ListingPage");
  377. getScripts();
  378. if (scripts.length > 0)
  379. {
  380. var isRelativeSearch = pathname.match(/scripts\/search/i) != null;
  381. createScriptTable(pathname.match(/scripts\/search/i) != null);
  382. populateScriptTable();
  383. if (document.getElementById("script-table"))
  384. {
  385. document.body.insertBefore(document.getElementById("script-table"), document.getElementById("main-header").nextElementSibling);
  386. //document.querySelector("#script-table tr td:nth-child(2)").appendChild(document.getElementById("UserSets"));
  387. if (isRelativeSearch)
  388. {
  389. el = document.createElement("div");
  390. el.setAttribute("style", "text-align: right; padding: 1px 50px");
  391. el.appendChild(document.createElement("span"));
  392. document.body.insertBefore(el, document.getElementById("script-table"));
  393. el = el.firstElementChild;
  394. el.id = "RelativeSearch";
  395. el.setAttribute("tag", "");
  396. el.textContent = "Relative Search";
  397. el.onclick = onTableHeaderClick;
  398. TSL.addStyle("RelativeSearchCSS", '#RelativeSearch {display: inline-block; background-color:orange; border-radius: 3px; padding: 3px 20px; text-align: center; width: 300px;cursor:pointer;}');
  399. }
  400. if (document.getElementById("UserSets"))
  401. {
  402. TSL.addStyle("TheBlackLagoon", "#UserSets {position: absolute !important;display: inline-table !important;float: none !important;left: 30px !important;top: 68px!important;padding: 2px 5px;background-color: yellow;border-radius: 5px;z-index: 200!important;visibility: hidden!important;opacity: 1!important;}"
  403. + "#UserSets:hover {visibility: visible!important;opacity: 1!important;}"
  404. + '#UserSets:before {content: "Sets ▼" !important; position: absolute !important;display: inline-block !important;left: 40px !important;top: -20px!important;margin: 2px 10px;padding: 1px 10px!important;background-color: yellow;border-radius: 5px;z-index: 200!important;visibility:visible!important;opacity: 1!important;}'
  405. + "#UserSets li {position: relative !important;display: inline !important;float: left!important;clear: both!important;min-width: 200px!important;margin-bottom: 2px!important;padding: 2px 8px;background-color: white;border-radius: 2px; text-align:left;}"
  406. );
  407. TSL.addStyle("TheBlackLagoon", "#UserSets, #UserSets:before {position: absolute;top: 4px;float: left;background-color: #FFC763;border-radius: 5px;z-index: 200;opacity:1;}"
  408. + "#UserSets {display: inline-table;left:10px;padding: 2px 5px;visibility: hidden;}"
  409. + "#UserSets:hover {visibility: visible;opacity: 1;}"
  410. + '#UserSets:before {display: inline-block;left: 40px;top:-18px;content: "Sets ▼";padding: 1px 10px;visibility: visible;}'
  411. + "#UserSets li {position: relative;display: inline;float: left;clear: both;min-width: 200px;margin-bottom: 2px;padding: 2px 8px;background-color: white;border-radius: 2px; text-align:left;}"
  412. );
  413. try
  414. {
  415. document.querySelector("[tag=name]").appendChild(document.getElementById("UserSets"));
  416. } catch(e) {};
  417. }
  418. //TODO: Need to fix the Sets filter in listing search
  419. //var header = document.querySelectorAll("#script-table thead td")[1],
  420. // sets = document.getElementById("UserSets");
  421. //header.appendChild(sets);
  422. }
  423. selectSortOrder("ListingPage", isRelativeSearch);
  424. TSL.removeNode("browse-script-list");
  425. }
  426. }
  427. else if (document.URL.match(/\/users\/(\w|-)+/)) //Authors Profile Page
  428. {
  429. var pageType = (document.getElementById("control-panel")) ? "PersonalProfile" : "UserProfile";
  430. document.body.setAttribute("PageType", pageType);
  431. document.body.setAttribute("ProfilePage", "");
  432. getScripts();
  433. OrangifyUserPage();
  434. if (scripts.length > 0)
  435. {
  436. createScriptTable();
  437. populateScriptTable();
  438. selectSortOrder(pageType);
  439. }
  440. }
  441. //Purge script details older than 90 days
  442. var now = Date.now(), names = GM_listValues();
  443. for (var i = 0; i < names.length; i++)
  444. {
  445. if (! /^Script:\d+/.test(names[i])) continue;
  446. //If greater than 30 days remove 1000*60*60*24=86400000
  447. if ((now - JSON.parse(GM_getValue(names[i])).timestamp) / 86400000 > 90) GM_deleteValue(names[i]);
  448. }
  449. /* Base CSS styling
  450. ---------------------------------------------------------------------------*/
  451. function OrangifyPage()
  452. {
  453. //#region Adding CSS Styles E3E2E2
  454. TSL.addStyle("CitrusGF_Main", "body {font-size: 14px;} .pagination {text-align:center;}"
  455. + "#main-header, #Head {background-color: orange !important; background-image: none !important;} #Head a, #site-nav a {color: yellow !important;}"
  456. + ".current, .HomepageTitle, .Active a {border-color: orange !important;}"
  457. + "#site-name {text-decoration: underline; color: white;}"
  458. + "#title-image {height: 50px; border-radius: 20px; margin-left: 5px;}"
  459. + "#title-text {font-size: 40px; color:black; font-family:'Open Sans',sans-serif; font-weight: 400; margin: 0 10px; line-height: 48px;}"
  460. + "#title-subtext {color: yellow !important; font-size: 10px; text-decoration: none; position: absolute; left: 210px; top: 43px; font-weight: 400 !important;}"
  461. + "#settings-subtext {color: yellow !important; font-size: 10px; text-decoration: none; position: absolute; left: 70px; top: 43px; font-weight: 400 !important;}"
  462. + "#nav-user-info {top: 3px;}"
  463. + "pre {background-color: #FFFF99; padding: 5px; margin-left: 30px; padding: 5px 10px;}"
  464. + "code {padding: 2px 4px; font-size: 90%; color: #C7254E; background-color: #F9F2F4; white-space: nowrap; border-radius: 4px; font-family: Menlo,Monaco,Consolas,'Courier New',monospace;}"
  465. + "pre > code {white-space: pre; background-color: transparent;}"
  466. + "#CForkSettings {position: fixed; top: 150px; background:white; border: 5px groove orangered; width: 400px;}"
  467. + "#CForkSettings > div {margin: 5px 10px}"
  468. + "#CForkSettings > footer {background-color:orange; padding: 1px 5px;text-align:right;}"
  469. + "#CForkSettings label {cursor: default;}"
  470. + ".preview-result {background-color: white; border-top: 10px ridge black;}"
  471. + ".preview-result img {max-width: 98%;}"
  472. + "#script-table, [ProfilePage] > .width-constraint {display: block; margin: 5px auto; max-width:1000px;min-width:700px;border-radius: 0;box-shadow: 0 0 2px gray;}"
  473. + "#script-search > input[type=submit], .sidebar-search > input[type=submit] {cursor:pointer;}"
  474. );
  475. TSL.addStyle("CitrusGF_ScriptPage", "#additional-info img {max-width: 98%; border: 1px solid orange; box-shadow: 5px 5px 2px #888888; margin: 5px 0; padding: 2px; color: yellow; }");
  476. if (document.location.pathname.match(/[\w-]+\/forum\//i))
  477. {
  478. TSL.addStyle("CitrusGF_Forum", "body:not(.Settings) a:not(.Button) { color: #F19E06; }"
  479. + "body a.Username { color: #E17205 !important; }"
  480. + ".QuoteAuthor a[href*='forum/profile/'] { color: #FB4507 !important;}"
  481. + "a[href*='forum/profile/'] { color: #25C614 !important; font-weight: 600;}"
  482. + "code {padding: 1px 3px; border-radius: 3px; border: 1px solid; background-color: #F9EBD2; color: #EB5100; margin: 0;}"
  483. + "#title-subtext {top: 45px;}"
  484. + "blockquote {background-color: #FFFFA4; margin: 5px 0px 5px 30px; padding: 5px;}"
  485. );
  486. }
  487. //#endregion
  488. var el = document.querySelector(".sidebar-search");
  489. if (el)
  490. {
  491. TSL.addStyle("SSSearch", ".sidebar-search {display:inline-block;vertical-align: unset;} .sidebar-search input[name=q] {width:164px; margin:0 !important; width: 164px !important;}"
  492. + ".sidebar-search > input {line-height:16px;font-size:14px;} .sidebar-search [value='✱'] {right:20px !important;}");
  493. document.querySelector("#site-nav nav").appendChild(el);
  494. }
  495. var sname = document.getElementById("site-name");
  496. sname.innerHTML = "";
  497. var link = document.createElement("a");
  498. link.href = "/";
  499. link.innerHTML = '<img id="title-image" src="' + GM_getResourceURL("MonkeyIcon") + '" />'
  500. + '<span id="title-text">Greasy Fork&nbsp;</span>'
  501. + '<span id="settings-subtext">Settings</span>'
  502. + '<a id="title-subtext" href="/users/1455-timidscript">100% Citrusy Goodness by <b>TimidScript</b></span>';
  503. sname.appendChild(link);
  504. var li = document.createElement("li");
  505. link = document.createElement("a")
  506. link.textContent = "Libraries";
  507. link.href = "/scripts/libraries";
  508. link.style.marginRight = "20px";
  509. li.appendChild(link);
  510. document.querySelector("nav").insertBefore(li, document.querySelector("nav").firstElementChild);
  511. var scriptsearch = document.querySelector("#script-search, .sidebar-search");
  512. if (scriptsearch)
  513. {
  514. var el = document.createElement("input");
  515. el.type = "submit";
  516. el.value = "✱";
  517. el.title = "Partial Search";
  518. el.onclick = function (e)
  519. {
  520. e.stopImmediatePropagation();
  521. //var search = document.querySelector("#script-search [type=search], .sidebar-search [type=search]");
  522. var search = document.querySelector("[type=search]");
  523. search.value = "*" + search.value.trim() + "*";
  524. search.value = search.value.replace(/^\*\*|\*\*$/g, "*");
  525. }
  526. if (GM_getValue("Use Original Search")) scriptsearch.appendChild(el);
  527. else scriptsearch.insertBefore(el, scriptsearch.lastElementChild);
  528. }
  529. document.getElementById("settings-subtext").onclick = function (e)
  530. {
  531. e.stopImmediatePropagation();
  532. if (document.getElementById("CForkSettings")) return false;
  533. var settings = document.createElement("settings");
  534. settings.id = "CForkSettings";
  535. settings.innerHTML = '<div><input type="checkbox"><label> Use standard date format (e.g. 2016-01-30) rather than relative (e.g. 5 days ago)</label></div>'
  536. + '<div><input type="checkbox"><label> Disable partial search set as default search option</label></div>'
  537. + '<div><input type="checkbox"><label> Enable feedback table view</label></div>'
  538. + '<footer><button>Accept</button></footer>';
  539. settings.style.left = ((document.body.clientWidth / 2) - 200) + "px";
  540. document.body.appendChild(settings);
  541. var lbls = settings.querySelectorAll("label");
  542. lbls[0].onclick = lbls[1].onclick = lbls[2].onclick = function (e) { this.previousElementSibling.click(); };
  543. var ipts = settings.querySelectorAll("input"), btn = settings.querySelector("button");
  544. if (GM_getValue("Use Standard Date Format", false)) ipts[0].checked = "checked";
  545. if (GM_getValue("Use Original Search", false)) ipts[1].checked = "checked";
  546. if (GM_getValue("Feedback Table View", false)) ipts[2].checked = "checked";
  547. btn.onclick = function (e)
  548. {
  549. if (ipts[0].checked) GM_setValue("Use Standard Date Format", true); else GM_deleteValue("Use Standard Date Format");
  550. if (ipts[1].checked) GM_setValue("Use Original Search", true); else GM_deleteValue("Use Original Search");
  551. if (ipts[2].checked) GM_setValue("Feedback Table View", true); else GM_deleteValue("Feedback Table View");
  552. document.location.reload();
  553. TSL.removeNode(settings);
  554. }
  555. return false;
  556. };
  557. var require = document.querySelector("#script-content > p > code");
  558. if (require && require.textContent.match("@require"))
  559. {
  560. var copyBar = document.createElement("div");
  561. var copyBtn = document.createElement("button");
  562. copyBtn.textContent = "Copy To Clipboard";
  563. require.parentElement.insertBefore(copyBar, require.nextElementSibling);
  564. require.setAttribute("style", "display:block;");
  565. copyBtn.setAttribute("style", "margin-right:10px");
  566. copyBar.appendChild(copyBtn);
  567. copyBar.appendChild(createRadio("Short URL"));
  568. copyBar.appendChild(createRadio("Long URL"));
  569. copyBar.appendChild(createRadio("Current Ver."));
  570. var scriptID = require.textContent.match(/\/scripts\/(\d+)/)[1];
  571. var radios = copyBar.querySelectorAll("input");
  572. radios[0].setAttribute("requireURL", "// @require https://greasyfork.org/scripts/" + scriptID + "/code/" + scriptID + ".js");
  573. radios[1].setAttribute("requireURL", require.textContent.replace(/\?\w+=\d+/, ""));
  574. radios[2].setAttribute("requireURL", require.textContent);
  575. radios[0].onclick = radios[1].onclick = radios[2].onclick = function (e)
  576. {
  577. for (var i = 0; i < radios.length; i++)
  578. {
  579. if (this != radios[i]) radios[i].checked = false;
  580. }
  581. require.textContent = this.getAttribute("requireURL");
  582. }
  583. copyBtn.onclick = function ()
  584. {
  585. GM_setClipboard(require.textContent);
  586. }
  587. radios[1].click();
  588. }
  589. if (pathname.match(/\/[\w-]+\/scripts/) && document.querySelector("#script-list-set ul")) //Script Listing
  590. {
  591. TSL.addStyle("TheBlackLagoon", "#UserSets {display: block; background-color: yellow; margin: 2px 10px; border-radius: 5px; padding: 2px 10px;}"
  592. + "#UserSets li {display: inline-block; padding: 2px 8px; background-color: white; border-radius: 2px;}"
  593. + "#UserSets li + li {margin-left: 1px}"
  594. );
  595. var sets = document.querySelector("#script-list-set ul");
  596. var mh = document.getElementById("main-header");
  597. sets.id = "UserSets";
  598. //document.body.insertBefore(sets, document.getElementById("main-header").nextElementSibling);
  599. document.body.appendChild(sets);
  600. }
  601. // decembre OK - TEST USER CSS - to SEE LANGUAGE PANEL
  602. // TSL.removeNode("script-list-option-groups");
  603. function createRadio(text)
  604. {
  605. var option = document.createElement("div");
  606. option.setAttribute("style", "display:inline-block; margin-right:10px;width:140px;")
  607. var radio = document.createElement("input");
  608. radio.type = "radio";
  609. var lbl = document.createElement("label");
  610. lbl.textContent = text;
  611. option.appendChild(radio);
  612. option.appendChild(lbl);
  613. return option;
  614. }
  615. }
  616. function disco(i)
  617. {
  618. notice.style.backgroundColor = (i % 2) ? "transparent" : "yellow";
  619. if (i < 18) setTimeout(disco, 500, ++i);
  620. }
  621. /* Styling for user page
  622. ---------------------------------------------------------------------------*/
  623. function OrangifyUserPage()
  624. {
  625. TSL.addStyle("CitrusGF_Shared", ".text-content {border: 0; box-shadow:0 0 0;padding:0;} #user-profile {background-color:#F9ECDB; margin: 0 15px}"
  626. + "body > .width-constraint {background-color:white; margin: 5px auto;padding: 2px 10px;} #control-panel {margin-top: 15px;}"
  627. );
  628. TSL.addStyle("", "#user-control-panel, #control-panel h3 {margin: 0; padding: 0;} #user-control-panel a {text-decoration: none;} #user-control-panel li:hover {background-color: #FBEACA;}"
  629. + "#user-control-panel > li {background-color: #f5f2f2;border: 1px solid #404040;border-radius: 5px;box-shadow: 3px 3px 2px #888888;display: inline-block;margin: 2px 5px;min-width: 150px;padding: 2px 5px;text-align: center;}"
  630. );
  631. TSL.addStyle("CitrusGF_OUJS", 'code {padding: 2px 4px;font-size: 90%;color: #C7254E;background-color: #F9F2F4;white-space: nowrap;border-radius: 4px;font-family: Menlo,Monaco,Consolas,"Courier New",monospace; }');
  632. var el = document.getElementById("user-script-sets");
  633. if (el) el.parentElement.className = "white-panel";
  634. el = document.getElementById("user-script-list");
  635. if (el) TSL.removeNode(el.parentElement);
  636. el = document.getElementById("user-deleted-script-list");
  637. if (el) TSL.removeNode(el.parentElement);
  638. //Get discussions
  639. el = document.querySelector("#user-discussions-on-scripts-written");
  640. if (el)
  641. {
  642. document.querySelector("body > .width-constraint").appendChild(el);
  643. return;
  644. }
  645. //https://greasyfork.org/en/forum/discussions.json?script_author=1455
  646. var userId = document.URL.match(/\/users\/(\d+)/)[1],
  647. localURL = document.URL.replace(/\/users\/.+/, ""),
  648. disURL = localURL + "/forum/discussions.json?script_author=" + userId;
  649. GM_xmlhttpRequest({
  650. url: disURL,
  651. method: "GET",
  652. headers: { "User-agent": navigator.userAgent, "Accept": "text/xml" },
  653. onload: function (xhr)
  654. {
  655. if (xhr.status == 200)
  656. {
  657. var data = JSON.parse(xhr.responseText);
  658. if (typeof data !== "object" || data.CountDiscussions == 0) return;
  659. console.log(data);
  660. var discussions = document.createElement("section");
  661. discussions.id = "user-discussions-on-scripts-written";
  662. discussions.innerHTML = '<h3>Discussions on scripts <a href="/en/forum/discussions/feed.rss?script_author="' + userId + '"><img src="/assets/feed-icon-14x14-ea341336588040dc7046d3423511d63d.png" alt="RSS Feed" rel="nofollow"></a></h3><ul class="discussion-list"></ul>';
  663. document.querySelector("body > .width-constraint").appendChild(discussions);
  664. var list = discussions.querySelector("ul");
  665. for (var i = 0, post, item; i < data.Discussions.length && i < 10; i++)
  666. {
  667. post = data.Discussions[i];
  668. item = document.createElement("li");
  669. item.class = "discussion-question";
  670. item.innerHTML = '<a href="' + localURL + '/scripts/' + post.ScriptID + '">' + post.DiscussionAboutName + '</a> : '
  671. + '<a href="' + post.Url + '">' + post.Name + '</a> by '
  672. + '<a href="' + localURL + "/forum/profile/" + post.FirstUserID + "/" + post.FirstName + '">' + post.FirstName + '</a> '
  673. + '<time datetime="' + post.FirstDate + '">(' + getRelativeDate(post.FirstDate) + ')</time>, last comment by '
  674. + '<a href="' + localURL + "/forum/profile/" + post.LastUserID + "/" + post.LastName + '">' + post.LastName + '</a> '
  675. + '<time datetime="' + post.LastDate + '">(' + getRelativeDate(post.LastDate) + ')</time>';
  676. list.appendChild(item);
  677. }
  678. }
  679. else callback(xhr, null);
  680. function getRelativeDate(date)
  681. {
  682. var ms = Date.now() - parseInt(new Date(date).getTime()),
  683. secs = Math.floor(ms / (1000)) % 60,
  684. mins = Math.floor(ms / (60 * 1000)) % 60,
  685. hrs = Math.floor(ms / (60 * 60 * 1000)) % 24,
  686. days = Math.floor(ms / (60 * 60 * 1000 * 24) % 7),
  687. weeks = Math.floor(ms / (60 * 60 * 1000 * 24) / 7);
  688. if (weeks) return date.replace(/\s+.+/, "");
  689. if (days) return days + "day" + isPlural(days) + " and " + hrs + "hr" + isPlural(hrs);
  690. if (hrs) return hrs + "hr" + isPlural(hrs) + " and " + mins + "min" + isPlural(mins);
  691. if (mins) return mins + "min" + isPlural(mins) + " and " + secs + "sec" + isPlural(secs);
  692. return secs + "sec" + isPlural(secs);
  693. function isPlural(val)
  694. {
  695. if (val == 1) return "";
  696. return "s";
  697. }
  698. }
  699. }
  700. });
  701. }
  702. /* Gets the scripts from document
  703. ---------------------------------------------------------------------------*/
  704. function getScripts(doc)
  705. {
  706. if (!doc) doc = document;
  707. var ids = ["user-script-list", "user-deleted-script-list", "browse-script-list"];
  708. scripts = new Array();
  709. for (var i = 0, el, deleted, list; i < ids.length; i++)
  710. {
  711. el = doc.getElementById(ids[i]);
  712. if (!el) continue;
  713. deleted = ids[i].indexOf("deleted") > 0;
  714. list = el.children;
  715. for (var j = 0, stamp; j < list.length; j++)
  716. {
  717. var li = list[j];
  718. // Fix by KONF
  719. if (li.classList.contains('ad-entry')) continue;
  720. var script = new Object();
  721. script.name = li.getAttribute("data-script-name");
  722. script.id = li.getAttribute("data-script-id");
  723. script.author = li.getAttribute("data-script-authors");
  724. script.authorID = script.author.match(/"(\d+)":"(.+)"/)[1];
  725. script.author = script.author.match(/"(\d+)":"(.+)"/)[2];
  726. script.description = li.getElementsByClassName("description")[0].textContent.trim();
  727. script.rating = li.getAttribute("data-script-rating-score");
  728. script.ratings = (li.querySelector("dd.script-list-ratings")) ? li.querySelector("dd.script-list-ratings").innerHTML : "";
  729. script.installsDaily = li.getAttribute("data-script-daily-installs");
  730. script.installsTotal = li.getAttribute("data-script-total-installs");
  731. //Fix by KONF
  732. /* OLD
  733. script.dateCreated = li.getAttribute("data-script-created-date") + "|" + li.querySelector(".script-list-created-date time").textContent;
  734. script.dateUpdated = li.getAttribute("data-script-updated-date") + "|" + li.querySelector("dd.script-list-updated-date span").textContent;
  735. script.dateUpdated = li.getAttribute("data-script-updated-date") + "|" + li.querySelector(".script-list-updated-date time").
  736. */
  737. script.dateCreated = li.getAttribute("data-script-created-date") + "|" + li.querySelector("dd.script-list-created-date span").textContent;
  738. script.dateUpdated = li.getAttribute("data-script-updated-date") + "|" + li.querySelector("dd.script-list-updated-date span").textContent;
  739. script.type = li.getAttribute("data-script-type");
  740. script.defunct = /defunct|depreciated|obselete|unsupported/i.test(script.description);
  741. script.deleted = deleted;
  742. scripts.push(script);
  743. stamp = GM_getValue("Script:" + script.id, false);
  744. //Fix by KONF
  745. /* OLD
  746. if (li.querySelector(".script-list-updated-date time").getAttribute("datetime") != stamp.datetime) stamp.version = "";
  747. if (li.querySelector(".script-list-updated-date time").getAttribute("datetime") != stamp.datetime) stamp.version = "";
  748. */
  749. if (stamp)
  750. {
  751. stamp = JSON.parse(stamp);
  752. if (li.querySelector("dd.script-list-updated-date span").getAttribute("datetime") != stamp.datetime) stamp.version = "";
  753. else script.version = stamp.version;
  754. }
  755. else stamp = { datetime: li.querySelector("dd.script-list-updated-date span").getAttribute("datetime"), version: "", timestamp: "" };
  756. stamp.timestamp = Date.now();
  757. GM_setValue("Script:" + script.id, JSON.stringify(stamp));
  758. }
  759. }
  760. }
  761. /* Creates scripts table (relative search)
  762. ---------------------------------------------------------------------------*/
  763. function createScriptTable(isRelativeSearch)
  764. {
  765. var scriptTable = document.createElement("table");
  766. scriptTable.id = "script-table";
  767. var thead = scriptTable.createTHead();
  768. var row = thead.insertRow(-1);
  769. var headers = ["Name", "Ratings", "Daily", "Total", "Created", "Updated"];
  770. var tags = ["name", "ratings", (isRelativeSearch ? "daily_installs" : ""), "total_installs", "created", "updated"];
  771. cell = row.insertCell(-1);
  772. cell.textContent = "#";
  773. var cell;
  774. for (var i = 0; i < headers.length; i++)
  775. {
  776. cell = row.insertCell(-1);
  777. cell.innerHTML = headers[i];
  778. cell.onclick = onTableHeaderClick;
  779. cell.setAttribute("tag", tags[i]);
  780. }
  781. cell = row.cells[1];
  782. //scriptTable.createTBody();
  783. scriptTable.appendChild(document.createElement("tbody"));
  784. document.body.appendChild(scriptTable);
  785. TSL.addStyle("CitrusGS_Table", "body {background-color: #EFEFB1; margin: 0;} body {background-color:whitesmoke;}"
  786. //+ "#script-table {display: block; margin: 0 5px 5px 5px; }"
  787. + "pagination {text-align:center;}"
  788. + "#script-table thead td {background-color: orange; border-radius: 0 0 5px 5px; box-shadow: 3px 3px 2px #888888;position:relative;}"
  789. + "#user-discussions-on-scripts-written > h3 {margin-bottom: 3px;}"
  790. + "#script-table thead td:hover {cursor:pointer; background-color: yellow;}"
  791. + "#script-table thead td:first-child:hover {cursor:default; background-color: orange;}"
  792. + "#script-table td {white-space: nowrap;width: auto; padding: 2px 5px; text-align:center;}"
  793. + "#script-table td:nth-child(0), #script-table td:nth-child(1), #script-table td:nth-child(2) {white-space: normal;}"
  794. //+ "#script-table thead tr td:nth-child(3) {width: 120px; display: block;}"
  795. //+ ".total-rating-count {display: inline-block; min-width: 1em; text-align: center; padding: 0px 0.25em; border-radius: 10px;}"
  796. + ".total-rating-count, .good-rating-count, .ok-rating-count, .bad-rating-count {display: inline-block; min-width: 1em; padding: 1px 3px; border-radius: 3px;}"
  797. + ".total-rating-count {background-color: rgba(0, 0, 255, 0.1);}"
  798. + "#script-table tbody td {background-color: #FFFBDB;}"
  799. + "#script-table tbody td:first-child{background-color: #F9D5A6;}"
  800. + "#script-table tbody td:nth-child(2){width: 99%; background-color: white;text-align:left;}"
  801. + "#script-table tbody tr:hover td {background-color: yellow;}"
  802. + ".loadingSort {background-color: #FDFDC3 !important;}"
  803. + ".type-library, .type-unlisted, .type-deleted, .type-defunct {font-size:smaller; display: inline-block; border-radius: 3px; padding: 0 5px; border: 1px solid black;}"
  804. + ".type-library, .type-unlisted, .type-deleted, .type-defunct {box-shadow: 2px 2px 1px #888888; margin: 2px 5px 3px 0;}"
  805. + "#script-table tbody [library] td:nth-of-type(3) {background-color:lightgray;}"
  806. + ".type-library {background-color: #CEFD8A;}"
  807. + ".type-deleted {background-color: #F77A7A;}"
  808. + ".type-defunct {background-color: #FF8600;}"
  809. + ".type-unlisted, .filterU {background-color: #CEE7F3;}"
  810. + ".type-library:before {content: 'Library';}"
  811. + ".type-deleted:before {content: 'Deleted';}"
  812. + ".type-unlisted:before {content: 'Unlisted';}"
  813. + ".type-defunct:before {content: 'No Longer Supported';}"
  814. + "#notice {margin:5px 5px 0 5px; background-color: #FDBB45;padding: 3px 5px; color: blue;}"
  815. + "thetitle {margin-bottom: 3px;} .theauthor{font-size:small;}"
  816. );
  817. TSL.addStyle("Al28dj21", ".thetitle a {margin-right: 2px !important;}");
  818. TSL.addStyle("Al28dj23", ".theversion {font-size: xsmall; margin-right: 4px;}");
  819. TSL.addStyle("Al28dj24", "tr[library] td:nth-child(2) {background-color: #F2FBEA !important;}");
  820. TSL.addStyle("Al28dj25", "tr[unlisted] td:nth-child(2) {background-color: #F4FBFF !important;}");
  821. TSL.addStyle("Al28dj27", "tr[deleted] td:nth-child(2) {background-color: #FDF7F7 !important;}");
  822. }
  823. /* Populate the table with scripts
  824. ---------------------------------------------------------------------------*/
  825. function populateScriptTable(clear)
  826. {
  827. //populateScriptTable0(true); return;
  828. var tbody = document.getElementById("script-table").getElementsByTagName("tbody")[0];
  829. if (clear) tbody.innerHTML = "";
  830. if (scripts.length == 0) return;
  831. for (var i = 0; i < scripts.length; i++)
  832. {
  833. var script = getScriptHTML(i);
  834. row = tbody.insertRow(-1);
  835. row.id = "s" + script.id;
  836. cell = row.insertCell(-1);
  837. cell.textContent = "##";
  838. cell = row.insertCell(-1);
  839. var el = document.createElement("div");
  840. el.className = "thetitle";
  841. el.innerHTML = "<a href='https://greasyfork.org/scripts/"
  842. + script.id + "' style='margin-right: 10px;'><b>" + script.name + "</b></a><span class='theversion'></span>";
  843. if (script.type == "library") AddScriptTag("library");
  844. else if (script.type == "unlisted") AddScriptTag("unlisted");
  845. else row.setAttribute("public", 0);
  846. if (script.deleted) AddScriptTag("deleted");
  847. if (script.defunct) AddScriptTag("defunct");
  848. // If page listing add author detail
  849. if (document.body.getAttribute("PageType") == "ListingPage")
  850. {
  851. el.innerHTML += '<span class="theauthor"><span>by </span><a href="https://greasyfork.org/users/' + script.authorID + '">' + script.author + '</a></span>';
  852. }
  853. cell.appendChild(el);
  854. el = document.createElement("div");
  855. el.textContent = script.description;
  856. cell.appendChild(el);
  857. cell = row.insertCell(-1);
  858. if (script.type != "library")
  859. {
  860. cell.innerHTML = script.ratings + '<span class="total-rating-count">' + script.rating + '</span>';
  861. cell.title = "Favoured plus Good Feedback, OK Feedback, Bad Feedback, Total Score (" + script.rating + ")";
  862. }
  863. row.insertCell(-1).textContent = script.installsDaily;
  864. row.insertCell(-1).textContent = script.installsTotal;
  865. row.insertCell(-1).textContent = GM_getValue("Use Standard Date Format", false) ? script.dateCreated.split("|")[0] : script.dateCreated.split("|")[1];
  866. row.insertCell(-1).textContent = GM_getValue("Use Standard Date Format", false) ? script.dateUpdated.split("|")[0] : script.dateUpdated.split("|")[1];
  867. function AddScriptTag(tag)
  868. {
  869. el.innerHTML += '<span class="type-' + tag + '" />';
  870. row.setAttribute(tag, "");
  871. }
  872. if (script.version) addScriptVersion(script);
  873. }
  874. OrganizeTableByCategory();
  875. function getScriptHTML(idx)
  876. {
  877. var properties = "name id author authorID description rating ratings installsDaily installsTotal dateCreated dateUpdated type deleted";
  878. return makeStruct(properties, scripts[idx]);
  879. }
  880. }
  881. function addScriptVersion(script)
  882. {
  883. var el = document.querySelector("#s" + script.id + " .thetitle .theversion");
  884. if (!el) return;
  885. el.innerHTML = "(<b>" + script.version + "</b>)";
  886. if (/defunct|depreciated|obselete|unsupported/i.test(script.version))
  887. {
  888. el.innerHTML += '<span class="type-defunct" />';
  889. el.parentElement.parentElement.setAttribute("defunct", "");
  890. }
  891. stamp = JSON.parse(GM_getValue("Script:" + script.id));
  892. stamp.version = script.version;
  893. GM_setValue("Script:" + script.id, JSON.stringify(stamp));
  894. }
  895. function numberScriptListing()
  896. {
  897. var rows = document.querySelectorAll("#script-table > tbody > tr");
  898. if (!rows) return;
  899. var offset = 1, len = rows.length.toString().length;
  900. if (document.body.getAttribute("PageType") == "ListingPage")
  901. {
  902. var page = 1, limit = 100, m = document.location.search.match(/(?:\?|&)page=(\d+)/);
  903. if (m) page = parseInt(m[1]);
  904. m = document.location.search.match(/per_page=(\d+)/);
  905. if (m) limit = parseInt(m[1]);
  906. console.log(page, limit);
  907. offset += limit * (page - 1);
  908. }
  909. for (var i = 0; i < rows.length; i++)
  910. {
  911. rows[i].firstElementChild.textContent = (i + offset).toString().lPad("0", len);
  912. }
  913. }
  914. function OrganizeTableByCategory()
  915. {
  916. if (document.body.getAttribute("PageType") == "ListingPage")
  917. {
  918. numberScriptListing();
  919. return;
  920. }
  921. var tbody = document.getElementById("script-table").getElementsByTagName("tbody")[0];
  922. var rows = tbody.children;
  923. for (var i = 0, n; i < rows.length - 1; i++)
  924. {
  925. n = i;
  926. for (var j = i + 1; j < rows.length; j++)
  927. {
  928. if (getPosValue(rows[n]) > getPosValue(rows[j])) n = j;
  929. }
  930. if (n != i) tbody.insertBefore(rows[n], rows[i]);
  931. }
  932. numberScriptListing();
  933. function getPosValue(el)
  934. {
  935. var v = 0;
  936. if (el.hasAttribute("unlisted")) v += 4;
  937. if (el.hasAttribute("defunct")) v += 1;
  938. if (el.hasAttribute("library")) v += 2;
  939. if (el.hasAttribute("deleted")) v += 6;
  940. return v;
  941. }
  942. }
  943. /*
  944. ---------------------------------------------------------------------------*/
  945. function selectSortOrder(pageType, isRelativeSearch)
  946. {
  947. var tag = (isRelativeSearch) ? "" : GM_getValue(pageType, "updated");
  948. var m = document.URL.match(/[\?&]sort=(\w+)/);
  949. var tagURL = (m) ? m[1] : "";
  950. var page = document.URL.match(/[\?&]page=(\d+)/);
  951. TSL.addStyle("SelectedSortColumn", "[tag='" + tagURL + "'] {background-color: yellow !important;}");
  952. if (!isRelativeSearch && !page && (tagURL != tag || (document.URL.indexOf("per_page=100") < 0)))
  953. {
  954. document.querySelector(("[tag='" + tag + "']")).click();
  955. return;
  956. }
  957. getScriptVersionNumbers();
  958. }
  959. /* Table header is clicked, get the correct script sorting
  960. ---------------------------------------------------------------------------*/
  961. function onTableHeaderClick(e)
  962. {
  963. if (document.querySelector("loadingSort")) return;
  964. this.className = "loadingSort";
  965. getScriptListing(this.getAttribute("tag"), true);
  966. }
  967. /* Get script page
  968. ---------------------------------------------------------------------------*/
  969. function getScriptListing(tag, removePage)
  970. {
  971. var isListingPage = (document.body.getAttribute("PageType") == "ListingPage");
  972. if (/\/code-search\?/i.test(document.URL)) url = document.URL.match(/.+\/code-search\?/)[0] + "per_page=100";
  973. else if (isListingPage) url = document.URL.match(/https:\/\/greasyfork.org\/[\w-]+\/scripts(\/by-site\/[\w\.\-_]+|\/search)?/)[0] + "?per_page=100";
  974. else url = document.URL.replace(/\?.+/, "?");
  975. var m = document.URL.match(/[^=\?&]+=[^&]+/g);
  976. if (m)
  977. for (var i = 0; i < m.length; i++)
  978. {
  979. //if (!m[i].match(/^(per_page|sort)/) && !(firstPage && m[i].match(/^page/))) url += "&" + m[i];
  980. if (!m[i].match(/^(per_page|sort)/)) url += "&" + m[i];
  981. }
  982. if (tag) url += "&sort=" + tag;
  983. if (removePage) url = url.replace(/[\?&]page=\d+/, "");
  984. url = url.replace(/\?&/, "?");
  985. url = url.replace(/\?$/, "");
  986. if (url.indexOf("?") < 0) url = url.replace("&", "?");
  987. console.warn("getScriptListing IN: " + url)
  988. GM_xmlhttpRequest({
  989. url: url,
  990. method: "GET",
  991. timeout: 15000,
  992. headers: {
  993. "User-agent": navigator.userAgent,
  994. "Host": "greasyfork.org",
  995. "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
  996. "Accept-Language": "en-US,en;q=0.5"
  997. },
  998. onload: function (xhr)
  999. {
  1000. if (xhr.status == 200)
  1001. {
  1002. GM_setValue(document.body.getAttribute("PageType"), tag);
  1003. TSL.addStyle("SelectedSortColumn", "[tag='" + tag + "'] {background-color: yellow !important;}");
  1004. //stackoverflow.com/questions/19193335/change-the-url-in-browser-bar-without-reloading-page
  1005. window.history.pushState(null, "", xhr.finalUrl); //Change document URL
  1006. scripts = new Array();
  1007. //var doc = new DOMParser().parseFromString(xhr.responseText, 'text/xml');
  1008. var doc = document.implementation.createHTMLDocument('MPIV');
  1009. doc.documentElement.innerHTML = xhr.responseText;
  1010. TSL.removeNode(document.getElementsByClassName("pagination")[0]);
  1011. var pager = doc.getElementsByClassName("pagination")[0];
  1012. if (pager)
  1013. {
  1014. document.body.insertBefore(pager, document.getElementById("script-table").nextElementSibling);
  1015. }
  1016. getScripts(doc);
  1017. populateScriptTable(true);
  1018. getScriptVersionNumbers();
  1019. }
  1020. TSL.removeClass(document.querySelector(".loadingSort"), "loadingSort")
  1021. console.warn("getScriptListing OUT: " + url);
  1022. }
  1023. });
  1024. }
  1025. function getScriptVersionNumbers()
  1026. {
  1027. //No need to do a JSON call as the stored information is already up-to-date
  1028. if (document.querySelectorAll(".theversion").length == document.querySelectorAll(".theversion b").length) return;
  1029. var jsonURL = document.URL.replace(/(\?|$)/, ".json$1");
  1030. console.log("JSON: " + jsonURL);
  1031. //Get version number
  1032. GM_xmlhttpRequest({
  1033. url: jsonURL,
  1034. method: "GET",
  1035. timeout: 15000,
  1036. headers: {
  1037. "User-agent": navigator.userAgent,
  1038. "Host": "greasyfork.org",
  1039. "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
  1040. "Accept-Language": "en-US,en;q=0.5"
  1041. },
  1042. onload: function (xhr)
  1043. {
  1044. if (xhr.status == 200)
  1045. {
  1046. var data = JSON.parse(xhr.responseText), scripts;
  1047. //console.log(data);
  1048. if (typeof data !== "object") return;
  1049. scripts = data.all_listable_scripts || data;
  1050. for (var i = 0, script; i < scripts.length; i++)
  1051. {
  1052. script = scripts[i];
  1053. addScriptVersion(script);
  1054. }
  1055. OrganizeTableByCategory();
  1056. }
  1057. }
  1058. });
  1059. }
  1060. function getScriptJSON(obj)
  1061. {
  1062. var properties = "bad_ratings code_updated_at code_url contribution_amount contribution_url created_at daily_installs description fan_score good_ratings id license locale name namespace ok_ratings redistributable support_url total_installs url version";
  1063. return makeStruct(properties, obj);
  1064. }
  1065. function makeStruct(keys, obj)
  1066. {
  1067. if (!obj) obj = {};
  1068. var names = keys.split(" ").sort();
  1069. for (var i = 0; i < names.length; i++)
  1070. {
  1071. obj[names[i]] = obj[names[i]];
  1072. }
  1073. return obj;
  1074. }
  1075. })();

TS] Citrus GFork v.1.1.49 Fix by KONF (Marqued) + Decembre fix (New Repos for TSLibrary - Generic (Archive))