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[];
15 this.retrieveStates();
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);
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) => {
44 this.md5_filters_arr[index] = md5.substring(1, md5.length - 1);
49 storeStates(...item_pairs:string[]):void{
50 window.localStorage.setItem(item_pairs[0], item_pairs[1]);
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;
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');
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);
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");
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;
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;
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;
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;
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');
168 //thread node holds the MD5
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');