1- var ALL_GROUPS = [ 249598592040574 , 1378294582253698 , 2224932161064321 , 1924443867832338 , 1922538421363451 , 1920036621597031 , 1903916609822504 , 1841081392797911 , 1806620552895262 , 1780072415645281 , 1741843536047014 , 1724152667880378 , 1607133026028061 , 1494181493938081 , 1443394385967980 , 1258355007573190 , 1152576018114322 , 1148469218498930 , 1075017422642967 , 1074858042611323 , 1071045349642536 , 1041205739348709 , 893652180764182 , 886251554842166 , 885490321621308 , 854314664699156 , 826341790867138 , 813879575430133 , 811281355669013 , 793016410839401 , 786453984830109 , 638854212931776 , 485698195138488 , 476463749198108 , 428973767504677 , 402137910152010 , 362906487478469 , 348458995586076 , 332006040559709 , 313087542449350 , 309450039518404 , 304477986647756 , 293458267749614 , 265793323822652 , 223094988221674 , 199036970608482 , 187217085094857 , 186924858495604 , 160941794378470 , 152127978670639 , 132580147377707 , 125327974795168 , 111858152705945 ] ; // all public groups
2-
31// remove blacklisted groups
4- for ( let groupId of fbDevInterest . _blacklist ) {
5- let idx = ALL_GROUPS . indexOf ( parseInt ( groupId , 10 ) ) ;
6- ALL_GROUPS . splice ( idx , 1 ) ;
2+ fbDevInterest . clearBlacklist = function ( ) {
3+ for ( let groupId of this . _blacklist ) {
4+ let idx = this . ALL_GROUPS . indexOf ( parseInt ( groupId , 10 ) ) ;
5+ this . ALL_GROUPS . splice ( idx , 1 ) ;
6+ }
77}
88
99fbDevInterest . createPlaceholder = function ( ) {
@@ -18,35 +18,85 @@ fbDevInterest.BASE_API_URL = `https://graph.facebook.com/v2.11/GROUPID/?&access_
1818
1919// gets a group id from ALL_GROUPS list
2020fbDevInterest . getGroupId = { } ;
21- fbDevInterest . getGroupId = ( function * ( ) {
22- let i = - 1 ;
21+ fbDevInterest . getGroupId = function ( ) {
22+ const self = this ;
23+ let i = - 1 ;
24+ return ( function * ( ) {
2325 while ( true ) {
24- yield this . ALL_GROUPS [ ++ i % ALL_GROUPS . length ] ;
26+ yield self . ALL_GROUPS [ ++ i % self . ALL_GROUPS . length ] ;
2527 } ;
2628 } ) ( ) ;
29+ }
2730
2831fbDevInterest . parent = document . querySelector ( '#pagelet_group_mall' ) ; // feed parent
2932fbDevInterest . state = { } ; // stores next fetch urls for group and group names
3033
31-
32- fbDevInterest . satisfiesFilters = function ( content ) {
33- if ( this . _keywords . size === 0 ) return true ;
34+ // find matching keywords in post body
35+ fbDevInterest . findMatchedKeywords = function ( content ) {
36+ if ( this . _keywords . size === 0 ) return [ [ 0 , 0 ] ] ;
3437 const $content = content . toLowerCase ( ) ;
38+ const matches = [ ] ;
3539 for ( const keyword of this . _keywords ) {
36- if ( $content . includes ( keyword ) ) return true ;
40+ const re = new RegExp ( `(?:^|\\b)(${ keyword . replace ( / \s \s + / g, '\\s*' ) } )(?=\\b|$)` ) ;
41+ const match = $content . match ( re ) ;
42+ if ( match ) matches . push ( [ match . index , match [ 0 ] . length ] )
3743 }
38- return false ;
44+ function compare ( a , b ) {
45+ if ( a [ 0 ] < b [ 0 ] ) return - 1 ;
46+ if ( a [ 0 ] > b [ 0 ] ) return 1 ;
47+ if ( a [ 1 ] < b [ 1 ] ) return 1 ; // to have larger keyword before
48+ if ( a [ 1 ] > b [ 1 ] ) return - 1 ;
49+ return 0 ;
50+ }
51+ return matches . sort ( compare ) ;
52+ }
53+
54+ // highlight matched keywords in post body
55+ fbDevInterest . highlightMatches = function ( str , matches ) {
56+ let $str = ''
57+ let pos ;
58+ let flag = 0 ;
59+ const alreadyIncludedStart = new Set ( ) ;
60+ for ( let i = 0 ; i < matches . length ; ++ i ) {
61+ pos = ( i === 0 ) ? 0 : matches [ i - 1 ] [ 0 ] + matches [ i - 1 ] [ 1 ] ;
62+ const [ $start , $length ] = matches [ i ] ;
63+ if ( alreadyIncludedStart . has ( $start ) ) {
64+ flag = matches [ i - 1 ] [ 0 ] + matches [ i - 1 ] [ 1 ] ;
65+ continue ; // to prevent highlight again if a smaller keyword in a larger keyword
66+ }
67+ alreadyIncludedStart . add ( $start ) ;
68+ $str += `${ str . substring ( flag !== 0 ? flag : pos , $start ) } <mark>${ str . substring ( $start , $start + $length ) } </mark>` ;
69+ flag = 0 ;
70+ }
71+ const lastMatch = matches [ matches . length - 1 ] ;
72+ $str += str . substring ( lastMatch [ 0 ] + lastMatch [ 1 ] ) ;
73+ return $str ;
74+ }
75+
76+ // split post body if too long
77+ fbDevInterest . splitPostBody = function ( content ) {
78+ const splitted = content . split ( '</p>' ) ;
79+ if ( splitted . length < 6 ) return content ;
80+ const visible = splitted . slice ( 0 , 6 ) . join ( '</p>' ) ;
81+ const hidden = splitted . slice ( 6 ) . join ( '</p>' ) ;
82+
83+ const id = Math . random ( ) . toString ( ) . replace ( '.' , '' ) ;
84+ const postBody = `<div id="id_${ id } " class="text_exposed_root">${ visible } <span class="text_exposed_hide">...</span><div class="text_exposed_show">${ hidden } </div><span class="text_exposed_hide"> <span class="text_exposed_link"><a class="see_more_link" onclick="var func = function(e) { e.preventDefault(); }; var parent = Parent.byClass(this, 'text_exposed_root'); if (parent && parent.getAttribute('id') == 'id_${ id } ') { CSS.addClass(parent, 'text_exposed'); Arbiter.inform('reflow'); }; func(event); "><span class="see_more_link_inner">See more</span></a></span></span></div>` ;
85+ return postBody ;
3986}
4087
4188// appends a post in feed
4289fbDevInterest . showPost = function ( entry , group ) {
4390 if ( ! entry . message ) return ;
44- if ( ! this . satisfiesFilters ( entry . message ) ) return ;
91+ const matchedKeywords = this . findMatchedKeywords ( entry . message ) ;
92+ if ( matchedKeywords . length === 0 ) return ;
93+ if ( this . _highlightMatches ) entry . message = this . highlightMatches ( entry . message , matchedKeywords ) ;
4594 entry . message = entry . message . replace ( / \n / g, "</p><p>" ) . linkify ( ) ;
95+
4696 if ( entry . link && ! entry . full_picture ) {
47- entry . message = `${ entry . message } </p><p>[<a href="${ entry . link } " target="_blank">${ entry . link } </a>]` ;
97+ entry . message = `${ entry . message } </p><p>[<b>LINK:</b> < a href="${ entry . link } " target="_blank">${ entry . link } </a>]` ;
4898 }
49-
99+ entry . message = this . splitPostBody ( entry . message ) ;
50100 const created_time = new Date ( entry . created_time ) ;
51101
52102 const image = ( entry . full_picture && ! entry . full_picture . includes ( '//external.' ) )
@@ -58,7 +108,7 @@ fbDevInterest.showPost = function(entry, group) {
58108 <div></div>
59109 <div class="_5pcr userContentWrapper">
60110 <div class="_1dwg _1w_m _q7o">
61- <h5>
111+ <h5 class="_5pbw fwb" >
62112 <a href="https://www.facebook.com/${ entry . from . id } ">${ entry . from . name } </a>
63113 ▶
64114 <a href="https://www.facebook.com/${ group . id } ">${ group . name } </a>
@@ -95,8 +145,6 @@ fbDevInterest.getGroupFeed = function(options) {
95145 fetchUrl = state . nextPageUrl ;
96146 }
97147
98- console . log ( fetchUrl )
99-
100148 fetch ( fetchUrl )
101149 . then ( ( res ) => res . json ( ) )
102150 . then ( json => {
@@ -139,6 +187,8 @@ fbDevInterest.clearPosts = function() {
139187} ;
140188
141189fbDevInterest . getFeed = function ( ) {
190+ this . clearBlacklist ( ) ;
191+ this . getGroupId = this . getGroupId ( ) ;
142192 this . clearPosts ( ) ;
143193 for ( let i = 0 ; i < 5 ; ++ i ) this . parent . appendChild ( this . createPlaceholder ( ) ) ;
144194 scrollToItem ( this . parent ) ;
@@ -160,7 +210,3 @@ fbDevInterest.showPostsOnScroll = function() {
160210 } ;
161211 window . addEventListener ( 'scroll' , onVisible , true )
162212}
163-
164- console . log ( '<<< fbDevInterest >>>' ) ;
165- fbDevInterest . parent . innerHTML = '' ;
166- fbDevInterest . getFeed ( ) ;
0 commit comments