Greasy Fork

heise.de Easy Reading

Makes reading heise news a little more comfortable

目前为 2017-07-02 提交的版本。查看 最新版本

// ==UserScript==
// @id                heise.de-8280af0b-4f9b-487e-95b3-45fff377348e
// @name              heise.de Easy Reading
// @name:de           heise.de Easy Reading
// @version           1.5
// @author            SpineEyE
// @description       Makes reading heise news a little more comfortable
// @description:de    Macht heise lesen etwas angenehmer
// @include           /https?:\/\/www\.heise\.de/.*$/
// @run-at            document-idle
// @grant             GM_addStyle
// @grant             GM_getValue
// @grant             GM_setValue
// @grant             GM_xmlhttpRequest
// @namespace
// @namespace 
// ==/UserScript==
// heise.de Cleaner user script
// Copyright 2011-2017, SpineEyE
// Released under the GPL license
// http://www.gnu.org/copyleft/gpl.html
//
// -----------------------------------------------------------------------------
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// changelog
// v1.5   - 03.07.2017 Added: Anti-pagination, hängt Inhalt der nächsten Seiten an den Artikel an.
// v1.4.1 - 10.03.2017: Fixed: Serifen-Einstellung wird gespeichert
// v1.4 - 10.03.2017: Added: Checkbox um zwischen Serifenschrift und Standard umzuschalten.
//                               Added: Autmoatisch Thread-Anzeige einblenden.
//                               Added: Startet mit https-URL.
//                               Der Einfachheit Kompatibilität für Jahre alte Browser aufgegeben.
//                               Changelog jetzt auf deutsch. Bitte trotzdem nicht Afd wählen.
// v1.3.1 - 14.05.2015: Fix: Text in unordered list has the same size as the rest,
//                      small code simplification
// v1.3 - 02.03.2015: Added: Back Button for the end of a gallery
// v1.2.5 - 12.02.2015: Fix: lead image anti popup
// v1.2.4 - 18.12.2014: Clicking the article's lead image ("aufmacherbild") will redirect to full size image instead of heise's container page for it (only some pictures are actually inserted downsized).
// v1.2.3 - 18.12.2014: Fix: Links at the top werent clickable
// v1.2.2 - 14.10.2014: Compatibility fix for Greasemonkey
// v1.2.1 - 22.03.2014: Fixed meldung_wrapper text content to have the new style as well
// v1.2 - 01.03.2014: Now uses GM_addStyle to change article style.
//						Text in <pre> tags is readable in whole width
// v1.1.1 - 16.11.2013: fixed h2-link-construction
//

