JSFiddle - React, Tailwind, and code Playground

by msm595

HTML

<script src="https://raw.github.com/soundcloud/Widget-JS-API/master/soundcloud.player.api.js"></script>
<div id="container">
    <span id="name">Loading...</span>
    <div id="controls">
        <a href="#" id="rewind"></a>
        <a href="#" id="play" class="play"></a>
        <a href="#" id="forward"></a>
        <div id="scrubber"><div id="scrubberBack">&nbsp;</div><div id="bufferedP">&nbsp;</div><div id="playedP">&nbsp;</div></div>
        <span id="time">[ <span id="currentTime">0:00</span>/<span id="duration">0:00</span> ]</span>
    </div>
    <div id="players">
        <object style="height: 250px; width: 250px;" id="youtubePlayer">
            <param name="movie" value="http://www.youtube.com/apiplayer?enablejsapi=1&version=3&playerapiid=ytplayer">
            <param name="allowFullScreen" value="true">
            <param name="allowScriptAccess" value="always">
            <embed src="http://www.youtube.com/apiplayer?enablejsapi=1&version=3&playerapiid=ytplayer" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="250" height="250" id="youtubePlayerE"></object>

    <!--<object height="81" width="100%" id="soundcloud" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"> <param name="movie" value="http://player.soundcloud.com/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F23562125&show_comments=false&auto_play=false&color=64D4FF&object_id=soundcloud&enable_api=true"></param> <param name="allowscriptaccess" value="always"></param> <embed name="soundcloud" allowscriptaccess="always" height="81" src="http://player.soundcloud.com/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F23562125&show_comments=false&auto_play=false&color=64D4FF&object_id=soundcloud&enable_api=true" type="application/x-shockwave-flash" width="100%"></embed> </object>-->
    </div>
</div>

CSS

html {
    height: 100%; 
    width: 80%;
    min-width: 600px;
    margin: 0 auto;
    padding: 80px 0 0; /*nvm *padding on bottom to offset padding in the body*/
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    background: #3f3f3f;
    text-shadow: #ddd 1px 1px 2px;
    color: #eee;
}
body {
    margin: 0;
    min-height: 100%;
    padding: 0 32px;
    position: relative;
    background: #1f1f1f;

    -moz-box-shadow: 0 0 0 1px #4b4b4b, 0 0 0 2px black, 0 0 20px -3px white;
    -webkit-box-shadow: 0 0 0 1px #4b4b4b, 0 0 0 2px black, 0 0 20px -3px white;
    box-shadow: 0 0 0 1px #4b4b4b, 0 0 0 2px black, 0 0 20px -3px white;

    background-image: -moz-linear-gradient(top, #1f1f1f 60%, #222 100%);
    background-image: -webkit-linear-gradient(top, #1f1f1f 60%, #222 100%);
    background-image: -o-linear-gradient(top, #1f1f1f 60%, #222 100%);
    background-image: linear-gradient(top, #1f1f1f 60%, #222 100%);
}

::-moz-selection{ background: #68BEFF; color:#fff; text-shadow: none; }
::selection { background:#68BEFF; color:#fff; text-shadow: none; } 

#container{
    text-align: center;
    font-family: "Lucida Grande", Helvetica, Arial, sans-serif;
}

#name{
    font-family: 'Wire One', sans-serif;
    font-size: 120px;
    line-height: 168px;
    display: block;
    overflow: hidden;
    white-space: nowrap;
}

/*arrow code adapted from http://hedgerwow.appspot.com/demo/arrows*/
.play,
.stop,
#rewind,
#rewind:before,
#forward,
#forward:after,
.play,
.stop{
    font-size: 32px;
    height: 0;
    line-height: 0;
    position: relative;
    vertical-align: middle;
    width: 0;
    border-style: dashed;
    border-color: transparent;
    border-width: 0.53em;
    display: -moz-inline-box;
    display: inline-block;
}

/*.stop {
  border-left: 1em solid #ccc;
  margin-left: .5em;
}
.stop:hover {
    border-left-color: #64D4FF;
}

.play {
    border: .5em solid #ccc;
    margin: 0 .5em;
}
.play:hover {
   ...

JavaScript

"use strict";

var settings = {
    maxTries: 5,    
    updateInterval: 250 //update bar every 40ms
};

var goodSongs = ['hGRqnNEOpe0', 'BgVfjXA_QY0', 's88r_q7oufE', 'ySzrJ4GRF7s', 'V5UOC0C0x8Q', 'F_Ck5e8Rtdk', 'QmIF6Yqad-0'];

/*Logging*/
var log = (function(o) {
    var level = 2; //0: just errors, 1: error and warnings, 2: errors, warnings, and everything

    o.error = function() {
        msg("Error", arguments);
    }

    o.log = function() {
        if (level >= 2)
            msg("Log", arguments);
    }

    function msg(type, msgs) {
        console.log(type + ": " + [].join.call(msgs, " "));
    }

    return o;
})({});

/*A basic lock class*/
function Lock() {
    var _lock = "";

    function isFree() {
        return _lock == "";
    }

    function lock(caller) {
        if (_lock != "")
            return false;
        
        _lock = caller;
        return true;
    }

    function unlock(caller) {
        if (_lock == caller) {
            _lock = "";
            return true;
        }

        return false;
    }

    function hasLock(caller) {
        return _lock == caller;
    }

    function canUse(caller) {
        return hasLock(caller) || isFree();
    }

    return {
        isFree: isFree,
        lock: lock,
        unlock: unlock,
        canUse: canUse,
        hasLock: hasLock
    };
}

/*A basic event emitter class*/
function EventEmitter() {
    var events = {};
    function on(event, func) {
        if (!(event in events))
            events[event] = [];
        
        log.log("EventEmitter on", event);
        events[event].push(func);
        console.log(events);
    }

    function once(event, func) {
        var wrap = (function(e,f,t) {
            return function w() {
                t.removeEventListener(e,w);
                f.apply(this, arguments);
            };
        })(event, func, this);
        on(event, wrap);
    }

    function removeEventListener(event, func) {
        log.log("EventEmitter remove",...