thread rebuilder. All features working
[4Free-FSE.git] / src / image-hider.ts
blob14266f48ecf0f7efdbe9281887bec7aa5a4a0333
2 class ImageHider extends FeatureInterface{
3         blank_png:string = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAACXBIWXMAALiMAAC4jAHM9rsvAAAA
4                                                                                                 G3RFWHRTb2Z0d2FyZQBDZWxzeXMgU3R1ZGlvIFRvb2zBp+F8AAAAo0lEQVR42u3RAQ0AAAjDMO5
5                                                                                                 f9LFBSCdhTdvRnQIEiIAAERAgAgJEQIC4AERAgAgIEAEBIiBABERAgAgIEAEBIiBABERAgAgIEAE
6                                                                                                 BIiBABERAgAgIEAEBIiBABERAgAgIEAEBIiBABERAgAgIEAEBIiBABERAgAgIEAEBIiBABERAgAg
7                                                                                                 IEAEBIiBABERAgAgIEAEBIiBABAQIECACAkRAgAjI9xbzUCtI4axs4wAAAABJRU5ErkJggg==`;
9         hide_expiration_time:number;
10         threads_to_hide:string[];
11         md5_filters_arr:string[];
12         
13         constructor(){
14                 super();
15                 this.retrieveStates();
16                 this.init();
17                 this.activate();
18         }
19         
20         //retrieve from memory the hidden images
21         //Images are stored in memory as f<ID_NUMBER>IMG and recalled using the storage_key
22         //Function makes a check to see if the hiding time limit for the thread has expired or not.
23         //Note: Must have the DOM itterate through before retrieval
24         retrieveStates():void{
25                 var storage_position:number = 0;
26         var JSON_storage:any = {};/*;any bypasses dot notation issues on objects*/
27                 var storage_key:string;
28                 var local_store_size = window.localStorage.length;
29                 while(storage_position < local_store_size) {
30                         storage_key = window.localStorage.key(storage_position);
31                         JSON_storage[storage_key] = window.localStorage.getItem(storage_key);
32                         storage_position++;
33                 }
34                 this.threads_to_hide = Generics.getJSONPropertiesByKeyName(JSON_storage,'[0-9]+IMG');
35                 //aquire each time to check for changes
36                 this.hide_expiration_time =  parseInt(JSON_storage.Expiration_Time);
37                 if(this.hide_expiration_time === null) this.hide_expiration_time = Constants.DEFAULT_HIDE_EXPIRATION_TIME;
38                 var md5_filters = JSON_storage.MD5_List_FSE;    
39                 if(md5_filters !== undefined && md5_filters !== null){
40                         this.md5_filters_arr = md5_filters.split('\n');
41                         //remove trailing and starting slash
42                         this.md5_filters_arr.forEach((md5, index) => {
43                                 md5 = md5.trim();
44                                 this.md5_filters_arr[index] = md5.substring(1, md5.length - 1);
45                         });
46                 }
47         }
48         
49         storeStates(...item_pairs:string[]):void{
50                 window.localStorage.setItem(item_pairs[0], item_pairs[1]);      
51         }
52         
53         init():void{    }
54         
55         //hide image onclick listener.
56         //Method 404's a given image. This 404'ing allows image dissabling to be toggled on and off.
57         //Post number associated with the image is stored in local storage.
58         hideOnClick(event:any):boolean{
59                 var is_hidden =  event.target.src.substring(21, 29) == ",iVBORw0";
60                 var hide_group_id:string;
61                 if((event.ctrlKey && event.shiftKey) && !is_hidden){
62                         event.preventDefault();
63                         event.stopPropagation();
64                         hide_group_id = event.target.getAttribute('hide-grouping');
65                         this.storeStates(hide_group_id, `${Date.now()}`);               
66                         [].slice.call(document.querySelectorAll('img[hide-grouping="' + hide_group_id + '"]')).forEach((image_node) => {
67                                 image_node.setAttribute('hidden-src', image_node.src);
68                                 image_node.src = this.blank_png;
69                         });
70                         return false;
71                 }
72                 else if(event.ctrlKey && event.shiftKey){
73                         event.preventDefault();
74                         event.stopPropagation();
75                         hide_group_id = event.target.getAttribute('hide-grouping');
76                         window.localStorage.removeItem(hide_group_id);
77                         event.target.src = event.target.getAttribute('hidden-src');
78                         [].slice.call(document.querySelectorAll('img[hide-grouping="' + hide_group_id + '"]')).forEach((image_node) => {
79                                 image_node.src = image_node.getAttribute('hidden-src');
80                         });
81                         return false;
82                 }
83                 return true;
84         }
85         
86         decideAction(node:any):void{
87                 //tagname is always upper in HTML, in xml it's displayed as written.
88                 if(node.tagName  === 'IMG'){
89                         if(!/\d+IMG/.test(node.getAttribute('hide-grouping')) && (node.getAttribute('data-md5') !== null)){
90                                 this.hideImageNode(node);
91                         }
92                 }
93         }
94                 //Activate
95         activate():void{
96                 new MutationObserver((mutations) => {
97                         this.retrieveStates();
98                         this.hideHoverImageNode(mutations);
99                 }).observe(document.getElementById('hoverUI'), {childList: true});
100                 console.log("4F-FSE: ImageHider Active");       
101         }
102         
103         hideImageNode(image_node:any){
104                 var sister_node:any = image_node.parentNode.parentNode.parentNode.getElementsByClassName('catalog-thumb')[0]; // the catalog sister to index
105                 if(sister_node === undefined) sister_node = document.createElement('IMG');
107                 image_node.setAttribute('hide-grouping', image_node.parentNode.parentNode.id.substring(1) + 'IMG');
108                 sister_node.setAttribute('hide-grouping', image_node.parentNode.parentNode.id.substring(1) + 'IMG');
110                 image_node.addEventListener('click', (evt) => this.hideOnClick(evt));
111                 sister_node.addEventListener('click',(evt) => this.hideOnClick(evt));
113                 var threadstore_len = this.threads_to_hide.length;
114                 var node_group_id = image_node.getAttribute('hide-grouping');
116                 for(let thread = 0 ; thread < threadstore_len; thread++){
117                         if(node_group_id == this.threads_to_hide[thread]){
118                                 image_node.setAttribute('hidden-src', image_node.src);
119                                 image_node.src = this.blank_png;
121                                 sister_node.setAttribute('hidden-src', sister_node.src);
122                                 sister_node.src = this.blank_png;
124                                 return;
125                         }
126                 }
127                 //index node holds the MD5
128                 var node_md5:string = image_node.getAttribute('data-md5');
129                 if(this.md5_filters_arr !== undefined){
130                         var md5_filters_arr_len = this.md5_filters_arr.length;
131                         for(var md5:number = 0 ; md5 < md5_filters_arr_len; md5++){
132                                 if(node_md5 == this.md5_filters_arr[md5]){
133                                         image_node.setAttribute('hidden-src', image_node.src);
134                                         image_node.src = this.blank_png;
136                                         sister_node.setAttribute('hidden-src', sister_node.src);
137                                         sister_node.src = this.blank_png;
139                                         return;
140                                 }
141                         }
142                 }
143         }
144         
145         hideHoverImageNode(mutation_record:any):void{
146                 mutation_record.forEach((mutation) => {
147                         mutation.addedNodes.forEach((image_node:any) => {                       
148                                 var is_embeded_post:boolean;
149                                 if(image_node.tagName == 'DIV') {
150                                         is_embeded_post = true;
151                                         image_node = image_node.getElementsByClassName('postContainer')[0];
152                                         if(image_node === undefined) return;
153                                 }
154                                 
155                                 var unprocessed_id:string = image_node.getAttribute('data-full-i-d');
156                                 if (unprocessed_id === null) return;                                    
157                                 var proccessed_id:string = unprocessed_id.substring(unprocessed_id.indexOf('.') + 1);
158                                 var image_node_id:string = proccessed_id + 'IMG';               
159                                 if(is_embeded_post) image_node =  image_node.getElementsByTagName('IMG')[0];
160                                 if(image_node === undefined) return;
161                                 
162                                 for(var thread = 0, threadstore_len:number = this.threads_to_hide.length ; thread < threadstore_len; thread++){
163                                         if(image_node_id == this.threads_to_hide[thread]){                                              
164                                                 image_node.removeAttribute('src');
165                                                 return;
166                                         }
167                                 }
168                                 //thread node holds the MD5
169                                 var node_md5:string;
170                                 if(is_embeded_post) node_md5 = image_node.getAttribute('data-md5');
171                                 else node_md5 = document.getElementById('f' + proccessed_id).getElementsByTagName('IMG')[0].getAttribute('data-md5');
172                                 if(this.md5_filters_arr !== undefined){
173                                         for(var md5:number = 0 , md5_filters_arr_len:number = this.md5_filters_arr.length; md5 < md5_filters_arr_len; md5++){
174                                                 if(node_md5 == this.md5_filters_arr[md5]){
175                                                         image_node.removeAttribute('src');
176                                                         return;
177                                                 }
178                                         }
179                                 }
180                         });
181                 });
182         }