View StackOverflow code snippet

Open code snippet on Stack Exchange in CodePen / JSFiddle

Versione datata 25/08/2017. Vedi la nuova versione l'ultima versione.

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==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);