User:Bradv/Scripts/Quickview.js

Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
//User:Bradv/Scripts/Quickview.js
(function( $, mw ) {
    'use strict';

    var quickview = {
        typeEnum: {
            CONTRIBS : 1,
            WATCHLIST : 2,
            RECENT: 3,
            RELATED: 4,
            HISTORY: 5,
			CATEGORY: 6,
			RESULTS: 7,
            DELCONTRIBS: 8,
            LOG: 9
        },
        type: 0,
        styleSheet: null,
        chkEnabled: null,
        changeslist: null,
        selector: null,
        init: function(qvType) {
            quickview.type = qvType;
            quickview.styleSheet = mw.util.addCSS(
                ":root { --width: 40vw } " +
                "body.quickview {margin-right: var(--width)} " +
                "body.quickview #p-personal {margin-right: var(--width)} " +
                "body.quickview #right-navigation {margin-right: var(--width)} " +
                "body:not(.quickview) #quickview {display: none} " +
                "#quickview {position:fixed; top: 0; right: 0; bottom: 0; width: var(--width); border-left: 2px solid #a7d7f9; box-shadow: 0px 0px 4px 2px #eee; background-color: #fcfdfe; padding-top:10px;} " +
                "#quickview:before {top: -100px; content: ''; position: absolute; left: -30px; width: 0; height: 0; border: 15px solid transparent; border-right-color: #a7d7f9; margin-top:-15px;} " +
                "#quickview:after  {top: -100px; content: ''; position: absolute; left: -25px; width: 0; height: 0; border: 15px solid transparent; border-right-color: transparent; margin-top:-15px;} " +
                "#quickview-slider {position:absolute; top: 20px; left: -10px; bottom: 0; width: 15px; opacity: 0; cursor: ew-resize; } " +
                "#quickview-content {overflow: auto scroll; height: calc(100% - 120px); width: calc(100% - 20px); padding: 10px 10px 100px; line-height: 1.6; font-size: 0.875em;} " +
                "#quickview-content .mw-revslider-container, #quickview-content .ve-init-mw-diffPage-diffMode {display:none} " +
                "#quickview-content > #empty {position:absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #a7d7f9; font-size: 1.5em; font-weight: bold; text-align:center;} " +
                "#quickview-content > #empty img {width: 30px; height: 30px; opacity:0.5;} " +
                "#quickview-content > #empty #empty-sub {font-size: 0.8em; font-weight: normal; padding-top: 1em;} " +
                "#quickview-content > #empty #empty-sub a {opacity: 0.5} " +
                ".quickview-active, .quickview-active:link, .quickview-active:active, .quickview-active:hover, .quickview-active:visited { color: orange !important; text-shadow: 0px 0px 1px white !important} " +
                "#quickview-popout {display:block; position:absolute; top:0; left:0px; width: 10px; height: 10px; background-color: #a7d7f9; padding: 1px; line-height:8px;} " +
                "#quickview-popout img {width: 8px; height: 8px;} " +
                "body.quickview .mw-changeslist-legend {display:none;} " +
                ""
            );
            if ([quickview.typeEnum.WATCHLIST, quickview.typeEnum.RECENT, quickview.typeEnum.RELATED].indexOf(qvType)>-1
                && $("#mw-content-text > .mw-rcfilters-ui-changesListWrapperWidget").length) {
                quickview.changeslist = ".mw-rcfilters-ui-changesListWrapperWidget";
                quickview.selector = ".mw-rcfilters-ui-changesListWrapperWidget > *:not(.mw-changeslist-legend) a:not(.mw-unwatch-link)";
            } else if (qvType == quickview.typeEnum.CONTRIBS && $(".mw-contributions-list").length) {
                quickview.changeslist = ".mw-contributions-list";
                quickview.selector = ".mw-contributions-list a";
            } else if (qvType == quickview.typeEnum.DELCONTRIBS && $("#mw-content-text > ul").length) {
                quickview.changeslist = "#mw-content-text > ul";
                quickview.selector = "#mw-content-text > ul a";
            } else if (qvType == quickview.typeEnum.HISTORY && $("ul#pagehistory").length) {
                quickview.changeslist = "ul#pagehistory";
                quickview.selector = "ul#pagehistory a";
			} else if (qvType == quickview.typeEnum.CATEGORY && $(".mw-category").length) {
				quickview.changeslist = ".mw-category-generated";
                quickview.selector = ".mw-category-generated a";
                console.log("category");
			} else if (qvType == quickview.typeEnum.RESULTS && $(".searchresults").length) {
				quickview.changeslist = ".mw-search-results";
				quickview.selector = ".mw-search-result-heading a";
            } else if (qvType == quickview.typeEnum.LOG && $("#mw-content-text ul").length) {
                quickview.changeslist = "#mw-content-text ul";
                quickview.selector = "#mw-content-text ul li a";
            } else {
                console.log("Quickview did not load.");
                return;
            }
            console.log("Quickview: " + qvType);
            mw.loader.load("mediawiki.diff.styles");

            var quickviewWrapper = document.createElement("div");
            quickviewWrapper.id="quickview";
            var quickviewContent = document.createElement("div");
            quickviewContent.id="quickview-content";
            $("body").append(quickviewWrapper);
            $(quickviewWrapper).append(quickviewContent);
            var quickviewPopout = document.createElement("a");
            quickviewPopout.id="quickview-popout";
            quickviewPopout.target="_blank";
            var img = document.createElement("img");
            img.src = "https://upload.wikimedia.org/wikipedia/commons/e/eb/OOjs_UI_icon_newWindow-ltr.svg";
            quickviewPopout.append(img);
            $(quickviewWrapper).append(quickviewPopout);

            quickview.chkEnabled = new OO.ui.CheckboxInputWidget( {
                value: 'quickview',
                selected: true,
            } );
            var fieldset = new OO.ui.FieldsetLayout( {id: 'quickview-fieldset'} );
            fieldset.addItems( [new OO.ui.FieldLayout(quickview.chkEnabled, {
                label: $( '<span>Load links in split screen (<a href="/wiki/User:Bradv/Scripts/Quickview" target="_blank">Quickview</a>)</span>' ),
                align: 'inline'
            } ) ] );
            $(quickview.changeslist).before(fieldset.$element);
            quickview.chkEnabled.on("change", function(value) {
                if (value) quickview.enable(); else quickview.disable();
            });
            $(document).scroll(quickview.scroll);
            if (localStorage.getItem("quickview:" + quickview.type)=="disabled") {
                quickview.chkEnabled.setSelected(false);
            } else {
                quickview.enable();
            }

            var quickviewSlider = document.createElement("div");
            quickviewSlider.id="quickview-slider";
            $(quickviewWrapper).append(quickviewSlider);
            var qvs = $(quickviewSlider);
            qvs.mousedown(function(event) {
                if (event.which==1) {
                    qvs.mm = function(event) {
                        event.preventDefault();
                        quickview.resize("calc(100vw - 12px - " + event.pageX + "px)", true);
                    }
                    $("body").mousemove(qvs.mm);
                    $("body").mouseup(function(event) {
                        $("body").off("mousemove", qvs.mm);
                        quickview.resize();
                    });
                }
            });

            console.log("Quickview loaded");
        },
        scroll: function() {
            if (quickview.sstemp) {
                $(quickview.sstemp.ownerNode).remove();
            }
            var active = $(".quickview-active");
            if (active.length) {
                var pos = $(active).offset().top - $(document).scrollTop() + ($(active).outerHeight()/2);
                quickview.sstemp = mw.util.addCSS('#quickview:before {top: ' + pos + 'px} #quickview:after {top: ' + pos + 'px}');
            }
        },
        clickhandler: function(event) {
            var target = event.currentTarget;
            event.preventDefault();
            function msg(text) {
                var c = $("#quickview-content");
                c.empty();
                var div = document.createElement("div");
                div.id="empty";
                div.append(document.createTextNode(text));
                c.append(div);
            }
            function msgLoading() {
                var c = $("#quickview-content");
                c.empty();
                var div = document.createElement("div");
                div.id="empty";
                var svg = document.createElement("img");
                svg.src="https://upload.wikimedia.org/wikipedia/commons/3/30/Chromiumthrobber.svg";
                div.append(svg);
                c.append(div);
            }
            function msgErr(url) {
                var c = $("#quickview-content");
                c.empty();
                var div = document.createElement("div");
                div.id="empty";
                c.append(div);
                $(div).html("Page could not be displayed.<div id='empty-sub'><a href='"+url+"' target='_blank'>Open in new tab</a>.");
            }
            function load(url) {
                $("#quickview-popout").attr("href", url);
                $("#quickview-content").load(url + " #mw-content-text", function(response, status, xhr) {
                    if(status=="success") {
                        var content = $("#quickview-content");
                        if (content.children().length===0) msg("No results");
                        $(content).find("form.mw-contributions-form").remove();
                        $("#quickview-content form[action]").attr('target', '_blank')
                        $(content).find("a[href]:not([href^='#'])").attr('target', '_blank');

                        if (url.indexOf("#")>=0) {
                            var hash = url.substring(url.indexOf("#")+1);
                            hash = $.escapeSelector(hash);
                            $(content).scrollTop($("#quickview-content #" + hash).offset().top-$(content).offset().top);
                        }
                        try {
                            $("#quickview-content .mw-collapsible").makeCollapsible();
                        } catch (e)
                        {}
                    } else {
                        console.log(xhr);
                        msgErr(url);
                    }
                });
            }
            var url = target.href;
            $(".quickview-active").removeClass("quickview-active");
            $(target).addClass("quickview-active");
            $("#quickview-content").empty();
            msgLoading();
            load(url);
            quickview.show();
        },
        observer: null,
        enable: function() {
            localStorage.setItem("quickview:" + quickview.type, "enabled");
            function bind() {
                $(quickview.selector).click(quickview.clickhandler);
                quickview.scroll();
            }
            quickview.observer = new MutationObserver(bind);
            quickview.observer.observe($(quickview.changeslist).get(0), {childList: true, subtree: true});
            bind();
        },
        disable: function() {
            localStorage.setItem("quickview:" + quickview.type, "disabled");
            if (quickview.observer) quickview.observer.disconnect();
            $(quickview.selector).off("click");
            quickview.hide();
        },
        show: function() {
            $("body").addClass("quickview");
            quickview.scroll();
            quickview.resize();
        },
        hide: function() {
            $("body").removeClass("quickview");
            $(".quickview-active").removeClass("quickview-active");
            quickview.resize();
        },
        resize: function(val, suppresstrigger) {
            if (val) document.body.style.setProperty('--width', val);
            if (!suppresstrigger) window.dispatchEvent(new Event('resize'));
        }
    };

    var cspn = mw.config.get("wgCanonicalSpecialPageName");
    if (cspn=="Contributions") {
        mw.loader.using("mediawiki.util").then(function () {
            quickview.init(quickview.typeEnum.CONTRIBS)
        });
    } else if (cspn=="DeletedContributions") {
        mw.loader.using("mediawiki.util").then(function () {
            quickview.init(quickview.typeEnum.DELCONTRIBS)
        });
    } else if (cspn=="Watchlist") {
        mw.loader.using("mediawiki.rcfilters.filters.ui").then(function () {
            quickview.init(quickview.typeEnum.WATCHLIST)
        });
    } else if (cspn=="Recentchanges") {
        mw.loader.using("mediawiki.rcfilters.filters.ui").then(function () {
            quickview.init(quickview.typeEnum.RECENT)
        });
    } else if (cspn=="Recentchangeslinked") {
        mw.loader.using("mediawiki.rcfilters.filters.ui").then(function () {
            quickview.init(quickview.typeEnum.RELATED)
        });
    } else if (mw.config.get("wgAction")=="history") {
        mw.loader.using("mediawiki.util").then(function () {
            quickview.init(quickview.typeEnum.HISTORY)
        });
    } else if (mw.config.get("wgCanonicalNamespace")=="Category") {
        mw.loader.using(["mediawiki.util", "oojs-ui-core"]).then(function () {
            quickview.init(quickview.typeEnum.CATEGORY)
        });
    } else if (cspn=="Search") {
		mw.loader.using("mediawiki.util").then(function () {
			quickview.init(quickview.typeEnum.RESULTS)
		});
	} else if (cspn=="Log" || cspn=="CheckUserLog") {
        mw.loader.using(["mediawiki.util", "oojs-ui-core"]).then(function () {
            quickview.init(quickview.typeEnum.LOG)
        });
    }
}(jQuery, mediaWiki ));