(function () { // function wrapper for Opera

/* Better for our eyes */

if (document.getElementsByClassName('meldung_wrapper').length > 0) {
	GM_addStyle(
		'.easy-reading-serif {'+
			'font-family: Georgia,"Times New Roman",serif;' +
			'line-height: 155%;' +
			'padding: 0.5em 0;' +
			'font-size: 1em !important;' +
			'letter-spacing: 0.2px;' +
		'}' +
		'#mitte_news ul {' +
			'font-size: 1em !important;' +
		'}'+
        /* remove top margin */
        '#bannerzone {' +
            'display:none'+
        '}'+
        '#container_content {' +
            'margin-top: -95px;'+
        '}'+
        /* fix to make text in <pre> tags visible over the whole width */
        'pre {' +
            'position: relative;' +
            'z-index: 1;' +
            'background-color: #FFFFFF;' +
        '}' +
            'pre:hover {' +
            'display: table-caption;' +
            'margin-top: 0' +
        '}'
	);
}

/* prevent image popups, rather insert normal hyperlink
	bild_links, bild_rechts
 **/
var inlineImages = document.evaluate('//span[starts-with(@class,"bild_")]', document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null),
	i, span, img, a, bigImageURL;
for(i = 0; i < inlineImages.snapshotLength; i++) {
	//console.log("Snapshot item " + i);
	span = inlineImages.snapshotItem(i);
	img = span.children[0];

	a = document.createElement('a');
	bigImageURL = img.getAttribute('data-zoom-src');
	if (!bigImageURL) continue;
	a.href = bigImageURL;

	// cloning a node removes all event listeners, so the popup as well
	a.appendChild(img.cloneNode(false));

	span.insertBefore(a, img);
	span.removeChild(img);
}

/* link to full size picture for aufmacherbild */
var imgAufmacher, aAufmacher;
if (document.getElementsByClassName("aufmacherbild")[0]) {
	aAufmacher  = document.getElementsByClassName("aufmacherbild")[0].children[0];
	imgAufmacher = aAufmacher.children[0];
}

if (imgAufmacher) {

	a = document.createElement('a');

	// class for the zoom overlay image in the bottom right corner
	a.setAttribute('class', 'image_zoom');
	// console.log(imgAufmacher.src.replace(/\/scale.*?\/imgs\//i, "/imgs/"));
	a.href = imgAufmacher.src.replace(/\/scale.*?\/imgs\//i, "/imgs/");

	// cloning a node removes all event listeners, so the popup as well
	a.appendChild(imgAufmacher.cloneNode(false));

	document.getElementsByClassName("aufmacherbild")[0].insertBefore(a, aAufmacher);
	document.getElementsByClassName("aufmacherbild")[0].removeChild(aAufmacher);
}

/* gallery fix: enable back button on advertisement slide */

if (document.querySelector(".gallery")) {
	a = document.createElement("a");
	a.setAttribute("data-slide", "prev");
	a.setAttribute("class", "gallery-control slide slide-prev greasy-added");
	a.innerHTML = '<span class="fa fa-angle-left fa-4x fa-inverse"></span>';
	// we need two of this, make deep copy
	var b = a.cloneNode(true);

	/* Several reasons why this runs as an interval:
	 * 1) I have found no way to hook into the event emitter
	 * 2) Every time changing tabs and returning to the page removes the button
	 * 3) Every time this back button is pressed, it's removed
	 * We could probably use the MutationObserver ... Maybe I'll look into it
	 * to see if it's lower on resources
	 */
	var galleryGuard = window.setInterval(function(){
		if (document.querySelector('.image-num').innerHTML.indexOf("Zurück zum Start") !== -1
            && document.querySelectorAll('.greasy-added').length != 2) {

			// modal window / fullscreen mode?
			// probably better to add the button to both views
			//if (document.querySelector(".gallery .heise-modal").style.display != "none") {
				document.querySelector(".image-stage").appendChild(a);
			//}
			//else {
				document.querySelector(".gallery-inner").appendChild(b);
			//}
		}
	}, 200);
}

/* Thread-Anzeige einblenden im Forum */
if (document.querySelector('.thread_view_switch a')
		&& document.querySelector('.thread_view_switch a').textContent == "Thread-Anzeige einblenden") {
	document.querySelector('.thread_view_switch a').click();
}

/* Serif checkbox */

function makeSerif(serifIfTrue) {
	var articleTextElements = document.querySelectorAll('.meldung_wrapper, .meldung_wrapper p, .meldung_wrapper h5, .artikel_content article p');
	var i = 0;
	for (i = 0; i < articleTextElements.length; i++) {
		if (serifIfTrue) {
			articleTextElements[i].classList.add("easy-reading-serif");
		}
		else {
			articleTextElements[i].classList.remove("easy-reading-serif");
		}
	}
}

function serifCheckboxHandler(){
	var checkbox = document.getElementById('useSerifFont');
	// this is already the new value
	var newValue = checkbox.checked;

	makeSerif(newValue);

	console.log("setting to " + newValue);
	GM_setValue( "serifFont", newValue);

	console.log("After checkbox: " + GM_getValue( "serifFont", false ));
}

var articleNode = document.getElementsByTagName("article")[0];
if (articleNode) {
	var label = document.createElement('label');
	var serifToggleLabel = document.createTextNode("Serifen-Schrift");
	var checkbox = document.createElement('input');
	checkbox.setAttribute('type', 'checkbox');
	checkbox.setAttribute('id', 'useSerifFont');
	label.appendChild(checkbox);
	label.appendChild(serifToggleLabel);

	var userSetting = GM_getValue( "serifFont", "init" );
	if (userSetting == "init") {
		GM_setValue( "serifFont", true );
		userSetting = true;
	}

	checkbox.checked = userSetting;
	makeSerif(userSetting);

	checkbox.addEventListener('click', serifCheckboxHandler);
	articleNode.appendChild(label);
}

var pagination = $('.seitenweise_navigation.paginiert');

if (pagination) {
    var promises = [];
    var otherPages = document.querySelector('.pagination a');
    if (otherPages.tagName && otherPages.tagName.toLowerCase() === 'a') {
        // there is exactly one more page
        promises.push(appendPage(otherPages.getAttribute('href')));
    }
    else for (var aElement in otherPages) {
        promises.push(appendPage(otherPages.getAttribute('href')));
    }
    Promise.all(promises)
        .then(function() {
            pagination.remove();
    });
}

function appendPage(url) {
    return new Promise(function(resolve, reject) {
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            onload: function(response) {
                responseDoc = document.createElement('html');
                responseDoc.innerHTML = response.responseText;
                // find chaoter title
                chapter_title = responseDoc.querySelector('.article__chapter');
                if (chapter_title) {
                    console.log(chapter_title);
                    articleNode.insertBefore(chapter_title, articleNode.querySelector('footer'));
                }
                meldung = responseDoc.querySelector('.meldung_wrapper');
                // remove ToC
                meldung.removeChild(meldung.querySelector('.pre-akwa-toc'));
                articleNode.insertBefore(meldung, articleNode.querySelector('footer'));
                resolve();
            }
        });
    });
}

})(); // function wrapper for Opera