View StackOverflow code snippet

Open code snippet on Stack Exchange in CodePen / JSFiddle

От 25.08.2017. Виж последната версия.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==UserScript==
// @name        View StackOverflow code snippet
// @description Open code snippet on Stack Exchange in CodePen / JSFiddle
// @namespace   https://github.com/tiansh/
// @include     https://stackoverflow.com/*
// @include     https://codegolf.stackexchange.com/*
// @include     https://codereview.stackexchange.com/*
// @include     https://gamedev.stackexchange.com/*
// @include     https://es.stackoverflow.com/*
// @include     https://ja.stackoverflow.com/*
// @include     https://pt.stackoverflow.com/*
// @include     https://ru.stackoverflow.com/*
// @homepageURL https://github.com/tiansh/vsocs
// @supportURL  https://github.com/tiansh/vsocs/issues
// @version     1.0
// @license     MPL 2.0
// @grant       none
// ==/UserScript==

// This file is modified from a file of kuma project of Mozilla
// https://github.com/mozilla/kuma/blob/00fc05b101658f863f58d7fc2b1aefecbcf71cf8/kuma/static/js/wiki-samples.js
// The original file is created by Mozilla Foundation and its contributors, and is licensed under MPL 2.0

(function(win, doc, $) {
    "use strict";

    var sites = ['codepen', 'jsfiddle'];

    var sourceURL = win.location.href.split('#')[0];
    var plug = '<!-- Content from the Stack Exchange network: ' + sourceURL + ' \n' +
        '     User contributions of Stack Exchange licensed under cc by-sa 3.0 with attribution required -->\n\n';

    var handleSnippet = function () {
        $('.snippet-ctas').each(function() {
            var $this = $(this);
            if ($this.find('.open-in-host-container').length) return;
            var $snippet = $this.closest('.snippet');
            createSampleButtons($snippet);
        });
    };
  
    var observer = new MutationObserver(handleSnippet);
    observer.observe(document.documentElement, { childList: true, subtree: true });
    handleSnippet();

    function openJSFiddle(title, htmlCode, cssCode, jsCode) {
        var $form = $(
            '<form target="_blank" method="post" action="https://jsfiddle.net/api/post/library/pure/" style="display:none!important">' +
                '<input type="hidden" name="html" />' +
                '<input type="hidden" name="css" />' +
                '<input type="hidden" name="js" />' +
                '<input type="hidden" name="title" />' +
                '<input type="hidden" name="wrap" value="b" />' +
                '<input type="submit" />' +
            '</form>'
        ).appendTo(doc.body);

        $form.find('input[name=html]').val(plug + htmlCode);
        $form.find('input[name=css]').val(cssCode);
        $form.find('input[name=js]').val(jsCode);
        $form.find('input[name=title]').val(title);
        $form.get(0).submit();
    }

    function openCodepen(title, htmlCode, cssCode, jsCode) {
        var $form = $(
            '<form target="_blank" method="post" action="https://codepen.io/pen/define" style="display:none!important">' +
                '<input type="hidden" name="data">' +
                '<input type="submit" />' +
            '</form>'
        ).appendTo(doc.body);

        var data = {
            'title': title,
            'html': plug + htmlCode,
            'css': cssCode,
            'js': jsCode
        };
        $form.find('input[name=data]').val(JSON.stringify(data));
        $form.get(0).submit();
    }

    function openSample(sampleCodeHost, title, htmlCode, cssCode, jsCode) {
        var cssCleanCode = cssCode.replace(/\xA0/g, " ");

        if (sampleCodeHost === 'jsfiddle') {
            openJSFiddle(title, htmlCode, cssCleanCode, jsCode);
        } else if (sampleCodeHost === 'codepen') {
            openCodepen(title, htmlCode, cssCleanCode, jsCode);
        }
    }
    
    var getButtonText = (function () {
        var lang = 'en';
        if (location.host === 'es.stackoverflow.com') lang = 'es';
        if (location.host === 'ja.stackoverflow.com') lang = 'ja';
        if (location.host === 'pt.stackoverflow.com') lang = 'pt';
        if (location.host === 'ru.stackoverflow.com') lang = 'ru';
        return ({
           en: function (host) { return 'Open in ' + host; },
           es: function (host) { return 'Abrir en ' + host; },
           ja: function (host) { return host + ' で開く'; },
           pt: function (host) { return 'Abrir em ' + host; },
           ru: function (host) { return 'Открыть на ' + host; },
        })[lang];
    }());
    
    function createSampleButtons($snippet) {

        var htmlCode = $snippet.find('.snippet-code-html').text();
        var cssCode = $snippet.find('.snippet-code-css').text();
        var jsCode = $snippet.find('.snippet-code-js').text();
        var title = document.title;

        var $sampleFrame = $snippet.find('.snippet-ctas');

        if (htmlCode + cssCode + jsCode === '') return;

        // add buttons if we have good data
        var $buttonContainer = $('<div class="open-in-host-container" />');
        $.each(sites, function() {
            // convert sitename to lowercase for icon name and host identifier
            var sampleCodeHost = this.toLowerCase();
            // create button
            var $button = $('<button />', { 'class': 'open-in-host' });
            // create text
            var $text = $('<span />').text(getButtonText(sampleCodeHost));

            // add button icon and text to DOM
            $button.append($text).appendTo($buttonContainer);

            // add listener for button interactions
            $button.on('click', function() {
                openSample(sampleCodeHost, title, htmlCode, cssCode, jsCode);
            });
        });
        $buttonContainer.appendTo($sampleFrame);
    }
  
    $('<style>').text(
        '.open-in-host-container { text-align: right; }' +
        '.open-in-host-container > button:not(:last-child) { margin-right: 6px; }' +
        '.snippet-code .popout { top: -80px; }'
    ).appendTo($('head'));

})(window, document, jQuery);