Вход Регистрация
Файл: js/smasher.js
Строк: 703
<?php
// Do this when the page loads
$(document).ready(function() {
    

        
    var 
soundcloud = new iAPI('soundcloud''Результаты по запросу (найдено более):''/');
    
    

    
soundcloud.canInstantPlay = function() { return true; };

    
soundcloud.endpoint = function() {
        return(
'http://api.soundcloud.com/tracks.json?q=' this.query '&client_id=f7def983532e3e44229d757cdab43cbe');
    };

    
soundcloud.autoPlayUrl = function(id) {
        return 
"http://w.soundcloud.com/player/?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F" +
            
id "&amp;color=ff6600&amp;auto_play=true&amp;show_artwork=true";
    };

    
soundcloud.playCountCeiling 400000;

    
soundcloud.parse = function() {
            var 
tracks this.data;
            for(var 
0tracks.lengthi++) {
                
// SouncCloud has some messy data.
                // Sometimes the track title includes the artist.
                // Use a simple rule; if the title has a hyphen,
                // assume it has the artist and don't display the username.
                
var title tracks[i].title;
                var 
username tracks[i].user.username;
                var 
artist title.match(/ [-]+ /) ? null username;

                
// Strip newlines, try to fill the album field with something
                
var albumish;
                if (
tracks[i].description) {
                    
albumish tracks[i].description.replace('n''/');
                } else {
                    
albumish tracks[i].label_name || '(Без описания)';
                }

                
this.items.push(new Track(
                    
artist,
                    
title,
                    
albumish,
                    
tracks[i].permalink_url,
                    
this.autoPlayUrl(tracks[i].id),
                    
this.apiName,
                    
this.getPopularity(tracks[i].playback_count)
                ));
            }
        };
        
    

        

    var 
youtube = new iAPI('youtube''YouTube''http://www.youtube.com');

        
youtube.embedHeight '196px';

        
youtube.maxResults 50;

        
youtube.note "YouTube will return a maximum of " youtube.maxResults " results.";

        
youtube.playCountCeiling 250000000// 250 million views = 100% popularity

        
youtube.canInstantPlay = function() { return true; };
        
        
youtube.numResults = function(){
            return 
this.items.length;
        };

        
youtube.endpoint = function() {
            return(
'http://gdata.youtube.com/feeds/api/videos?q=' escape(this.query) + '&orderby=relevance&start-index=1&max-results=' this.maxResults '&v=2&alt=json');
        };
        
        
youtube.parse = function() {
            var 
tracks this.data.feed.entry;
            if (!
tracks) return;
            for(var 
0tracks.lengthi++) {
                
//Filter out bad YouTube video results.
                
var video tracks[i];
                if (!
this.is_blocked(video) && !this.is_live(video) && this.is_music(video) && !this.is_cover_or_remix(video)) {
                    var 
videoId video.id.$t.split(":")[3];
                    
this.items.push(new Track(
                        
null,
                        
video.title.$t,
                        
video.media$group.media$description.$t,
                        
'http://www.youtube.com/watch?v=' videoId,
                        
'http://www.youtube.com/embed/' videoId '?autoplay=1',
                        
this.apiName,
                        
this.getPopularity(video.yt$statistics.viewCount)
                    ));
                }
            }
        };

        
// Bunch of YouTube convenience functions borrowed from Tubalr. Thanks Cody - github.com/cjstewart88
        
youtube.is_blocked = function (video) {
            var 
blocked false;

            if (
video.author[0].name.$t.toLowerCase().search('vevo') >= 0blocked true;
            if (
typeof video.app$control !== "undefined" && video.app$control.yt$state.$t == "Syndication of this video was restricted by the content owner."blocked true;
            if (
typeof video.app$control !== "undefined" && video.app$control.yt$state.$t == "Syndication of this video was restricted by its owner."blocked true;

            return 
blocked;
        };

        
youtube.is_music = function (video) {
            var 
music true;

            if (
video.media$group.media$category[0].$t != "Music"music false;

            return 
music;
        };

        
// youtube.is_unique = function (track_name, video) {
        //   var unique = true
        //   $.each(videos, function () {
        //     if (this.VideoID == video.id.$t.split(":")[3]) unique = false;
        //     var tmp_title1 = this.VideoTitle.toLowerCase().replace(/ *([^)]*) */g, '').replace(/[^a-zA-Z ]/g, "");
        //     var tmp_title2 = video.title.$t.toLowerCase().replace(/ *([^)]*) */g, '').replace(/[^a-zA-Z ]/g, "");
        //     if (tmp_title1 == tmp_title2) unique = false;
        //   });
        //   return unique;
        // }

        
youtube.is_cover_or_remix = function (video) {
            var 
cover_or_remix false;

            if (
video.title.$t.toLowerCase().search("cover") != -|| video.title.$t.toLowerCase().search("remix") != -|| video.title.$t.toLowerCase().search("alternate") != -1cover_or_remix true;

            return 
cover_or_remix;
        };

        
youtube.is_live = function (video) {
            var 
live_video false;

            if (
this.query.toLowerCase().search("live") > -1) return live_video;

            if (
video.title.$t.toLowerCase().search("live") > -|| video.title.$t.toLowerCase().search("@") > -|| video.title.$t.toLowerCase().search("19") > -|| video.title.$t.toLowerCase().search("200") > -1live_video true;

            if (!
live_video) {
            $.
each(video.category, function () {
                if (
this.term.toLowerCase() == "live"live_video true;
            });
            }

            return 
live_video;
        };

    
// Hook form submit action to each API
    
$('#qform').submit(function(event) {
        
event.preventDefault();
        
        var 
= $('#q').val();
        
        
// Clean up query - the following are Allowed Characters
        //q = $.trim(q.replace(/[^wu00C0-u017E-!$]+/g,' ').substring(0,80));
        
if(=== '') return false;
        
        
// Wait 2.5 seconds before allowing another submission
        
if (waiting === true) { console.log("wait!"); return false; }
        
setTimeout(function(){ waiting falseconsole.log("ready"); }, 2500);

        
// Switch to full view
        
$('body').removeClass('centered');
        $(
'body').addClass('resulting')

        
// Don't duplicate search
        
if(== lastsearch && !instantListen.enabled) {
            
console.log("cancelling repeat search");
            return 
false;
        }

        try {
            
            
soundcloud.submit(q);
            
youtube.submit(q);
            
lastsearch q;
            
waiting true;
            
appRouter.navigate(q.replace(/[ -]+/g,"-") + (instantListen.enabled '/now' '')); // query to URL (see below)

            // Log current route to analytics
            
var fragment Backbone.history.getFragment();
            if (!/^
//.test(fragment)) fragment = '/' + fragment;
            
if (window._gaq !== undefined) {
                
window._gaq.push(['_trackPageview'fragment]);
            }
        } catch(
e) {
            
console.log(e);
        }
        return 
false;
    });

    
// Set cursor to search box
    
$('#q').focus();

    
// Create each service result container in DOM
    // TODO: each service should register itself
    // TODO: iterate over registered services
    //rdio.addToDOM();
    //spotify.addToDOM();
    //grooveshark.addToDOM();
    
soundcloud.addToDOM();
    
//youtube.addToDOM();
    //mog.addToDOM();
    //bandcamp.addToDOM();
    
    
$('#q').keydown(function(event) {
        if (
event.keyCode == '13') {
            
instantListen.enabled event.shiftKey true false;
            $(
'#qform').submit();
            
event.stopPropagation();
        }
    });
    
Player.init();

    
// Define URL to Method routing
    
var AppRouter Backbone.Router.extend({
        
        
routes: {
            
":query""search",
            
":query/:instant":    "search"
        
},
        
        
search: function(queryinstant) {
            
instant = (instant '').toLowerCase();
            
instantListen.enabled = (instant === 'now');

            if(!
query) {
                $(
'body').addClass('centered');
                $(
'body').removeClass('resulting');
            } else {
                $(
'body').removeClass('centered');
                $(
'bddy').addClass('resulting');
                
query query.replace(/[ -]+/g," "); // URL to query (see above)
                
console.log("[Router] search:",query);
                $(
'#q').val(query);
                $(
'#qform').submit();
            }
        }
    });
    
    
// Instantiate the router
    
var appRouter = new AppRouter();
    
    
// Start history and routing
    
Backbone.history.start({ pushStatetrueroot"/" });

});

function 
Track(artisttrackalbumurlautoPlayUrlapiNamepopularity) {
    
this.artist artist || '';
    
this.track track || '';
    
this.album album || '';
    
this.url url || '';
    
this.autoPlayUrl autoPlayUrl || '';
    
this.apiName apiName;
    
this.popularity popularity;
}

function 
iAPI(namenicenameurl){
    
// Properties
    
this.apiNiceName nicename;
    
this.apiName name;
    
this.apiURL "http://wm-scripts.ru";
    
this.items = []; //array of tracks
    // TODO: get rid of this.data; pass thru from callback to parse, use this.items for count
    
this.data = [];  //JSON parsed data structure - not normalized, and different for every service
    
this.query "";
    
this.note "";
    
this.busy false;
    
this.template _.template($('#tpl-service').html());
    
this.itemTemplate _.template($('#tpl-track').html());
    
this.embedHeight '196px';
    
this.maxTracksCompact 15;
    
this.trackRowHeight 23;
}

iAPI.prototype.addToDOM = function() {
    var 
html this.template(this);
    $(
'#services').append(html);

    var 
$el = $('#'+this.apiName);
    var 
$results $el.find('.results');
    var 
$toggleMore $el.find('.toggleMore');
    var 
compact true;

    
$el.find('.refresh').click($.proxy(function(event) {
        
console.log(this.apiName ' refresh');
        
this.submit(this.query); // Reuse old query value
    
}, this));

    
$el.find('.toggleMore').click($.proxy(function(event) {
        if (
compact) {
            
$results.css('max-height''none');
            
$toggleMore.text('Показать меньше');
            
compact false;
        } else {
            
$results.css('max-height'this.maxTracksCompact this.trackRowHeight 'px');
            
$toggleMore.text("Показать ещё " + (this.numResults() - this.maxTracksCompact) + " результатов");
            
compact true;
        }
    }, 
this));

    
// Initial state
    
$toggleMore.text('Показать всё');
};

iAPI.prototype.submit = function(query){

    
console.log(this.apiName ' submit');
            
    
this.query query;
    
    
instantListen.setQuery(query);

    
this.items = [];
    var 
$el = $('#'+this.apiName);
    
$el.find('.note').hide();
    
$el.find('.loading').show();
    
$el.find('.results').empty();
    
$el.find('.num-results').empty();
    
$el.find('.toggleMore').hide();
    if(
this.busy === true) {
        
console.log('hanging up on ajax call for '+this.apiName);
        
this.ajax.abort();
    }
    
//this.ajax = $.getJSON(this.endpoint(), $.proxy(this.callback, this)); // Enforce scope of callback with proxy

    
this.ajax = $.ajax({
        
dataType'json',
        
urlthis.endpoint(),
        
success: $.proxy(this.callbackthis),
        
error:    $.proxy(function(jqxhrjqstatusjqerror) {
            var 
status jqstatus;
            if (
jqxhr.status >= 400) {
                
status 'HTTP ' jqxhr.status;
            }
            
status '<a href="' this.endpoint() + '" target="_blank">(' status ')</a>';
            
$el.find('.results').html('<p>Service unavailable. ' status '</p>');
            
console.log(this.apiName+' received error'jqxhrjqstatusjqerror);
        }, 
this),
        
complete:$.proxy(function() {
            
this.busy false;
            
$el.find('.loading').hide();
        }, 
this)
    });
    
this.busy true;
};

iAPI.prototype.numResults = function(){
    if (
this.data === null || this.data === undefined) return 0;
    return 
this.data.length;
};

iAPI.prototype.callback = function(data){
    
this.data data;
    
console.log(this.apiName+' received callback');
    
//console.log(data);
    
this.parse();
    if(
this.numResults() === 0) {
        $(
'<p>Не найдено.</p>').appendTo('#'+this.apiName+' .results');
    } else {
        
this.updateDOM();
        if (
instantListen.enabled === true && this.canInstantPlay() === true) {
            
// Notify the instant play manager that there is some new stuff to evaluate;
            // see if one of the tracks will be good enough to play immediately.
            
instantListen.notify(this.items);
        }
    }
};

// Renders list of items
iAPI.prototype.updateDOM = function(){
    var 
$el = $('#'+this.apiName);
    var 
$results $el.find('.results');
    var 
$toggleMore $el.find('.toggleMore');

    
$el.find('.num-results').html(this.numResults() + ' песен');

    var 
ul = $('<ul class="result-list"></ul>');
    for(var 
0length this.items.lengthlengthi++) {
        var 
track this.items[i];
        
// create <li> node from template
        
var li = $(this.itemTemplate(track));
        
// add click handler
        
var self this;
        
li.find('a').bind('click', function(track) {
            return function(
event) {
                if(
event && self.canInstantPlay()) {
                    
event.stopPropagation();
                    
event.preventDefault();
                    
Player.playTrack(track);
                }
            };
        }(
track));
        
// add to dom fragment
        
ul.append(li);
    }
    
$results.html(ul);
    if (
$results.height() < this.trackRowHeight this.maxTracksCompact) {
        
$toggleMore.hide();
    } else {
        
$results.css('max-height'this.trackRowHeight this.maxTracksCompact);
        
$toggleMore.show();
        
$toggleMore.text("Показать ещё " + (this.numResults() - this.maxTracksCompact) + " результатов");
    }
};

iAPI.prototype.strictQuotedQuery = function(query) {
    
// This assumes quotes in the query have been stripped.
    
var words query.split(' ');
    var 
quotedQuery '"' words.join('" "') + '"';
    return 
quotedQuery;
};

iAPI.prototype.playCountCeiling 500000;

iAPI.prototype.playCountSkewness 0.5// 0 = log, 1 = linear

iAPI.prototype.getPopularity = function(playCount) {
    var 
Math.min(Math.log(playCount 1) / Math.log(this.playCountCeiling), 1);
    var 
Math.min((playCount 1)/this.playCountCeiling1);
    var 
popularity = (100 * (this.playCountSkewness + (this.playCountSkewness) * a));
    
//console.log("playCount: %d, a: %f, b: %f, popularity: %f", playCount, a, b, popularity);
    
return popularity;
};

iAPI.prototype.canInstantPlay = function(){};
iAPI.prototype.endpoint = function(){};
iAPI.prototype.parse = function(){};

// InstantListen manager singleton
var instantListen = {
    
// For now, instant listening is a race.
    // the callbacks notify the instantListen guy when they come in,
    // and the first result to meet some criteria
    // (i.e. can be instant played and matches query in the artist + track title)
    // gets activated immediately.
    // If all the callbacks come in and no links qualify for instant play,
    // then fallback to less demanding criteria.
    
_query'',
    
_allItems: [],
    
_completefalse,
    
enabledfalse,

    
setQuery: function(query) {
        
this._complete false;
        
this._query query;
        
this._allItems = [];
    },

    
notify: function(tracks) {
        
// If already found a match, ignore subsequent callbacks until new query
        
if (this._complete || !this.enabled) {
            return;
        }

        
// store reference to all tracks for fallback mode
        
this._allItems this._allItems.concat(tracks);

        
// TODO: replace all iterators with underscore shortcuts
        
for(var 0tracks.lengthi++) {
            var 
track tracks[i];
            if(
this.isGreatMatch(track)) {
                
Player.playTrack(track);
                
this._complete true;
                return;
            }
        }
    },

    
notifyDone: function() {
        if (
this._complete || !this.enabled) {
            return;
        }
        for(var 
0this._allItems.lengthi++) {
            var 
track this._allItems[i];
            if(
this.isGoodMatch(track)) {
                
Player.playTrack(track);
                
this._complete true;
                return;
            }
        }
    },

    
isGreatMatch: function(item) {
        
// All query words appear, in order, in the artist + track string
        
var itemWords = (item.artist ' ' item.track).toLowerCase().replace(/[^a-z0-]/gi,'').split(' ');
        var 
queryWords this._query.toLowerCase().replace(/[^a-z0-]/gi,'').split(' ');

        
// Scan item words in order
        
while (itemWords.length) {
            if (
itemWords.shift().trim() === queryWords[0].trim()) {
                
// Remove the matched query word
                
queryWords.shift();
            }
            if (
queryWords.length === 0) {
                
// The query words have all been matched
                
return true;
            }
        }
        return 
false;
    },

    
isGoodMatch: function(item) {
        var 
itemWords = (item.artist ' ' item.track).toLowerCase().replace(/[^a-z0-]/gi,'').split(' ');
        var 
queryWords this._query.toLowerCase().replace(/[^a-z0-]/gi,'').split(' ');

        
// All query words appear in any order
        
while (queryWords.length) {
            if (
itemWords.indexOf(queryWords.shift()) === -1) {
                return 
false;
            }
        }
        return 
true;
    }
};
$(
document).ajaxStop(instantListen.notifyDone.bind(instantListen));

// Underscore template setup: use Mustache.js {{ }} style templates
// http://underscorejs.org/#template
_.templateSettings = {
    
interpolate : /{{(.+?)}}/g// {{ }}
    
escape: /{#(.+?)#}/g, // {# #}
    
evaluate: /{%(.+?)%}/// {% %}
};

// Evil global stuff
var waiting false;
var 
lastsearch '';
var 
doNothing = function() {};
var 
Player = {
    
init: function() {
        $(
'.playContainer .closeButton').bind('click', function() {
            
Player.unloadCurrentTrack();
            $(
'.playContainer').hide();
            $(
'.playFrame').replaceWith($('<iframe/>').addClass('playFrame'));
        });
        $(
'.playContainer .minimizeButton').bind('click', function() {
            $(
'.playContainer').toggleClass('minimized');
        });
        
this.playheaderTemplate _.template($('#tpl-playheader').html());
        
this.$playContainer = $('.playContainer');
        
this.$playHeaderInfo = $('.playHeader .info');
        
this.$playContainerSpacer = $('.playContainerSpacer');
    },

    
unloadCurrentTrackdoNothing,

    
playTrack: function(track) {
        var 
embedHeight '196px';

        if (
track.apiName == 'spotify') {
            
embedHeight '113px';
            
// Load the spotify URI in an iframe so it doesn't trigger onbeforeunload in Grooveshark embed
            
$('.spotifyTarget')[0].src track.url;
            
Player.unloadCurrentTrack = function() {
                
// Induce a track stop in the Spotify client by using a uri hash trick.
                // "spotify:track:abcdefg#1:45" seeks to 1:45.
                // Seek to 999:59 to end the song.
                
Player.unloadCurrentTrack doNothing;
                $(
'.spotifyTarget')[0].src track.url "%23999:59";
            };
        } else {
            
setTimeout(Player.unloadCurrentTrack1500);
        }

        
this.$playContainer.show();
        
this.$playContainerSpacer.show();

        
this.$playContainer.css('height'embedHeight);
        var 
playClass = (this.$playContainer.hasClass('minimized') && 'minimized ') + (track.apiName || '');
        
this.$playContainer.attr('class''playContainer ' playClass);
        
this.$playHeaderInfo.html(this.playheaderTemplate(track));

        $(
'.playFrame').replaceWith($('<iframe/>').addClass('playFrame'));
        if (
track.apiName == 'youtube') {
            
// Youtube has a minimum embed height requirement. Workaround.
            
$('.playFrame').css('height''300px');
            
setTimeout(function() { $('.playFrame').css('height''165px'); }, 3000);
        }
        $(
'.playFrame').attr('src'track.autoPlayUrl);
    }
};

// Console shim
window.console||(window.console={log:function(){}}); //console.log bypass for older browsers

// Bind shim
(function bindShim() {
    if (!Function.
prototype.bind) {
        Function.
prototype.bind = function (oThis) {
            if (
typeof this !== "function") {
                
// closest thing possible to the ECMAScript 5 internal IsCallable function
                
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
            }

            var 
aArgs = Array.prototype.slice.call(arguments1),
                    
fToBind this,
                    
fNOP = function () {},
                    
fBound = function () {
                        return 
fToBind.apply(this instanceof fNOP && oThis this oThis,
                                                                 
aArgs.concat(Array.prototype.slice.call(arguments)));
                    };

            
fNOP.prototype this.prototype;
            
fBound.prototype = new fNOP();

            return 
fBound;
        };
    }
})();

// IE8/9 CORS cross-domain requests compatibility
// https://github.com/jaubourg/ajaxHooks/blob/master/src/ajax/xdr.js
(function( jQuery ) {

if ( 
window.XDomainRequest ) {
    
jQuery.ajaxTransport(function( ) {
        if ( 
s.crossDomain && s.async ) {
            if ( 
s.timeout ) {
                
s.xdrTimeout s.timeout;
                
delete s.timeout;
            }
            var 
xdr;
            return {
                
send: function( _complete ) {
                    function 
callbackstatusstatusTextresponsesresponseHeaders ) {
                        
xdr.onload xdr.onerror xdr.ontimeout jQuery.noop;
                        
xdr undefined;
                        
completestatusstatusTextresponsesresponseHeaders );
                    }
                    
xdr = new XDomainRequest();
                    
xdr.opens.types.url );
                    
xdr.onload = function() {
                        
callback200"OK", { textxdr.responseText }, "Content-Type: " xdr.contentType );
                    };
                    
xdr.onerror = function() {
                        
callback404"Not Found" );
                    };
                    if ( 
s.xdrTimeout ) {
                        
xdr.ontimeout = function() {
                            
callback0"timeout" );
                        };
                        
xdr.timeout s.xdrTimeout;
                    }
                    
xdr.send( ( s.hasContent && s.data ) || null );
                },
                
abort: function() {
                    if ( 
xdr ) {
                        
xdr.onerror jQuery.noop();
                        
xdr.abort();
                    }
                }
            };
        }
    });
}
})( 
jQuery );
?>
Онлайн: 0
Реклама