NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name 444.hu Disqus Embed // @description Embeds Disqus comments below all articles on 444.hu // @author amazingvalue (https://disqus.com/by/amazingvalue/) // @license MIT // @include https://444.hu* // @include https://*.444.hu* // @version 0.4.5 // @updateURL https://dev.null/ // @downloadURL https://dev.null/ // ==/UserScript== /* * * Userscript for embedding comments below all articles on 444.hu. * * Author: @amazingvalue (https://disqus.com/by/amazingvalue/) * Updates: * https://gitlab.com/444hu/disqus * https://openuserjs.org/scripts/amazing_value/444.hu_Disqus_Embed/ * * Usage: * * 1) Install the "greasemonkey" add-on or some of the alternatives * (tampermonkey, violentmonkey) from * https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/ or * https://www.tampermonkey.net/ * * 2) Open on the greasemonkey menu in your browser (monkey head near * top right corner) and click on "New user script" * * 3) Then an editor opens in another tab. Copy the content of this file * into it and save. * * Használat: * * 1) Telepítsd a greasemonkey kiegészítőt vagy valamelyik alternatíváját * (tampermonkey, violentmonkey) innen: * https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/ * vagy innen: * https://www.tampermonkey.net/ * * 2) Nyisd meg a greasemonkey menüjét (majom fej a jobb felső sarokban) * és válaszd az új user script opciót * * 3) Ekkor megnyílik egy szerkesztő ablak ahová másold be ennek a fájlnak * a tartalmát és mentsd el. * * Frissítéseket itt találod: * https://gitlab.com/444hu/disqus * https://openuserjs.org/scripts/amazing_value/444.hu_Disqus_Embed/ * */ /* * Changelog: * 2021-07-26 :: 0.4.5 * -- Resetting Disqus recommendations only if it presents in the page: * this prevents running into an error before Disqus could be reloaded * on pages loaded by XHR * * 2021-07-23 :: 0.4.4 * -- Finding article by footer: now it's the 3rd parent, not the 2nd * -- Updated article CSS classes * -- Updated CSS classes for author box (for nicer top comments button) * * 2021-06-14 :: 0.4.3 * -- Avoiding to add comments button under side column headings * * 2021-06-07 :: 0.4.2 * -- Updated article classes * -- Another method to find the article by its heading * (for extra robustness) * -- Updated top button layout classes * * 2021-06-04 :: 0.4.1 * -- Smaller buttons * -- Top button: better layout for narrow screens and many author articles * -- Removed activeTab permission * -- Doubled number of attempts to make sure it works at * very slow page loading * * 2021-05-25 :: 0.4.0 * -- Works also as a webextension content script in Firefox * -- Removes also top and sidebar advertisements * -- Tested as Chrome, Firefox and Firefox Android extension * * 2021-05-25 :: 0.3.4 * -- Using reset also on recommendations, no more complaints from Disqus * * 2021-05-25 :: 0.3.3 * -- Not relying on window load event, instead checking for article every * 200 ms * -- Using DISQUS.reset instead of loading embed.js after the first load * * 2021-05-24 :: 0.3.2 * -- Minor code improvements & fixed minor issues * -- Moved globals into namespaces * * 2021-05-24 :: 0.3.1 * -- Fixed a bug: sometimes on phones, very rare cases on desktop, the * buttons kept being added in an infinite cycle, resulting high CPU * load and making it impossible to load the comments * * 2021-05-24 :: 0.3.0 * -- Another comments button in the authors line (page top) * -- Using let and const instead of var * -- Scrolling down upon loading comments * -- More robust detection of article: checking every 200 ms for 6 s * * 2021-05-22 :: 0.2.5 * -- Included distribution URL in the header * -- Loading comments if the URL points to a comment * * 2021-05-21 :: 0.2.4 * -- Adding CSS only once * -- Green link colors in Disqus * -- Reduced delay to 1000 ms * -- Finds article also on blog subpages * -- Removes some ads below articles * * 2021-05-21 :: 0.2.3 * -- Article not found if querySelector returns null * -- Setting up the observer only once to avoid infinite loop, * clearing interval in the beginning of the disqus444Main * -- Adjusted class selector for article * -- If fails to find article by class, falling back to parent of parent of * #ap-article-footer1 * -- Added downloadURL = none, updateURL = none to the header * -- Tried to use DISQUS.reset, but could not really make it work * * 2021-05-21 :: 0.2.2 * -- Padding for comments container: better readability on phones * * 2021-05-21 :: 0.2.1 * -- Added observer to reload comments when navigating to new URL * * 2021-05-21 :: 0.2.0 * -- Adjusted to new design * -- Added 2000 ms delay, otherwise it loads prematurely * -- Removed "highlight Czinkoczi" * * 2019-12-31 :: 0.1.3 * -- Added features from Gazsify444: highlight Czinkoczi and reddit button * * 2019-12-29 :: 0.1.2 * -- Comment button is always right after the article (above ads) * -- Even if comments are allowed by the editors we create a new button * -- Subdomains added to @include (e.g. kepek.444.hu) * * 2019-12-28 :: 0.1.1 * -- ? * * 2019-12-28 :: 0.1.0 * -- Comments button works: gets appended below all articles and loads * comments on click * */ /* jshint esversion: 6 */ console.log('Disqus comments: Hello 444!'); let disqus444; disqus444 = window.disqus444 || { main_interval: null, obsr_interval: null, observer: null, old_href: null, attempt: 0 }; const DISQUS444 = { DELAY: 200, OBSR_DELAY: 1500, ATTEMPTS: 60, BASE_SCROLL: 400, BOTTOM_SCROLL: 300 }; const comments_html = ` <section id="comments"> <button id="comment-button" class="comment-button big-comment-button" > Hozzászólások </button> <div id="disqus_thread" class="freehand layout"></div> </section> `; const top_button_html = ` <button id="comment-button-top" class="comment-button">Kommentek</button> `; const main_style = ` .comment-button { padding: 10px; background-color: rgb(41, 175, 10); color: white; border-width: 0px; cursor: pointer; font-family: Boxed, Helvetica, Arial, sans-serif; text-transform: uppercase; font-weight: bold; } .reddit-button { background-color: #00BFFF!important; } .big-comment-button { font-size: x-large; margin-bottom: 20px; width: 100%; } #comment-button-top { margin-left: 10px; } #comments { padding: 0px 8px; font-family: Noticia Text; font-size: 18px; color: #080808; } #disqus_thread a { color: rgb(41, 175, 10); } @media only screen and (min-width: 980px) { .eb.ea.e9.dd { flex-direction: row; } } @media only screen and (max-width: 979px) { #comment-button-top { margin: 20px 0 0 0px; } .eb.ea.e9.dd { flex-direction: column; } .eb.ea.e9.dd.ef.ec { flex-direction: row; } .eb.ea.e9.dd.ef.ec > #comment-button-top { margin: 0 0 0 10px; } } @media only screen and (max-width: 420px) { .eb.ea.e9.dd.ef.ec { flex-direction: column; } .eb.ea.e9.dd.ef.ec > #comment-button-top { margin: 20px 0 0 0px; } } `; function disqus444AddStyle() { let styleSheet = document.getElementById('disqus-button-css'); if(styleSheet == null){ styleSheet = document.createElement('style'); styleSheet.setAttribute('id', 'disqus-button-css'); styleSheet.innerText = main_style; document.head.appendChild(styleSheet); } } function disqus444HtmlToElement(html) { const parser = new DOMParser(); const template = parser.parseFromString(html, 'text/html'); return(template.querySelector('body').firstElementChild); } function disqus444RemoveById(id) { const elem = document.getElementById(id); if(elem != null){ elem.remove(elem); } } function disqus444RemoveComments() { disqus444RemoveById('comments'); } function disqus444RemoveBottomAds() { disqus444RemoveById('ap-article-footer1'); disqus444RemoveById('ap-article-footer2'); document.querySelectorAll('.taboola-wrapper').forEach(el => el.remove()); disqus444RemoveAds(); } function disqus444RemoveAds() { document.querySelectorAll('.ad').forEach(el => el.remove()); } function disqus444LoadComments(extra_scroll = 0) { clearInterval(disqus444.main_interval); console.log('Disqus comments: Loading comments.'); const [ page_disqus, page_recom ] = disqus444GetPageDisqus(); if(page_disqus){ disqus444LoadReload(page_disqus, page_recom); }else{ disqus444LoadEmbedJs(); } window.scrollBy(0, DISQUS444.BASE_SCROLL + extra_scroll); } function disqus444LoadEmbedJs() { console.log('Disqus comments: Loading `embed.js`.'); let d = document; let s = d.createElement('script'); s.src = 'https://444hu.disqus.com/embed.js'; s.setAttribute('data-timestamp', + new Date()); (d.head || d.body).appendChild(s); disqus444RemoveById('comment-button'); } function disqus444LoadReload(page_disqus, page_recom) { console.log('Disqus comments: Calling `DISQUS.reset`.'); let the_config = { reload: true, config() { this.page.url = document.location.href + '/'; } }; document.querySelectorAll('.big-comment-button').forEach( el => el.remove() ); if(disqus444InFirefoxExtension()){ const the_window = disqus444GetWindow(); /* global exportFunction */ the_window.current_disqus_config = the_window.Object(); the_window.current_disqus_config.reload = true; the_window.current_disqus_config.config = exportFunction( function(){this.page.url = document.location.href + '/';}, the_window ); the_config = the_window.current_disqus_config; } if(typeof page_recom !== 'undefined'){ page_recom.reset(); } page_disqus.reset(the_config); } function disqus444GetPageDisqus() { const the_window = disqus444GetWindow(); if(the_window != null && typeof the_window.DISQUS !== 'undefined'){ return( [ the_window.DISQUS, the_window.DISQUS_RECOMMENDATIONS ] ); } return( [ null, null ] ); } function disqus444GetWindow() { let the_window = window; if(typeof window.wrappedJSObject !== 'undefined'){ if(typeof window.wrappedJSObject.unsafeWindow === 'undefined'){ the_window = window.wrappedJSObject; }else{ the_window = window.wrappedJSObject.unsafeWindow; } } return(the_window); } function disqus444InFirefoxExtension() { const in_firefox_ext = typeof cloneInto === 'function'; console.log('Disqus comments: In Firefox extension: ' + in_firefox_ext); return(in_firefox_ext); } function disqus444InsertButton(article, comments) { console.log('Disqus comments: Appending comments button.'); comments.firstElementChild.addEventListener( 'click', function(){disqus444LoadComments(DISQUS444.BOTTOM_SCROLL);}, false ); article.appendChild(comments); console.log('Disqus comments: Comments button added.'); } function disqus444GetArticle() { const article = ( disqus444GetArticleByClass() || disqus444GetArticleByFooter() || disqus444BlogGetArticle() || disqus444GetArticleByHeading() ); return(article); } function disqus444GetArticleByClass() { const article = document.querySelector( '.g1.cs.ff,' + '.g2.ct.fg,' + '.g3.cu.fh,' + '.g4.cv.fi,' + '.g5.cw.fj,' + '.g6.cx.fk,' + '.ig.d7.gx' ); if(article != null){ console.log('Disqus comments: Article found by classes.'); } return(article); } function disqus444GetArticleByFooter() { const footer = document.querySelector('#ap-article-footer1'); if(footer != null){ const article = footer.parentNode.parentNode.parentNode; console.log('Disqus comments: Article is 3rd parent of the footer.'); return(article); } } function disqus444BlogGetArticle() { let article = null; const content_main = document.getElementById('content-main'); if(content_main != null){ article = content_main.getElementsByTagName('article')[0]; if(article != null){ if( article.classList.contains('article--compact') || article.classList.contains('article-grid-box') ){ article = null; }else{ console.log( 'Disqus comments: Article found in legacy layout.' ); } } } return(article); } function disqus444GetArticleByHeading() { const h1 = document.querySelector('h1'); const article = ( h1 && h1.parentElement.tagName == 'HEADER' ? null : ( [ 'parentElement', 'nextElementSibling', 'nextElementSibling', 'firstElementChild' ].reduce( function(elem, prop){ return( elem && prop in elem ? elem[prop] : null ); }, h1 ) ) ); if(article){ console.log('Disqus comments: Article found by heading.'); } return(article); } function disqus444GetAuthorsLine(article) { let auth = document.querySelector('.byline__info'); if(auth == null){ auth = article.parentNode.previousElementSibling.firstElementChild; } return(auth); } function disqus444InsertTopButton(article, top_button) { if(document.getElementById('comment-button-top') != null){ return; } const top = disqus444GetAuthorsLine(article); top_button.addEventListener( 'click', function(){ if(document.getElementById('comment-button') != null){ disqus444LoadComments(); } document.getElementById('comments').scrollIntoView(); }, false ); top.appendChild(top_button); } function disqus444RedditLinks() { const open_reddit = function() { const url = 'https://www.reddit.com/' + window.location; window.open(url, '_blank'); }; const cbutton = document.querySelector('#comment-button'); const rbutton = document.createElement('button'); rbutton.setAttribute( 'class', 'comment-button big-comment-button reddit-button' ); rbutton.innerText = 'Reddit'; rbutton.addEventListener('click', function() { open_reddit(); }); cbutton.parentNode.insertBefore(rbutton, cbutton); } function disqus444OpenIfCommentUrl() { if(window.location.hash.startsWith('#comment')){ disqus444LoadComments(); } } function disqus444SetObserver() { clearInterval(disqus444.obsr_interval); if(disqus444.observer == null){ const the_body = document.querySelector('body'); disqus444.observer = new MutationObserver(function(mutations) { disqus444RemoveAds(); mutations.forEach(function() { if (disqus444.old_href != document.location.href) { console.log('Disqus comments: Navigating to new URL.'); disqus444.attempt = 0; disqus444.old_href = document.location.href; clearInterval(disqus444.main_interval); disqus444.main_interval = setInterval( disqus444Main, DISQUS444.DELAY ); } }); }); const config = { childList: true, subtree: true }; disqus444.observer.observe(the_body, config); } } function disqus444Main() { clearInterval(disqus444.main_interval); const article = disqus444GetArticle(); if(typeof article === 'undefined' || article == null){ disqus444RemoveById('comment-button-top'); disqus444.attempt++; if(disqus444.attempt >= DISQUS444.ATTEMPTS){ clearInterval(disqus444.main_interval); disqus444.attempt = 0; console.log('Disqus comments: No article found in page.'); }else{ disqus444.main_interval = setInterval( disqus444Main, DISQUS444.DELAY ); } return; } disqus444.attempt = 0; disqus444AddStyle(); disqus444RemoveComments(); const comments = disqus444HtmlToElement(comments_html); const top_button = disqus444HtmlToElement(top_button_html); disqus444InsertButton(article, comments); disqus444InsertTopButton(article, top_button); disqus444RedditLinks(); disqus444RemoveBottomAds(); disqus444.old_href = document.location.href; disqus444OpenIfCommentUrl(); } (function(){ if(window.self == window.top){ disqus444.main_interval = setInterval( disqus444Main, DISQUS444.DELAY ); disqus444.obsr_interval = setInterval( disqus444SetObserver, DISQUS444.OBSR_DELAY ); }else{ console.log('Disqus comments: Not in top frame?'); } }());