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