Advertisement
Guest User

Untitled

a guest
Apr 5th, 2016
36
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.03 KB | None | 0 0
  1. // ==UserScript==
  2. // @name Robin Enhancement Script
  3. // @namespace https://www.reddit.com/
  4. // @version 3.1.0
  5. // @description Highlight mentions, make link clickable, use channels & automatically remove spam
  6. // @author Bag
  7. // @author netnerd01
  8. // @match https://www.reddit.com/robin*
  9. // @grant none
  10. // @grant GM_setValue
  11. // @grant GM_getValue
  12. // ==/UserScript==
  13. (function() {
  14.  
  15. // Grab users username + play nice with RES
  16. var robin_user = $("#header-bottom-right .user a").first().text();
  17. var ignored_users = {};
  18.  
  19. // for spam counter - very important i know :P
  20. var blocked_spam_el = null;
  21. var blocked_spam = 0;
  22. var user_last_message = '';
  23. //
  24. var _robin_grow_detected = false;
  25.  
  26. /**
  27. * Pull tabber out in to semi-stand alone module
  28. * Big thanks to netnerd01 for his pre-work on this
  29. *
  30. * Basic usage - tabbedChannels.init( dom_node_to_add_tabs_to );
  31. * and hook up tabbedChannels.proccessLine(lower_case_text, jquery_of_line_container); to each line detected by the system
  32. */
  33. var tabbedChannels = new function(){
  34. var _self = this;
  35.  
  36. // Default options
  37. this.channels = ["~","*",".","%","$","#",";","^","<3",":gov","#rpg","@"];
  38. this.mode = 'single';
  39.  
  40. // internals
  41. this.unread_counts = {};
  42. this.$el = null;
  43. this.$opt = null;
  44. this.defaultRoomClasses = '';
  45. this.channelMatchingCache = [];
  46.  
  47. //channels user is in currently
  48. this.currentRooms = 0;
  49.  
  50. // When channel is clicked, toggle it on or off
  51. this.toggle_channel = function(e){
  52. var channel = $(e.target).data("filter");
  53. if(channel===null)return; // no a channel
  54.  
  55. if(!$("#robinChatWindow").hasClass("robin-filter-" + channel)){
  56. _self.enable_channel(channel);
  57. $(e.target).addClass("selected");
  58. // clear unread counter
  59. $(e.target).find("span")[0].innerHTML = '0';
  60. _self.unread_counts[channel] = 0;
  61.  
  62. // set key indicatior (blanking others)
  63. _self.$el.find(".robin-filters").children("span").each(function(){$(this).find("span")[1].innerHTML = '◇';});
  64. $(e.target).find("span")[1].innerHTML = '◆';
  65. }else{
  66. $(e.target).removeClass("selected");
  67. _self.disable_channel(channel);
  68.  
  69. // set key indicators
  70. _self.$el.find(".robin-filters").children("span").each(function(){$(this).find("span")[1].innerHTML = '◇';});
  71. _self.$el.find("span[data-filter=" + _self.channels.indexOf($("#robinChatWindow").attr("data-channel-key")) + "]").find("span")[1].innerHTML = '◆';
  72. }
  73.  
  74. // scroll everything correctly
  75. _scroll_to_bottom();
  76. };
  77.  
  78. // Enable a channel
  79. this.enable_channel = function(channel_id){
  80.  
  81. // if using room type "single", deslect other rooms on change
  82. if(this.mode == "single"){
  83. this.disable_all_channels();
  84. }
  85.  
  86. $("#robinChatWindow").addClass("robin-filter robin-filter-" + channel_id);
  87. $("#robinChatWindow").attr("data-channel-key", this.channels[channel_id]);
  88. this.currentRooms++;
  89. // unselect show all
  90. _self.$el.find("span.all").removeClass("selected");
  91. };
  92.  
  93. // disable a channel
  94. this.disable_channel = function(channel_id){
  95. $("#robinChatWindow").removeClass("robin-filter-" + channel_id);
  96. // update key
  97. $("#robinChatWindow").attr("data-channel-key", $(".robin-filters span.selected").first().data("filter-name"));
  98. if(!$(".robin-filters span.selected").first().data("filter-name")) $("#robinChatWindow").attr("data-channel-key", "");
  99. this.currentRooms--;
  100.  
  101. // no rooms selcted, run "show all"
  102. if(this.currentRooms == 0) this.disable_all_channels();
  103. };
  104.  
  105. // turn all channels off
  106. this.disable_all_channels = function(e){
  107. $("#robinChatWindow").attr("class", _self.defaultRoomClasses);
  108. _self.$el.find(".robin-filters > span").removeClass("selected");
  109. this.currentRooms = 0;
  110.  
  111. // reset key indicators
  112. _self.$el.find(".robin-filters").children("span").each(function(){$(this).find("span")[1].innerHTML = '◇';});
  113.  
  114. _self.$el.find("span.all").addClass("selected");
  115. _scroll_to_bottom();
  116. };
  117.  
  118. // render tabs
  119. this.drawTabs = function(){
  120. html = '';
  121. for(var i in this.channels){
  122. if(typeof this.channels[i] === 'undefined') continue;
  123. html += '<span data-filter="' + i + '" data-filter-name="'+ this.channels[i] +'">' + this.channels[i] + ' (<span>0</span>) <span style="float:right;padding-right:4px;font-size:25px;height:0px;top:-11px;position:relative;">◇</span></span> ';
  124.  
  125.  
  126. }
  127. this.$el.find(".robin-filters").html(html);
  128. };
  129.  
  130. // Add new channel
  131. this.addChannel = function(new_channel){
  132. if(this.channels.indexOf(new_channel) === -1){
  133. this.channels.push(new_channel);
  134. this.unread_counts[this.channels.length-1] = 0;
  135. this.updateChannelMatchCache();
  136. this.saveChannelList();
  137.  
  138. // re-parse (and reset counters)
  139. $("#robinChatWindow").find("div.robin-message").each(function(idx,item){
  140. var line = $(item).find(".robin-message--message").text().toLowerCase();
  141. tabbedChannels.proccessLine(line, $(item));
  142. });
  143. for(var i in this.channels){
  144. this.unread_counts[i] = 0;
  145. }
  146.  
  147. this.drawTabs();
  148.  
  149. // refresh everything after redraw
  150. this.disable_all_channels();
  151. }
  152. };
  153.  
  154. // remove existing channel
  155. this.removeChannel = function(channel){
  156. if(confirm("are you sure you wish to remove the " + channel + " channel?")){
  157. var idx = this.channels.indexOf(channel);
  158. delete this.channels[idx];
  159. this.updateChannelMatchCache();
  160. this.saveChannelList();
  161.  
  162. // re-parse (and reset counters)
  163. $("#robinChatWindow").find("div.robin-message").each(function(idx,item){
  164. var line = $(item).find(".robin-message--message").text().toLowerCase();
  165. tabbedChannels.proccessLine(line, $(item));
  166. });
  167. for(var i in this.channels){
  168. this.unread_counts[i] = 0;
  169. }
  170.  
  171. this.drawTabs();
  172.  
  173. // refresh everything after redraw
  174. this.disable_all_channels();
  175. }
  176. };
  177.  
  178.  
  179. // save channel list
  180. this.saveChannelList = function(){
  181. // clean array before save
  182. var channels = this.channels.filter(function (item) { return item != undefined });
  183. GM_setValue("robin-enhance-channels", channels);
  184. };
  185.  
  186. // Change chat mode
  187. this.changeChannelMode = function(e){
  188. _self.mode = $(this).data("type");
  189.  
  190. // swicth bolding
  191. $(this).parent().find("span").css("font-weight","normal");
  192. $(this).css("font-weight","bold");
  193. _self.disable_all_channels();
  194.  
  195. // Update mode setting
  196. GM_setValue("robin-enhance-mode", _self.mode);
  197. };
  198.  
  199. this.updateChannelMatchCache = function(){
  200. var order = this.channels.slice(0);
  201. order.sort(function(a, b){
  202. return b.length - a.length; // ASC -> a - b; DESC -> b - a
  203. });
  204. for(var i in order){
  205. order[i] = this.channels.indexOf(order[i]);
  206. }
  207. // sorted array of channel name indexs
  208.  
  209. this.channelMatchingCache = order;
  210. };
  211.  
  212. // Procces each chat line to create text
  213. this.proccessLine = function(text, $element){
  214. var i, idx, channel;
  215.  
  216. $element.removeClass("in-channel");
  217.  
  218. for(i=0; i< this.channelMatchingCache.length; i++){
  219. $element.removeClass("robin-filter-" + this.channelMatchingCache[i]);
  220. }
  221.  
  222. for(i=0; i< this.channelMatchingCache.length; i++){
  223. idx = this.channelMatchingCache[i];
  224. channel = this.channels[idx];
  225.  
  226. if(typeof channel === 'undefined') continue;
  227.  
  228. if(text.indexOf(channel) === 0){
  229. $element.addClass("robin-filter-" + idx +" in-channel");
  230. this.unread_counts[idx]++;
  231. return;
  232. }
  233. }
  234. };
  235.  
  236. // If in one channel, auto add channel keys
  237. this.submit_helper = function(){
  238. if($("#robinChatWindow").hasClass("robin-filter")){
  239. // auto add channel key
  240. var channel_key = $("#robinChatWindow").attr("data-channel-key");
  241.  
  242. if($(".text-counter-input").val().indexOf("/me") === 0){
  243. $(".text-counter-input").val("/me " + channel_key + " " + $(".text-counter-input").val().substr(3));
  244. }else if($(".text-counter-input").val().indexOf("/") !== 0){
  245. // if its not a "/" command, add channel
  246. $(".text-counter-input").val(channel_key + " " + $(".text-counter-input").val());
  247. }
  248. }
  249. };
  250.  
  251. // Update everuything
  252. this.tick = function(){
  253. _self.$el.find(".robin-filters").children("span").each(function(){
  254. if($(this).hasClass("selected")) return;
  255. $(this).find("span")[0].innerHTML = _self.unread_counts[$(this).data("filter")];
  256. });
  257. };
  258.  
  259. // Init tab zone
  260. this.init = function($el){
  261. // Load channels
  262. if(GM_getValue("robin-enhance-channels")){
  263. this.channels = GM_getValue("robin-enhance-channels");
  264. }
  265. if(GM_getValue("robin-enhance-mode")){
  266. this.mode = GM_getValue("robin-enhance-mode");
  267. }
  268.  
  269. // init counters
  270. for(var i in this.channels){
  271. this.unread_counts[i] = 0;
  272. }
  273.  
  274. // update channel cache
  275. this.updateChannelMatchCache();
  276.  
  277. // set up el
  278. this.$el = $el;
  279.  
  280. // Create inital markup
  281. this.$el.html("<span class='all selected'>Everything</span><span><div class='robin-filters'></div></span><span class='more'>[Options]</span>");
  282. this.$opt = $("<div class='robin-channel-add' style='display:none'><input name='add-channel'><button>Add channel</button> <span class='channel-mode'>Channel Mode: <span title='View one channel at a time' data-type='single'>Single</span> | <span title='View many channels at once' data-type='multi'>Multi</span></span></div>").insertAfter(this.$el);
  283.  
  284. // Attach events
  285. this.$el.find(".robin-filters").click(this.toggle_channel);
  286. this.$el.find("span.all").click(this.disable_all_channels);
  287. this.$el.find("span.more").click(function(){ $(".robin-channel-add").slideToggle(); });
  288. this.$el.find(".robin-filters").bind("contextmenu", function(e){
  289. e.preventDefault();
  290. e.stopPropagation();
  291. var chan_id = $(e.target).data("filter");
  292. if(chan_id===null)return; // no a channel
  293. _self.removeChannel(_self.channels[chan_id]);
  294. });
  295. // Form events
  296. this.$opt.find(".channel-mode span").click(this.changeChannelMode);
  297. this.$opt.find("button").click(function(){
  298. var new_chan = _self.$opt.find("input[name='add-channel']").val();
  299. if(new_chan != '') _self.addChannel(new_chan);
  300. _self.$opt.find("input[name='add-channel']").val('');
  301. });
  302.  
  303.  
  304. $("#robinSendMessage").submit(this.submit_helper);
  305.  
  306. // store default room class
  307. this.defaultRoomClasses = $("#robinChatWindow").attr("class");
  308.  
  309. // redraw tabs
  310. this.drawTabs();
  311.  
  312. // start ticker
  313. setInterval(this.tick, 1000);
  314. }
  315. };
  316.  
  317. /**
  318. * Check if a message is "spam"
  319. */
  320. var is_spam = function(line){
  321. return (
  322. // Hide auto vote messages
  323. (/^voted to (grow|stay|abandon)/.test(line)) ||
  324. // random unicode?
  325. (/[\u0080-\uFFFF]/.test(line)) ||
  326. // hide any auto voter messages
  327. (/\[.*autovoter.*\]/.test(line)) ||
  328. // Common bots
  329. (/^(\[binbot\]|\[robin-grow\])/.test(line)) ||
  330. // repeating chars in line (more than 5). e.g. aaaaaaa !!!!!!!!
  331. (/(.)\1{5,}/.test(line)) ||
  332. // Some common messages
  333. (/(voting will end in approximately|\[i spam the most used phrase\]|\[message from creator\]|\[.*bot.*\])/.test(line)) ||
  334. // no spaces = spam if its longer than 25 chars (dont filter links)
  335. (line.indexOf(" ") === -1 && line.length > 25 && line.indexOf("http") === -1) ||
  336. // repeating same word
  337. /(\b\S+\b)\s+\b\1\b/i.test(line)
  338. );
  339. };
  340.  
  341. /**
  342. * Check if a message is from an ignored user
  343. *
  344. */
  345. var is_ignored = function($usr, $ele){
  346. // no user name, go looking for when said it
  347. if($usr.length === 0){
  348. while($usr.length === 0){
  349. $ele = $ele.prev();
  350. $usr = $ele.find(".robin--username");
  351. }
  352. }
  353. // are they ignored?
  354. return (ignored_users[$usr.text()]);
  355. };
  356.  
  357. /**
  358. * Make links clickable
  359. *
  360. */
  361. var auto_link = function($msg){
  362. var text = $msg.html(); // read as html so stuff stays escaped
  363. // normal links
  364. text = text.replace(/\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|]/gim, '<a target="blank" href="$&">$&</a>');
  365. // reddit subreddit links
  366. text = text.replace(/ \/r\/(\w+)/gim, ' <a target="blank" href="https://reddit.com/r/$1">/r/$1</a>');
  367. // update text
  368. $msg.html(text);
  369. };
  370.  
  371. /**
  372. * Mute a user
  373. */
  374. var _mute_user = function(usr){
  375. // Add to ignore list
  376. ignored_users[usr] = true;
  377. _render_muted_list();
  378. };
  379.  
  380. /**
  381. * un-mute a user
  382. */
  383. var _unmute_user = function(usr){
  384. // Add to ignore list
  385. delete ignored_users[usr];
  386. _render_muted_list();
  387. };
  388.  
  389. // Render list of ignored users
  390. var _render_muted_list = function(){
  391. var html = "<strong>Ignored users</strong><br>";
  392. for(var u in ignored_users){
  393. html += "<div data-usr='"+ u + "'>" + u + " - [unmute]</div>";
  394. }
  395. $("#muted_users").html(html);
  396. };
  397.  
  398. // Scroll chat back to bottom
  399. var _scroll_to_bottom = function(){
  400. $("#robinChatWindow").scrollTop($("#robinChatMessageList").height());
  401. };
  402.  
  403. var update_spam_count = function(){
  404. blocked_spam++;
  405. blocked_spam_el.innerHTML = blocked_spam;
  406. };
  407.  
  408. var fill_name = function(e){
  409. e.preventDefault();
  410. e.stopPropagation();
  411.  
  412. // if text area blank, prefill name. if not, stick it on the end
  413. if($(".text-counter-input").val() === ''){
  414. $(".text-counter-input").val($(this).text() + ' ').focus();
  415. }else{
  416. $(".text-counter-input").val($(".text-counter-input").val() + ' ' + $(this).text()).focus();
  417. }
  418. };
  419.  
  420. /**
  421. * Parse a link and apply changes
  422. */
  423. var parse_line = function($ele){
  424. var $msg = $ele.find(".robin-message--message");
  425. var $usr = $ele.find(".robin--username");
  426. var line = $msg.text().toLowerCase();
  427. // dont parse system messages
  428. if($ele.hasClass("robin--user-class--system")){
  429. if(line.indexOf("ratelimit | you are doing that too much") !== -1){
  430. $(".text-counter-input").val(user_last_message);
  431. }
  432. return;
  433. }
  434.  
  435. // If user is ignored or message looks like "Spam". hide it
  436. if (is_ignored($usr, $ele) || is_spam(line)) {
  437. $ele.addClass("spam-hidden");
  438. update_spam_count();
  439. }
  440.  
  441. // Highlight mentions
  442. if(line.indexOf(robin_user) !== -1){
  443. $ele.addClass("user-mention");
  444. }
  445.  
  446. // Make links clickable
  447. if(!_robin_grow_detected && line.indexOf("http") !== -1){
  448. auto_link($msg);
  449. }
  450.  
  451. // Add mute button to users
  452. if(!$ele.hasClass("robin--user-class--system") && $usr.text() != robin_user){
  453. $("<span style='font-size:.8em;cursor:pointer'> [mute] </span>").insertBefore($usr).click(function(){
  454. _mute_user($usr.text());
  455. });
  456. }
  457.  
  458. // Track channels
  459. tabbedChannels.proccessLine(line, $ele);
  460.  
  461. // bind click to use (override other click events if we can)
  462. $usr.bindFirst("click", fill_name);
  463. };
  464.  
  465.  
  466. // Detect changes, are parse the new message
  467. $("#robinChatWindow").on('DOMNodeInserted', function(e) {
  468. if ($(e.target).is('div.robin-message')) {
  469. // Apply changes to line
  470. parse_line($(e.target));
  471. }
  472. });
  473.  
  474. // When everything is ready
  475. $(document).ready(function(){
  476.  
  477. // Set default spam filter type
  478. $("#robinChatWindow").addClass("hide-spam");
  479.  
  480. // Add checkbox to toggle "hide" behaviors
  481. $("#robinDesktopNotifier").append("<label><input type='checkbox' checked='checked'>Hide spam completely (<span id='spamcount'>0</span> removed)</label>").click(function(){
  482. if($(this).find("input").is(':checked')){
  483. $("#robinChatWindow").removeClass("mute-spam").addClass("hide-spam");
  484. }else{
  485. $("#robinChatWindow").removeClass("hide-spam").addClass("mute-spam");
  486. }
  487. // correct scroll after spam filter change
  488. _scroll_to_bottom();
  489. });
  490.  
  491. blocked_spam_el = $("#spamcount")[0];
  492.  
  493. // Add Muted list & hook up unmute logic
  494. $('<div id="muted_users" class="robin-chat--sidebar-widget robin-chat--notification-widget"><strong>Ignored users</strong></div>').insertAfter($("#robinDesktopNotifier"));
  495. $('#muted_users').click(function(e){
  496. var user = $(e.target).data("usr");
  497. if(user) _unmute_user(user);
  498. });
  499.  
  500. // Init tabbed channels
  501. tabbedChannels.init($('<div id="filter_tabs"></div>').insertAfter("#robinChatWindow"));
  502.  
  503. // store i copy of last message, in case somthing goes wrong (rate limit)
  504. $("#robinSendMessage").submit(function(){
  505. user_last_message = $(".text-counter-input").val();
  506. });
  507.  
  508. //test for msgcount
  509. //for(i = 0; i < 10000; i++){
  510. // $("#robinChatMessageList").append('<div class="robin-message robin--flair-class--flair-2 robin--message-class--message robin--user-class--user robin-filter-0 in-channel"><time class="robin-message--timestamp" datetime="2016-04-06T01:57:24.567Z">11:57:24</time><span class="robin-message--from robin--username">hFUIEHBSDHYIDYBEHY</span><span class="robin-message--message">test</span></div>');
  511. //}
  512.  
  513. });
  514.  
  515. // fix by netnerd01
  516. var stylesheet = document.createElement('style');
  517. document.head.appendChild(stylesheet);
  518. stylesheet = stylesheet.sheet;
  519.  
  520. // filter for channel
  521. stylesheet.insertRule("#robinChatWindow.robin-filter div.robin-message { display:none; }", 0);
  522. stylesheet.insertRule("#robinChatWindow.robin-filter div.robin-message.robin--user-class--system { display:block; }", 0);
  523. for(var c=0;c<35;c++){
  524. stylesheet.insertRule("#robinChatWindow.robin-filter.robin-filter-"+c+" div.robin-message.robin-filter-"+c+" { display:block; }", 0);
  525. }
  526.  
  527. // Styles for filter tabs
  528. stylesheet.insertRule("#filter_tabs {width:100%; display: table; table-layout: fixed; background:#d7d7d2; border-bottom:1px solid #efefed;}",0);
  529. stylesheet.insertRule("#filter_tabs > span {width:90%; display: table-cell;}",0);
  530. stylesheet.insertRule("#filter_tabs > span.all, #filter_tabs > span.more {width:60px; text-align:center; vertical-align:middle; cursor:pointer;}",0);
  531. stylesheet.insertRule("#filter_tabs > span.all.selected, #filter_tabs > span.all.selected:hover {background: #fff;}", 0);
  532. stylesheet.insertRule("#filter_tabs .robin-filters { display: table; width:100%;table-layout: fixed; '}", 0);
  533. stylesheet.insertRule("#filter_tabs .robin-filters > span { padding: 5px 2px;text-align: center; display: table-cell; cursor: pointer;width:2%; vertical-align: middle; font-size: 1.1em;}", 0);
  534. stylesheet.insertRule("#filter_tabs .robin-filters > span.selected, #filter_tabs .robin-filters > span:hover { background: #fff;}", 0);
  535. stylesheet.insertRule("#filter_tabs .robin-filters > span > span {pointer-events: none;}", 0);
  536.  
  537. stylesheet.insertRule(".robin-channel-add {padding:5px; display:none;}", 0);
  538. stylesheet.insertRule(".robin-channel-add input {padding: 2.5px; }", 0);
  539. stylesheet.insertRule(".robin-channel-add .channel-mode {float:right; font-size:1.2em;padding:5px;}", 0);
  540. stylesheet.insertRule(".robin-channel-add .channel-mode span {cursor:pointer}", 0);
  541. //mentions should show even in filter view
  542. stylesheet.insertRule("#robinChat #robinChatWindow div.robin-message.user-mention { display:block; font-weight:bold; }", 0);
  543.  
  544. // Add initial styles for "spam" messages
  545. stylesheet.insertRule("#robinChat #robinChatWindow.hide-spam div.robin-message.spam-hidden { display:none; }", 0);
  546. stylesheet.insertRule("#robinChat #robinChatWindow.mute-spam div.robin-message.spam-hidden { opacity:0.3; font-size:1.2em; }", 0);
  547.  
  548. // muted user box
  549. stylesheet.insertRule("#muted_users { font-size:1.2em; }", 0);
  550. stylesheet.insertRule("#muted_users div { padding: 2px 0; }", 0);
  551. stylesheet.insertRule("#muted_users strong { font-weight:bold; }", 0);
  552.  
  553. // FIX RES nightmode (ish) [ by Kei ]
  554. stylesheet.insertRule(".res-nightmode #robinChatWindow div.robin-message { color: #ccc; }", 0);
  555. stylesheet.insertRule(".res-nightmode .robin-chat--sidebar-widget { background: #222; color: #ccc;}", 0);
  556. stylesheet.insertRule(".res-nightmode .robin-room-participant { background: #222; color: #999;}", 0);
  557. stylesheet.insertRule(".res-nightmode #filter_tabs {background: rgb(51, 51, 51);}", 0);
  558. stylesheet.insertRule(".res-nightmode #filter_tabs .robin-filters > span.selected,.res-nightmode #filter_tabs .robin-filters > span:hover,.res-nightmode #filter_tabs > span.all.selected,.res-nightmode #filter_tabs > span.all:hover {background: rgb(34, 34, 34)}", 0);
  559. stylesheet.insertRule(".res-nightmode .robin-chat--input { background: #222 }", 0);
  560. stylesheet.insertRule(".res-nightmode .robin--presence-class--away .robin--username {color: #999;}", 0);
  561. stylesheet.insertRule(".res-nightmode .robin--presence-class--present .robin--username {color: #ccc;}", 0);
  562. stylesheet.insertRule(".res-nightmode #robinChat .robin--user-class--self .robin--username { color: #999; }", 0);
  563. stylesheet.insertRule(".res-nightmode .robin-chat--vote { background: #777; color: #ccc;}", 0);
  564. stylesheet.insertRule(".res-nightmode .robin-chat--buttons button.robin-chat--vote.robin--active { background: #ccc; color:#999; }", 0);
  565.  
  566. $(document).ready(function(){
  567. setTimeout(function(){
  568. // Play nice with robin grow (makes room for tab bar we insert)
  569. if($(".usercount.robin-chat--vote").length !== 0){
  570. _robin_grow_detected = true;
  571. stylesheet.insertRule("#robinChat.robin-chat .robin-chat--body { height: calc(100vh - 150px); }", 0);
  572. }
  573. },500);
  574. });
  575.  
  576. // Allow me to sneek functions in front of other libaries - used when working with robin grow >.< sorry guys
  577. //http://stackoverflow.com/questions/2360655/jquery-event-handlers-always-execute-in-order-they-were-bound-any-way-around-t
  578. $.fn.bindFirst = function(name, fn) {
  579. // bind as you normally would
  580. // don't want to miss out on any jQuery magic
  581. this.on(name, fn);
  582.  
  583. // Thanks to a comment by @Martin, adding support for
  584. // namespaced events too.
  585. this.each(function() {
  586. var handlers = $._data(this, 'events')[name.split('.')[0]];
  587. // take out the handler we just inserted from the end
  588. var handler = handlers.pop();
  589. // move it at the beginning
  590. handlers.splice(0, 0, handler);
  591. });
  592. };
  593.  
  594. })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement