Greasy Fork is available in English.

Fuck-Yudao

Help you climb over the paywall for a so-called "Free & Open Source Software", built by someone who truly understand our generations duty. To you-know-who: *thank you*. China's OSS environment got much better because of professionals like you.

// ==UserScript==
// @name         Fuck-Yudao
// @namespace    none
// @version      0.3
// @license      MIT
// @description  Help you climb over the paywall for a so-called "Free & Open Source Software", built by someone who truly understand our generations duty. To you-know-who: *thank you*. China's OSS environment got much better because of professionals like you.
// @author       The love you care
// @match        https://www.iocoder.cn/*
// @match        https://doc.iocoder.cn/*
// @match        https://cloud.iocoder.cn/*
// @grant        unsafeWindow
// @run-at document-end
// ==/UserScript==


(function() {
    'use strict';

    // Overwrite jqueryAlert, simply comment out `init` can disable the annoying dialog
    unsafeWindow.jqueryAlert = function(opts) {
        var opt = {
            'style': 'wap',
            'title': '',
            'content': '',
            'contentTextAlign': 'center',
            'width': 'auto',
            'height': 'auto',
            'minWidth': '0',
            "className": '',
            'position': 'fixed',
            'animateType': 'scale',
            'modal': false,
            'isModalClose': false,
            'bodyScroll': false,
            'closeTime': 3000,
            "buttons": {},
        }
        var option = $.extend({}, opt, opts);
        var dialog = {}
        dialog.time = 0;
        dialog.init = function() {
            dialog.framework();
        }
        var isHaveTouch = "ontouchend"in document ? true : false;
        if (isHaveTouch) {
            dialog.event = 'touchstart';
        } else {
            dialog.event = 'click';
        }
        var $modal = $("<div class='alert-modal'>")
        var $container = $("<div class='alert-container animated'>");
        var $title = $("<div class='alert-title'>" + option.title + "</div>");
        var $content = $("<div class='alert-content'>");
        var $buttonBox = $("<div class='alert-btn-box'>");
        var $closeBtn = $("<div class='alert-btn-close'>×</div>");
        if (option.content[0].nodeType == 1) {
            var $newContent = option.content.clone();
            $content.append($newContent)
        } else {
            $content.html(option.content);
        }
        dialog.framework = function() {
            dialog.buttons = [];
            for (var key in option.buttons) {
                dialog.buttons.push(key);
            }
            dialog.buttonsLength = dialog.buttons.length;
            $container.append($title).append($content);
            if (option.style == 'pc') {
                $container.append($closeBtn).addClass('pcAlert');
            }
            if (option.modal || option.modal == 'true') {
                $('body').append($modal)
                option.bodyScroll && $('body').css('overflow', 'hidden');
            }
            $('body').append($container)
            $content.css({
                'text-align': option.contentTextAlign
            })
            if (parseInt(option.minWidth) > parseInt($container.css('width'))) {
                option.width = option.minWidth;
            }
            $modal.css('position', option.position);
            $modal.css('z-index', zIndex);
            ++zIndex;
            if (option.position == 'fixed') {
                $container.css({
                    'position': option.position,
                    'left': '50%',
                    'top': '50%',
                    'z-index': zIndex,
                })
            }
            if (option.position == 'absolute') {
                $container.css({
                    'position': option.position,
                    'left': $(window).width() / 2,
                    'top': $(window).height() / 2 + $(window).scrollTop(),
                    'z-index': zIndex,
                })
            }
            $container.css('width', option.width);
            $container.css('height', option.height);
            if (option.width == 'auto') {
                $container.css('width', $container[0].clientWidth + 10);
            }
            if (parseInt($(window).height()) <= parseInt($container.css('height'))) {
                $container.css('height', $(window).height());
            }
            (!!option.className) && $container.addClass(option.className);
            for (var key in option.buttons) {
                var $button = $("<p class='alert-btn-p'>" + key + "</p>");
                if (option.style != 'pc') {
                    $button.css({
                        'width': Math.floor(($container[0].clientWidth) / dialog.buttonsLength),
                    })
                }
                $button.bind(dialog.event, option.buttons[key]);
                $buttonBox.append($button);
            }
            if (dialog.buttonsLength > 0) {
                $container.append($buttonBox);
                $content.css('padding-bottom', '46px');
            }
            if (option.title != '') {
                $content.css('padding-top', '42px');
            }
            if (dialog.buttonsLength <= 0 && option.title == '') {
                $container.addClass('alert-container-black');
            }
            $container.css({
                'margin-left': -parseInt($container.css('width')) / 2,
                'margin-top': -parseInt($container.css('height')) / 2,
            });
            if (option.animateType == 'scale') {
                $container.addClass('bounceIn');
            }
            if (option.animateType == 'linear') {
                $container.addClass('linearTop');
            }
            isSelfClose();
        }
        ;
        function isSelfClose() {
            if (dialog.buttonsLength <= 0 && option.style != 'pc') {
                setTimeout(function() {
                    $container.fadeOut(300);
                    $modal.fadeOut(300);
                    option.bodyScroll && $('body').css('overflow', 'auto');
                }, option.closeTime)
            }
        }
        dialog.toggleAnimate = function() {
            if (option.animateType == 'scale') {
                return $container.removeClass('bounceIn').addClass('bounceOut');
            } else if (option.animateType == 'linear') {
                return $container.removeClass('linearTop').addClass('linearBottom');
            } else {
                return $container;
            }
        }
        dialog.close = function() {
            dialog.toggleAnimate().fadeOut(dialog.time);
            $modal.fadeOut(dialog.time);
            option.bodyScroll && $('body').css('overflow', 'auto');
        }
        ;
        option.style == 'pc' && $closeBtn.bind(dialog.event, dialog.close);
        option.isModalClose && $modal.bind(dialog.event, dialog.close);
        dialog.destroy = function() {
            dialog.toggleAnimate().fadeOut(dialog.time);
            setTimeout(function() {
                $container.remove();
                $modal.remove();
                option.bodyScroll && $('body').css('overflow', 'auto');
            }, dialog.time)
        }
        dialog.show = function() {
        }
        // dialog.init();
        dialog.close();
        return dialog;
    }


    // The content of yudao's pooly-written documentation. Almost at the same miserable level as uni-app's docs.
    // Read the docs of vue, react and a lot more responsible, real open source repos to learn how to make professional statements.
    let yudaosPoorlyWrittenDoc = null, prevPath = document.location.pathname;
    // The routes that are currently being marked as VIP only. Real jokes.
    const blockPathList = ['bpm', 'user-center', 'social-user', 'oauth2', 'saas-tenant', 'sms', 'mail', 'notify', 'mybatis-pro', 'dynamic-datasource', 'report', 'Spring-Boot', 'Spring-Cloud', 'api-doc', 'module-new', 'new-feature', 'dev-hot-swap', 'file', 'message-queue', 'job', 'idempotent', 'distributed-lock', 'rate-limiter', 'project-rename', 'delete-code', 'resource-permission', 'data-permission', 'deployment-linux', 'deployment-docker', 'mp', 'mall', 'pay', 'crm', 'member', 'erp', 'websocket', 'vo', 'system-log', 'ai'];

    // If the current url is 'blocked'.
    // You do know that for a static documentation site nothing is really blocked, don't you
    const isBlocked = () => {
        const ret = blockPathList.some((e) => document.location.pathname.includes(e));
        return ret;
    }

    // Get the documentation content wrapper element
    const getWrapper = () => {
        return document.querySelector('.content-wrapper');
    }

    const replace = (str) => {
        const wrapper = getWrapper()
        if (str) {
            while (wrapper.innerHTML !== str) {
                wrapper.innerHTML = str
            }
        }
    }

    const contentObserver = new MutationObserver(() => {
        if (getWrapper().innerHTML.includes('仅 VIP 可见')) {
            replace(yudaosPoorlyWrittenDoc)
        }
    })

    const urlObserver = new MutationObserver(() => {
        const wrapperEl = getWrapper()
        /*
        if (document.location.href !== 'https://doc.iocoder.cn/' && isBlocked() && !window.location.href.includes('refreshed')) {
            window.location.href = window.location.href + '?refreshed=1'
            // window.location.reload();
        }
        */
        if (prevPath !== document.location.pathname) {
            window.location.reload()
        }
    })

    urlObserver.observe(document.body, { childList: true })

    //=============================================================================================================================================

    const $$wrapper = getWrapper();
    if (getWrapper() && isBlocked()) {
        yudaosPoorlyWrittenDoc = $$wrapper.innerHTML.includes('仅 VIP 可见') ? null : $$wrapper.innerHTML;
        unsafeWindow.$$content = yudaosPoorlyWrittenDoc;
        unsafeWindow.$$replace = function() {
            replace(unsafeWindow.$$content)
        }
        contentObserver.observe($$wrapper, { childList: true, characterData: true, subtree: true });
        replace(yudaosPoorlyWrittenDoc);
    }

    //=============================================================================================================================================

})();