2 // @name 4chan-Ignoring-Enhancements
3 // @namespace http://tampermonkey.net/
5 // @description 4chan Pain Kill Extension
6 // @author ECHibiki-/qa/
7 // @match http://boards.4chan.org/*
8 // @match https://boards.4chan.org/*
9 // @include https://boards.4chan.org/*
10 // @include http://boards.4chan.org/*
11 // @run-at document-body
12 // @updateURL https://github.com/ECHibiki/4chan-UserScripts/raw/master/4chan-Ignoring-Enhancements.user.js
13 // @downloadURL https://github.com/ECHibiki/4chan-UserScripts/raw/master/4chan-Ignoring-Enhancements.user.js
16 var localStoreThreads
;
19 var windowDisplayed
= false;
20 var defaultExpireTime
= 172800000;
23 var windowDisplayed
= false;
24 var numberOfFilters
= 0;
25 var initialFilters
= [];
29 var secondObserverSet
;
32 function storageAvailable(type
) {
34 var storage
= window
[type
],
35 x
= '__storage_test__';
36 storage
.setItem(x
, x
);
37 storage
.removeItem(x
);
41 return e
instanceof DOMException
&& (
42 // everything except Firefox
46 // test name field too, because code might not be present
47 // everything except Firefox
48 e
.name
=== 'QuotaExceededError' ||
50 e
.name
=== 'NS_ERROR_DOM_QUOTA_REACHED') &&
51 // acknowledge QuotaExceededError only if there's something already stored
57 function detectBrowser() {
58 if((navigator
.userAgent
.indexOf("Opera") || navigator
.userAgent
.indexOf('OPR')) != -1 )
63 else if(navigator
.userAgent
.indexOf("Chrome") != -1 )
65 console
.log("Chrome");
68 else if(navigator
.userAgent
.indexOf("Safari") != -1)
70 console
.log("Safari");
73 else if(navigator
.userAgent
.indexOf("Firefox") != -1 )
75 console
.log("FireFox");
78 else if((navigator
.userAgent
.indexOf("MSIE") != -1 ) || (!!document
.documentMode
== true )) //IF IE > 10
90 //hide image onclick listener
91 function hideImage(event
){
92 var hideIndex
= this.src
.indexOf(".HIDDEN");
93 if((event
.ctrlKey
&& event
.shiftKey
) && hideIndex
== -1){
94 event
.preventDefault();
95 event
.stopPropagation();
96 if (storageAvailable('localStorage')) {
97 if(this.id
.charAt(0) == "p") this.id
= "f" + this.id
.substr(1);
98 localStorage
.setItem(this.id
, Date
.now());
101 console
.log("No Storage");
103 this.src
= this.src
+ ".HIDDEN" + "?" + Date
.now();
106 else if(event
.ctrlKey
&& event
.shiftKey
){
107 event
.preventDefault();
108 event
.stopPropagation();
109 if (storageAvailable('localStorage')) {
110 if(this.id
.charAt(0) == "p") this.id
= "f" + this.id
.substr(1);
111 localStorage
.removeItem(this.id
);
114 console
.log("No Storage");
116 this.src
= this.src
.substring(0, hideIndex
);
122 //functions to find properties by regex
123 function getPropertyByRegex(obj
,propName
) {
124 var re
= new RegExp("^" + propName
+ "(\\[\\d*\\])?$"),
133 //retrieve from memory the hidden iamges
135 function retrieveStates(){
139 while( i
< window
.localStorage
.length
) {
141 sKey
= window
.localStorage
.key(i
);
142 oJson
[sKey
] = window
.localStorage
.getItem(sKey
);
144 localStoreThreads
= getPropertyByRegex(oJson
,"f[0-9]*IMG");
145 localStoreThreads
.forEach(function callback(elem
){
146 if(Date
.now() - oJson
[elem
] > expireTime
)
147 localStorage
.removeItem(elem
);
148 var node
= document
.getElementById(""+elem
);
149 if(node
!== null && node
.src
.indexOf(".HIDDEN") == -1){
150 node
.src
= node
.src
+ ".HIDDEN" + "?" + Date
.now();
153 else if((node
= document
.getElementById("p"+elem
.substring(1))) !== null && node
.src
.indexOf(".HIDDEN") == -1){
154 node
.src
= node
.src
+ ".HIDDEN" + "?" + Date
.now();
157 else if((node
= document
.getElementById("thread-"+elem
.substring(1))) !== null && node
.src
.indexOf(".HIDDEN") == -1){
158 node
.src
= node
.src
+ ".HIDDEN" + "?" + Date
.now();
161 else if((node
= document
.getElementById("thumb-"+elem
.substring(1))) !== null && node
.src
.indexOf(".HIDDEN") == -1){
162 node
.src
= node
.src
+ ".HIDDEN" + "?" + Date
.now();
171 function hideWindow(){
172 var style
= document
.createElement('style');
173 style
.innerHTML
= ".inputs{background-color:rgb(200,200,200);margin:5px 7px;width:100px;}";
174 document
.body
.appendChild(style
);
176 var backgroundDiv
= document
.createElement("div");
177 backgroundDiv
.setAttribute("style", "border:solid 1px black;position:fixed;width:100%;height:100%;background-color:rgba(200,200,200,0.3);top:0;left:0;display:none; z-index:9");
178 backgroundDiv
.setAttribute("id", "hiBackground");
179 document
.body
.appendChild(backgroundDiv
);
180 backgroundDiv
.addEventListener("click", hideToggle
);
182 var windowDiv
= document
.createElement("div");
183 windowDiv
.setAttribute("style", "border:solid 1px black;position:fixed;width:400px;background-color:rgb(200,200,200);left:40%;top:20%;margin-bottom:0; display:none; z-index:10");
184 windowDiv
.setAttribute("id", "hiWindow");
186 var closeDiv
= document
.createElement("div");
187 closeDiv
.setAttribute("style", "border:solid 1px black;position:absolute;width:25px;height:25px;background-color:rgba(255,100,90,0.9); right:3px;top:3px; z-index:10");
188 closeDiv
.addEventListener("click", hideToggle
);
189 windowDiv
.appendChild(closeDiv
);
191 var titleP
= document
.createElement("p");
192 titleP
.setAttribute("style", "margin-left:5px;margin-top:5px");
193 var titleText
= document
.createTextNode("Filter Settings");
194 titleP
.appendChild(titleText
);
195 windowDiv
.appendChild(titleP
);
197 var containerDiv
= document
.createElement("div");
198 containerDiv
.setAttribute("style","background-color:white;margin:0 0;padding:5px;");
199 windowDiv
.appendChild(containerDiv
);
201 var expirationLabel
= document
.createElement("label");
202 var expirationText
= document
.createTextNode("Expiration Time(hours): ");
203 expirationLabel
.appendChild(expirationText
);
204 containerDiv
.appendChild(expirationLabel
);
205 var expirationInput
= document
.createElement("input");
206 expirationInput
.setAttribute("id", "expirationTime");
207 containerDiv
.appendChild(expirationInput
);
208 containerDiv
.appendChild(expirationInput
);
209 containerDiv
.appendChild(document
.createElement("br"));
210 var setButton
= document
.createElement("input");
211 setButton
.setAttribute("type", "button");
212 setButton
.setAttribute("id", "setTime");
213 setButton
.setAttribute("value", "Set Time");
214 setButton
.addEventListener("click", function(){
216 if (storageAvailable('localStorage')) {
217 var time
= document
.getElementById("expirationTime");
218 var msTime
= time
.value
* 3600000;
219 if (msTime
== 0) msTime
= defaultExpireTime
;
221 //console.log("B" + expireTime);
222 localStorage
.setItem("ExpirationTime", msTime
);
226 expirationInput
.setAttribute("value", localStorage
.getItem("ExpirationTime") / 3600000);
227 containerDiv
.appendChild(setButton
);
229 document
.body
.appendChild(windowDiv
);
233 function hideToggle(){
235 document
.getElementById("hiWindow").style
.display
= "none";
236 document
.getElementById("hiBackground").style
.display
= "none";
237 windowDisplayed
= false;
240 document
.getElementById("hiWindow").style
.display
= "inline-block";
241 document
.getElementById("hiBackground").style
.display
= "inline-block";
242 windowDisplayed
= true;
246 function hideButton(){
247 var button
= document
.createElement("input");
248 button
.setAttribute("Value", "Hide Image Settings");
249 button
.setAttribute("type", "button");
250 button
.setAttribute("style", "position:absolute;top:45px");
251 button
.addEventListener("click", hideWindow
);
252 if(document
.body
=== null){
253 setTimeout(hideButton
, 30);
256 document
.body
.appendChild(button
);
257 button
.addEventListener("click", hideToggle
);
259 expireTime
= localStorage
.getItem("ExpirationTime");
260 //console.log("Z" + expireTime);
264 //0000000000000000000000000000000000000000000000000000000000000000000000000000000////0000000000000000000000000000000000000000000000000000000000000000000000000000000//
265 //0000000000000000000000000000000000000000000000000000000000000000000000000000000////0000000000000000000000000000000000000000000000000000000000000000000000000000000//
266 //0000000000000000000000000000000000000000000000000000000000000000000000000000000////0000000000000000000000000000000000000000000000000000000000000000000000000000000//
267 //0000000000000000000000000000000000000000000000000000000000000000000000000000000////0000000000000000000000000000000000000000000000000000000000000000000000000000000//
268 //0000000000000000000000000000000000000000000000000000000000000000000000000000000////0000000000000000000000000000000000000000000000000000000000000000000000000000000//
269 //0000000000000000000000000000000000000000000000000000000000000000000000000000000////0000000000000000000000000000000000000000000000000000000000000000000000000000000//
270 //0000000000000000000000000000000000000000000000000000000000000000000000000000000////0000000000000000000000000000000000000000000000000000000000000000000000000000000//
271 //0000000000000000000000000000000000000000000000000000000000000000000000000000000////0000000000000000000000000000000000000000000000000000000000000000000000000000000//
273 function formatSettings(input
){
274 var rtn
= input
.split('"-"');
276 rtn
.forEach(function(filter
){
277 rtn
[i
] = filter
.replace("\"", "");
283 function loadSettings(){
287 while( i
< window
.localStorage
.length
) {
289 sKey
= window
.localStorage
.key(i
);
290 oJson
[sKey
] = window
.localStorage
.getItem(sKey
);
292 numberOfFilters
= oJson
["q"];
293 console
.log(numberOfFilters
);
294 filters
= getPropertyByRegex(oJson
,"filter[0-9]*");
295 filters
.forEach(function(filter
){
296 initialFilters
.push(formatSettings(oJson
[filter
]));
300 function saveSettings(){
302 if(storageAvailable('localStorage')){
303 window
.localStorage
.setItem("q", numberOfFilters
);
304 for (var i
= 0 ; i
< numberOfFilters
; i
++){
305 var pattern
= document
.getElementById("Pattern"+i
).value
;
306 var replacement
= document
.getElementById("Replacement"+i
).value
;
308 if(pattern
=== "" || replacement
=== "") continue;
309 if (pattern
.charAt(0) == "/" && pattern
.charAt(pattern
.length
- 1) == "/"){
310 pattern
= pattern
+ setting
;
312 else if(pattern
.charAt(0) !== "/" && pattern
.substr(pattern
.length
- 2).match(/\/[a-zA-Z$]/) == null){
313 pattern
= "/" + pattern
+ "/" + setting
;
315 document
.getElementById("Pattern"+i
).value
= pattern
;
316 var saveString
= '"' + document
.getElementById("Active"+i
).checked
+ '"-"' + pattern
+ '"-"' + replacement
+ '"';
317 window
.localStorage
.setItem("filter" + i
, saveString
);
320 alert("Replacements Saved");
323 function filterWindow(){
324 var style
= document
.createElement('style');
325 style
.innerHTML
= ".inputs{background-color:rgb(200,200,200);margin:5px 7px;width:100px;}";
326 document
.body
.appendChild(style
);
328 var backgroundDiv
= document
.createElement("div");
329 backgroundDiv
.setAttribute("style", "border:solid 1px black;position:fixed;width:100%;height:100%;background-color:rgba(200,200,200,0.3);top:0;left:0;display:none; z-index:9");
330 backgroundDiv
.setAttribute("id", "FilterBackground");
331 document
.body
.appendChild(backgroundDiv
);
332 backgroundDiv
.addEventListener("click", filterToggle
);
334 var windowDiv
= document
.createElement("div");
335 windowDiv
.setAttribute("style", "border:solid 1px black;position:fixed;width:400px;background-color:rgb(200,200,200);left:40%;top:20%;margin-bottom:0; display:none; z-index:10");
336 windowDiv
.setAttribute("id", "FilterWindow");
338 var closeDiv
= document
.createElement("div");
339 closeDiv
.setAttribute("style", "border:solid 1px black;position:absolute;width:25px;height:25px;background-color:rgba(255,100,90,0.9); right:3px;top:3px; z-index:10");
340 closeDiv
.addEventListener("click", filterToggle
);
341 windowDiv
.appendChild(closeDiv
);
343 var titleP
= document
.createElement("p");
344 titleP
.setAttribute("style", "margin-left:5px;margin-top:5px");
345 var titleText
= document
.createTextNode("Filter Settings");
346 titleP
.appendChild(titleText
);
347 windowDiv
.appendChild(titleP
);
349 var containerDiv
= document
.createElement("div");
350 containerDiv
.setAttribute("style","background-color:white;margin:0 0;padding:5px;");
351 windowDiv
.appendChild(containerDiv
);
353 var filterTable
= document
.createElement("table");
354 filterTable
.setAttribute("style", "text-align:center;");
355 filterTable
.setAttribute("id", "FilterTable");
356 containerDiv
.appendChild(filterTable
);
358 var tableRow
= document
.createElement("tr");
359 filterTable
.appendChild(tableRow
);
360 var tableHeadActive
= document
.createElement("th");
361 var headTextActive
= document
.createTextNode("Active");
362 tableHeadActive
.appendChild(headTextActive
);
363 filterTable
.appendChild(tableHeadActive
);
364 var tableHeadPattern
= document
.createElement("th");
365 var headTextPattern
= document
.createTextNode("Pattern");
366 tableHeadPattern
.appendChild(headTextPattern
);
367 filterTable
.appendChild(tableHeadPattern
);
368 var tableHeadReplacement
= document
.createElement("th");
369 var headTextReplacement
= document
.createTextNode("Replacement");
370 tableHeadReplacement
.appendChild(headTextReplacement
);
371 filterTable
.appendChild(tableHeadReplacement
);
373 //loop to create rows
374 //console.log(numberOfFilters);
375 if (numberOfFilters
=== 0 || isNaN(numberOfFilters
)) numberOfFilters
= 6;
376 //console.log(numberOfFilters);
377 for (var i
= 0; i
< numberOfFilters
; i
++){
378 var tableRowContents
= document
.createElement("tr");
379 tableRowContents
.setAttribute("id", "FilterRow" + i
);
381 var tableDataActive
= document
.createElement("td");
382 var tableCheckBoxActive
= document
.createElement("input");
383 tableCheckBoxActive
.setAttribute("type", "checkbox");
384 tableCheckBoxActive
.setAttribute("id", "Active" + i
);
385 tableDataActive
.appendChild(tableCheckBoxActive
);
386 tableRowContents
.appendChild(tableDataActive
);
388 var tableDataPattern
= document
.createElement("td");
389 var tableInputPattern
= document
.createElement("input");
390 tableInputPattern
.setAttribute("class", "inputs");
391 tableInputPattern
.setAttribute("id", "Pattern" + i
);
392 tableDataPattern
.appendChild(tableInputPattern
);
393 tableRowContents
.appendChild(tableDataPattern
);
395 var tableDataReplacement
= document
.createElement("td");
396 var tableInputReplacement
= document
.createElement("input");
397 tableInputReplacement
.setAttribute("class", "inputs");
398 tableInputReplacement
.setAttribute("id", "Replacement" + i
);
399 tableDataReplacement
.appendChild(tableInputReplacement
);
400 tableRowContents
.appendChild(tableDataReplacement
);
402 filterTable
.appendChild(tableRowContents
);
405 var tableLastContents
= document
.createElement("tr");
407 var tableAddCollumn
= document
.createElement("td");
408 var tableAddRowButton
= document
.createElement("input");
409 var tableSubtractRowButton
= document
.createElement("input");
410 tableSubtractRowButton
.setAttribute("type", "button");
411 tableSubtractRowButton
.setAttribute("value", "-");
412 tableSubtractRowButton
.setAttribute("style", "padding: 7px 0; margin:5px 0;");
413 tableAddCollumn
.appendChild(tableSubtractRowButton
);
414 tableSubtractRowButton
.addEventListener("click", removeRow
);
415 tableAddRowButton
.setAttribute("type", "button");
416 tableAddRowButton
.setAttribute("value", "+");
417 tableAddRowButton
.setAttribute("style", "padding: 7px 0; margin:5px 0;");
418 tableAddCollumn
.appendChild(tableAddRowButton
);
419 tableAddRowButton
.addEventListener("click", addRow
);
421 tableLastContents
.appendChild(tableAddCollumn
);
423 var tableSetCollumn
= document
.createElement("td");
424 var tableConfirmButton
= document
.createElement("input");
425 tableConfirmButton
.setAttribute("type", "button");
426 tableConfirmButton
.setAttribute("id", "tableConfirmButton");
427 tableConfirmButton
.setAttribute("value", "Set Replacements");
428 tableConfirmButton
.setAttribute("style", "padding: 7px 0; margin:5px 0;");
429 tableConfirmButton
.addEventListener("click", saveSettings
);
430 tableConfirmButton
.addEventListener("click", modifyDOM
);
431 tableConfirmButton
.addEventListener("click", filterToggle
);
432 tableSetCollumn
.appendChild(tableConfirmButton
);
433 tableLastContents
.appendChild(tableSetCollumn
);
436 var tableCloseCollumn
= document
.createElement("td");
437 var tableCloseButton
= document
.createElement("input");
438 tableCloseButton
.setAttribute("type", "button");
439 tableCloseButton
.setAttribute("value", "Close Menu");
440 tableCloseButton
.setAttribute("style", "padding: 7px 0; margin:5px 0;");
441 tableCloseButton
.addEventListener("click", filterToggle
);
442 tableCloseCollumn
.appendChild(tableCloseButton
);
443 tableLastContents
.appendChild(tableCloseCollumn
);
445 filterTable
.appendChild(tableLastContents
);
447 document
.body
.appendChild(windowDiv
);
451 function filterToggle(){
453 document
.getElementById("FilterWindow").style
.display
= "none";
454 document
.getElementById("FilterBackground").style
.display
= "none";
455 windowDisplayed
= false;
458 document
.getElementById("FilterWindow").style
.display
= "inline-block";
459 document
.getElementById("FilterBackground").style
.display
= "inline-block";
460 windowDisplayed
= true;
464 function filterButton(){
465 var button
= document
.createElement("input");
466 button
.setAttribute("Value", "Word Filter Settings");
467 button
.setAttribute("type", "button");
468 button
.setAttribute("style", "position:absolute;top:75px");
469 button
.addEventListener("click", filterWindow
);
470 document
.body
.appendChild(button
);
471 button
.addEventListener("click", filterToggle
);
475 var table
= document
.getElementById("FilterTable");
476 table
.deleteRow(parseInt(numberOfFilters
) + 1);
479 var tableRowContents
= document
.createElement("tr");
480 tableRowContents
.setAttribute("id", "FilterRow" + (numberOfFilters
- 1));
482 var tableDataActive
= document
.createElement("td");
483 var tableCheckBoxActive
= document
.createElement("input");
484 tableCheckBoxActive
.setAttribute("type", "checkbox");
485 tableCheckBoxActive
.setAttribute("id", "Active" + (numberOfFilters
- 1));
486 tableDataActive
.appendChild(tableCheckBoxActive
);
487 tableRowContents
.appendChild(tableDataActive
);
489 var tableDataPattern
= document
.createElement("td");
490 var tableInputPattern
= document
.createElement("input");
491 tableInputPattern
.setAttribute("class", "inputs");
492 tableInputPattern
.setAttribute("id", "Pattern" + (numberOfFilters
- 1));
493 tableDataPattern
.appendChild(tableInputPattern
);
494 tableRowContents
.appendChild(tableDataPattern
);
496 var tableDataReplacement
= document
.createElement("td");
497 var tableInputReplacement
= document
.createElement("input");
498 tableInputReplacement
.setAttribute("class", "inputs");
499 tableInputReplacement
.setAttribute("id", "Replacement" + (numberOfFilters
- 1));
500 tableDataReplacement
.appendChild(tableInputReplacement
);
501 tableRowContents
.appendChild(tableDataReplacement
);
503 table
.appendChild(tableRowContents
);
505 var tableLastContents
= document
.createElement("tr");
507 var tableAddCollumn
= document
.createElement("td");
508 var tableAddRowButton
= document
.createElement("input");
509 var tableSubtractRowButton
= document
.createElement("input");
510 tableSubtractRowButton
.setAttribute("type", "button");
511 tableSubtractRowButton
.setAttribute("value", "-");
512 tableSubtractRowButton
.setAttribute("style", "padding: 7px 0; margin:5px 0;");
513 tableAddCollumn
.appendChild(tableSubtractRowButton
);
514 tableSubtractRowButton
.addEventListener("click", removeRow
);
515 tableAddRowButton
.setAttribute("type", "button");
516 tableAddRowButton
.setAttribute("value", "+");
517 tableAddRowButton
.setAttribute("style", "padding: 7px 0; margin:5px 0;");
518 tableAddCollumn
.appendChild(tableAddRowButton
);
519 tableAddRowButton
.addEventListener("click", addRow
);
521 tableLastContents
.appendChild(tableAddCollumn
);
523 var tableSetCollumn
= document
.createElement("td");
524 var tableConfirmButton
= document
.createElement("input");
525 tableConfirmButton
.setAttribute("type", "button");
526 tableConfirmButton
.setAttribute("id", "tableConfirmButton");
527 tableConfirmButton
.setAttribute("value", "Set Replacements");
528 tableConfirmButton
.setAttribute("style", "padding: 7px 0; margin:5px 0;");
529 tableConfirmButton
.addEventListener("click", saveSettings
);
530 tableConfirmButton
.addEventListener("click", modifyDOM
);
531 tableConfirmButton
.addEventListener("click", filterToggle
);
532 tableSetCollumn
.appendChild(tableConfirmButton
);
533 tableLastContents
.appendChild(tableSetCollumn
);
535 var tableCloseCollumn
= document
.createElement("td");
536 var tableCloseButton
= document
.createElement("input");
537 tableCloseButton
.setAttribute("type", "button");
538 tableCloseButton
.setAttribute("value", "Close Menu");
539 tableCloseButton
.setAttribute("style", "padding: 7px 0; margin:5px 0;");
540 tableCloseButton
.addEventListener("click", filterToggle
);
541 tableCloseCollumn
.appendChild(tableCloseButton
);
542 tableLastContents
.appendChild(tableCloseCollumn
);
544 table
.appendChild(tableLastContents
);
547 function removeRow(){
548 var table
= document
.getElementById("FilterTable");
549 if(numberOfFilters
!= 0){
550 table
.deleteRow(numberOfFilters
);
557 initialFilters
.forEach(function(filter
){
558 if(filter
[2] === null || filter
[1] === null || filter
[0] === null || i
== numberOfFilters
) return;
559 if(filter
[0] == "true"){
560 document
.getElementById("Active"+i
).checked
= true;
562 else if(filter
[0] == "false"){
563 document
.getElementById("Active"+i
).checked
= false;
565 document
.getElementById("Pattern"+i
).value
= filter
[1];
566 document
.getElementById("Replacement"+i
).value
= filter
[2];
572 //1111111111111111111111111111111111111111111111111111111111111111111111////11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111//
573 //1111111111111111111111111111111111111111111111111111111111111111111111////11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111//
574 //1111111111111111111111111111111111111111111111111111111111111111111111////11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111//
575 //1111111111111111111111111111111111111111111111111111111111111111111111////11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111//
576 //1111111111111111111111111111111111111111111111111111111111111111111111////11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111//
577 //1111111111111111111111111111111111111111111111111111111111111111111111////11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111//
578 //1111111111111111111111111111111111111111111111111111111111111111111111////11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111//
579 //1111111111111111111111111111111111111111111111111111111111111111111111////11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111//
580 //1111111111111111111111111111111111111111111111111111111111111111111111////11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111//
581 //1111111111111111111111111111111111111111111111111111111111111111111111////11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111//
584 function modifyDOM(){
586 var start
= document
.getElementById("delform");
587 if (start
=== null) start
= document
.body
;
588 else start
= start
.firstChild
;
589 if(!secondObserverSet
){
590 //console.log(start);
591 observer
.disconnect();
592 observeDynamicMutation(start
);
593 secondObserverSet
= true;
597 var start
= document
;
599 if(start
=== null) return;
600 var itterator
= document
.createTreeWalker(start
, NodeFilter
.SHOW_ELEMENTS
, NodeFilter
.SHOW_ELEMENTS
);
603 //console.log("modify DOM");
604 while((node
= itterator
.nextNode())){
605 var cname
= node
.className
;
606 var tag
= node
.tagName
;
607 if(tag
=== "IMG" || tag
=== "img"){
608 if(node
.getAttribute("data-md5") !== null || node
.className
.indexOf("thumb") != -1){
610 node
.id
= node
.parentNode
.parentNode
.id
+ "IMG";
611 node
.addEventListener("click", hideImage
, {passive
:false, capture
:false, once
:false});
614 else if(cname
== "postMessage"){
615 while((localNode
= itterator
.nextNode())){
616 var className
= localNode
.className
;
617 if(className
== undefined || className
== "quotelink"){
618 for(var i
= 0 ; i
< numberOfFilters
; i
++){
619 //console.log(localNode.className);
620 if(kill
[i
] == true) continue;
621 filter
= document
.getElementById("Pattern"+i
);
622 replacement
= document
.getElementById("Replacement"+i
);
623 active
= document
.getElementById("Active"+i
);
626 var lastChar
= filter
.value
.length
- 1;
627 var filterText
= filter
.value
;
628 if(filterText
=== "") break;
629 var setting
= filterText
.substr(lastChar
);
630 filterText
= filterText
.substr(1, lastChar
-2);
631 filterText
= "(^|[\\s!$%^&*()_+|~\\-=`{}\\[\\]:\";'<>?,\\.\\/])" + filterText
+ "([\\s!$%^&*()_+|~\\-=`{}\\[\\]:\";'<>?,\\.\\/]|$)";
633 var regex
= new RegExp(filterText
, setting
);
634 localNode
.textContent
= localNode
.textContent
.replace(regex
, " " + replacement
.value
+ " ");
637 alert(i
+ "'s regex was invalid");
640 // console.log("Inner: " + (Date.now() - later));
651 //detect page changes
652 function observeDynamicMutation(node
){
653 if(node
=== undefined)
655 observer
= new MutationObserver(function callBack(mutations
){
656 var later
= Date
.now();
659 //console.log("PKX: " + (Date.now() - later));
661 var config
= {subtree
: true, childList
:true};
662 observer
.observe(node
, config
);
665 if (window
.top
!= window
.self
) //-- Don't run on frames or iframes
668 //initial onload setup
669 function hideSetup(){
675 function filterSetup(){
685 observeDynamicMutation();
688 browser
= detectBrowser();
690 console
.log("Script loaded: 4chanPKX");