1 /** 2 * This is a library to handle custom filtering of Twitter timelines based on 3 * usernames and message content 4 * @constructor 5 * @param {Object} opts 6 * @param {string} opts.name name of filter 7 * @param {string} opts.type whitelist or blacklist (default) 8 * @deprecated 9 */ 10 SpazTimelineFilter = function(opts) { 11 12 if (!opts) { opts = {}; }; 13 14 if (opts.type !== 'whitelist') { opts.type = 'blacklist'; }; 15 16 this.settings = { 17 name : opts.name || 'unnamed', 18 type : opts.type, 19 usernames_show : opts.usernames_show || [], 20 usernames_hide : opts.usernames_hide || [], 21 content_show : opts.content_show || [], 22 content_hide : opts.content_hide || [], 23 filter_class_prefix: opts.filter_class_prefix || 'customfilter-', 24 timeline_selector: opts.timeline_selector || 'div.timeline', 25 entry_selector : opts.entry_selector || 'div.timeline-entry', 26 username_attr : opts.username_attr || 'data-user-screen_name', 27 content_selector:opts.content_selector || 'div.timeline-entry status-text', 28 style_selector : opts.style_selector || 'style[title="custom-timeline-filters"]' 29 }; 30 // this.settings = { 31 // name : 'php-people', 32 // type : 'whitelist', // whitelist | blacklist 33 // usernames_show : [], 34 // usernames_hide : [], 35 // content_show : [], 36 // content_hide : [], 37 // filter_class_prefix: 'customfilter-', 38 // timeline_selector: 'div.timeline', 39 // entry_selector : 'div.timeline-entry', 40 // username_attr : 'data-user-screen_name', 41 // content_selector:'div.timeline-entry status-text', 42 // style_selector : 'style[title="custom-timeline-filters"]' 43 // } 44 45 }; 46 47 48 49 /** 50 * this generates the base selector for timeline entries based on 51 * the opts given to the constructor 52 * @return {string} 53 */ 54 SpazTimelineFilter.prototype.getBaseSelector = function() { 55 var base_sel = this.settings.timeline_selector+ 56 "."+this.getTimelineClass()+ 57 " "+this.settings.entry_selector; 58 return base_sel; 59 }; 60 61 /** 62 * this returns the timeline class we'll apply to the timeline container 63 */ 64 SpazTimelineFilter.prototype.getTimelineClass = function() { 65 return this.settings.filter_class_prefix+this.settings.name; 66 }; 67 68 /** 69 * This generates the user-filtering CSS rules 70 * @return {array} 71 */ 72 SpazTimelineFilter.prototype.getUserCSS = function() { 73 var base_sel = '', rule = '', rules = [], thisuser; 74 75 base_sel = this.getBaseSelector(); 76 77 /* 78 start with white or black 79 */ 80 if (this.settings.type === 'whitelist') { 81 rule = base_sel+" { display:none; }"; 82 rules.push(rule); 83 } 84 else if (this.settings.type === 'blacklist') { 85 rule = base_sel+" { display:block; }"; 86 rules.push(rule); 87 } else { 88 return null; 89 } 90 91 /* 92 add usernames to show 93 */ 94 for (var i=0; i < this.settings.usernames_show.length; i++) { 95 thisuser = this.settings.usernames_show[i]; 96 rule = base_sel+"["+this.settings.username_attr+"='"+thisuser+"'] { display:block; }"; 97 rules.push(rule); 98 }; 99 100 /* 101 add usernames to hide 102 */ 103 for (var i=0; i < this.settings.usernames_hide.length; i++) { 104 thisuser = this.settings.usernames_show[i]; 105 rule = base_sel+"["+this.settings.username_attr+"='"+thisuser+"'] { display:none; }"; 106 rules.push(rule); 107 }; 108 109 return rules.join("\n"); 110 }; 111 112 113 /** 114 * This takes a string of comma-delimited usernames and "hide" OR "show" and 115 * parses it into the arrays used in this.settings 116 * @param {string} str string of usernames, separated by commas 117 * @param {string} hide_or_show 'hide' or 'show'. defaults to 'show' 118 */ 119 SpazTimelineFilter.prototype.parseUsersFromString = function(str, hide_or_show) { 120 121 if (hide_or_show !== 'hide') { hide_or_show = 'show'; } 122 var users = str.split(','); 123 for (var i=0; i < users.length; i++) { 124 users[i] = sch.trim(users[i]); 125 }; 126 127 this.parseUsersFromArray(users, hide_or_show); 128 }; 129 130 /** 131 * This takes an array of usernames and "hide" OR "show" and 132 * parses it into the arrays used in this.settings 133 * @param {array} user_arr array of usernames 134 * @param {string} hide_or_show 'hide' or 'show'. defaults to 'show' 135 */ 136 SpazTimelineFilter.prototype.parseUsersFromArray = function(user_arr, hide_or_show) { 137 138 if (hide_or_show !== 'hide') { hide_or_show = 'show'; } 139 140 if (hide_or_show === 'hide') { 141 this.usernames_hide = user_arr; 142 } else { 143 this.usernames_show = user_arr; 144 } 145 }; 146 147 148 /** 149 * This takes a username and "hide" or "show" and adds it to the appropriate 150 * array in this.settings 151 * @param {string} str the username 152 * @param {string} hide_or_show 'hide' or 'show'. defaults to 'show' 153 */ 154 SpazTimelineFilter.prototype.addUser = function(str, hide_or_show) { 155 156 if (hide_or_show !== 'hide') { hide_or_show = 'show'; } 157 158 var username = sch.trim(str); 159 160 if (hide_or_show === 'hide') { 161 this.usernames_hide.push(username); 162 } else { 163 this.usernames_show.push(username); 164 } 165 166 }; 167 168 /** 169 * This takes a string of comma-delimited strings and "hide" OR "show" and 170 * parses it into the content string filter arrays used in this.settings 171 * @param {string} str string of strings, separated by commas 172 * @param {string} hide_or_show 'hide' or 'show'. defaults to 'show' 173 */ 174 SpazTimelineFilter.prototype.parseContentStringsFromString = function(str, hide_or_show) { 175 if (hide_or_show !== 'hide') { hide_or_show = 'show'; } 176 var contentstrings = str.split(','); 177 for (var i=0; i < contentstrings.length; i++) { 178 contentstrings[i] = sch.trim(contentstrings[i]); 179 }; 180 181 this.parseContentStringsFromArray(contentstrings, hide_or_show); 182 }; 183 184 /** 185 * This takes an array of comma-delimited strings and "hide" OR "show" and 186 * parses it into the content string filter arrays used in this.settings 187 * @param {array} str_arr array of strings 188 * @param {string} hide_or_show 'hide' or 'show'. defaults to 'show' 189 */ 190 SpazTimelineFilter.prototype.parseContentStringsFromArray = function(str_arr, hide_or_show) { 191 192 if (hide_or_show !== 'hide') { hide_or_show = 'show'; } 193 194 if (hide_or_show === 'hide') { 195 this.content_hide = str_arr; 196 } else { 197 this.content_show = str_arr; 198 } 199 200 }; 201 202 /** 203 * This takes a string and "hide" or "show" and adds it to the appropriate 204 * content string filter array in this.settings 205 * @param {string} str the string 206 * @param {string} hide_or_show 'hide' or 'show'. defaults to 'show' 207 */ 208 SpazTimelineFilter.prototype.addContentString = function(str, hide_or_show) { 209 if (hide_or_show !== 'hide') { hide_or_show = 'show'; } 210 211 var contentstring = sch.trim(str); 212 213 if (hide_or_show === 'hide') { 214 this.content_hide.push(contentstring); 215 } else { 216 this.content_show.push(contentstring); 217 } 218 }; 219 220 /** 221 * returns the current this.settings object as JSON. Mainly this is for 222 * saving the settings to some permanent data store 223 */ 224 SpazTimelineFilter.prototype.settingsToJSON = function() { 225 226 return sch.enJSON(this.settings); 227 228 }; 229 230 /** 231 * takes JSON, decodes it, and assigns it to this.settings. Mainly this is 232 * for loading the settings from a file or DB 233 * @param {string} json 234 */ 235 SpazTimelineFilter.prototype.settingsFromJSON = function(json) { 236 237 this.settings = sch.deJSON(json); 238 239 }; 240 241 /** 242 * This applies the user filtering CSS by inserting it into the <style> 243 * tag designated by this.settings.style_selector 244 */ 245 SpazTimelineFilter.prototype.applyUserCSS = function() { 246 jQuery(this.settings.style_selector).text( this.getUserCSS() ); 247 }; 248 249 /** 250 * this clears the CSS code inside the <style> tag 251 */ 252 SpazTimelineFilter.prototype.disableUserCSS = function() { 253 jQuery(this.settings.style_selector).text(''); 254 }; 255 256 /** 257 * This applies the content filters by hiding and showing elements via jQuery 258 */ 259 SpazTimelineFilter.prototype.applyContentFilters = function() { 260 var thiscontent; 261 262 var contentfilters = this.buildContentFilterSelectors(); 263 var jq_entries = jQuery(this.getBaseSelector()); 264 265 for (var i=0; i < contentfilters.hide.length; i++) { 266 jq_entries.filter(contentfilters.hide[i]).hide(); 267 } 268 for (var i=0; i < contentfilters.show.length; i++) { 269 jq_entries.filter(contentfilters.show[i]).show(); 270 } 271 }; 272 273 /** 274 * This disables the content filters by showing *everything* 275 */ 276 SpazTimelineFilter.prototype.disableContentFilters = function() { 277 var jq_entries = jQuery(this.getBaseSelector()); 278 jq_entries.filter().show(); 279 }; 280 281 /** 282 * this builds the content filtering selectors used by jQuery to hide and 283 * show elements based on content 284 */ 285 SpazTimelineFilter.prototype.buildContentFilterSelectors = function() { 286 287 var contentfilters = { 288 'hide':[], 289 'show':[] 290 }; 291 292 for (var i=0; i < this.settings.content_hide.length; i++) { 293 thiscontent = this.settings.content_hide[i]; 294 contentfilters.hide.push(':contains("'+thiscontent+'")'); 295 } 296 for (var i=0; i < this.settings.content_show.length; i++) { 297 thiscontent = this.settings.content_show[i]; 298 contentfilters.show.push(':contains("'+thiscontent+'")'); 299 } 300 return contentfilters; 301 }; 302 303 /** 304 * Apply user and content filtering 305 */ 306 SpazTimelineFilter.prototype.apply = function() { 307 this.applyUserCSS(); 308 this.applyContentFilters(); 309 }; 310 311 /** 312 * Disable user and content filtering 313 */ 314 SpazTimelineFilter.prototype.disable = function() { 315 this.disableUserCSS(); 316 this.disableContentFilters(); 317 }; 318