├── .gitignore ├── lastfm_19.png ├── images ├── ban.png ├── ban_2.png ├── buy.png ├── info.png ├── lfm.png ├── love.png ├── next.png ├── pause.png ├── play.png ├── plus.png ├── skip.png ├── stop.png ├── delete.png ├── header.png ├── lfm_big.gif ├── lfm_off.png ├── next_2.png ├── normal.png ├── shuffle.png ├── skip_2.png ├── stop_bw.png ├── volume.png ├── lfm_small.png ├── no_image.png ├── no_repeat.png ├── plus_blue.png ├── previous.png ├── repeat_all.png ├── repeat_bw.png ├── repeat_one.png ├── shuffle_bw.png ├── volume_2.png ├── volume_bg.gif ├── folder_music.png ├── lfm_small_bw.png └── skip_forward.png ├── lastfm_128.png ├── .dropbox ├── external_search.png ├── _locales ├── en │ └── messages.json └── ru │ └── messages.json ├── css ├── smoothness │ ├── images │ │ ├── ui-anim_basic_16x16.gif │ │ ├── ui-icons_222222_256x240.png │ │ ├── ui-icons_2e83ff_256x240.png │ │ ├── ui-icons_454545_256x240.png │ │ ├── ui-icons_888888_256x240.png │ │ ├── ui-icons_cd0a0a_256x240.png │ │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ │ ├── ui-bg_flat_75_ffffff_40x100.png │ │ ├── ui-bg_glass_55_fbf9ee_1x400.png │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ ├── ui-bg_glass_75_dadada_1x400.png │ │ ├── ui-bg_glass_75_e6e6e6_1x400.png │ │ ├── ui-bg_glass_95_fef1ec_1x400.png │ │ └── ui-bg_highlight-soft_75_cccccc_1x100.png │ └── jquery-ui.css ├── mp3_player_button.css ├── style.css └── popup.css ├── README.rst ├── javascript ├── add_to_any.js ├── lastfm_auth_callback.js ├── ga.js ├── ga_popup.js ├── hotkeys.js ├── cache.js ├── utils.js ├── popup_footer.js ├── browser_detect.js ├── options.js ├── banner.js ├── xml2json.js ├── content_scripts │ └── content_script.js ├── background.js ├── md5.js ├── vk.js ├── scrobbler.js ├── music_manager.js ├── jquery-ui.min.js └── popup.js ├── CHANGELOG.rst ├── background.html ├── manifest.json ├── popup.html └── options.html /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | 3 | *.swk 4 | *.swj 5 | -------------------------------------------------------------------------------- /lastfm_19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/lastfm_19.png -------------------------------------------------------------------------------- /images/ban.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/ban.png -------------------------------------------------------------------------------- /images/ban_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/ban_2.png -------------------------------------------------------------------------------- /images/buy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/buy.png -------------------------------------------------------------------------------- /images/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/info.png -------------------------------------------------------------------------------- /images/lfm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/lfm.png -------------------------------------------------------------------------------- /images/love.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/love.png -------------------------------------------------------------------------------- /images/next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/next.png -------------------------------------------------------------------------------- /images/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/pause.png -------------------------------------------------------------------------------- /images/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/play.png -------------------------------------------------------------------------------- /images/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/plus.png -------------------------------------------------------------------------------- /images/skip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/skip.png -------------------------------------------------------------------------------- /images/stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/stop.png -------------------------------------------------------------------------------- /lastfm_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/lastfm_128.png -------------------------------------------------------------------------------- /.dropbox: -------------------------------------------------------------------------------- 1 | (dp1 2 | Vtag 3 | p2 4 | S'shared' 5 | p3 6 | sVns 7 | p4 8 | I26553061 9 | s. -------------------------------------------------------------------------------- /images/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/delete.png -------------------------------------------------------------------------------- /images/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/header.png -------------------------------------------------------------------------------- /images/lfm_big.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/lfm_big.gif -------------------------------------------------------------------------------- /images/lfm_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/lfm_off.png -------------------------------------------------------------------------------- /images/next_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/next_2.png -------------------------------------------------------------------------------- /images/normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/normal.png -------------------------------------------------------------------------------- /images/shuffle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/shuffle.png -------------------------------------------------------------------------------- /images/skip_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/skip_2.png -------------------------------------------------------------------------------- /images/stop_bw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/stop_bw.png -------------------------------------------------------------------------------- /images/volume.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/volume.png -------------------------------------------------------------------------------- /external_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/external_search.png -------------------------------------------------------------------------------- /images/lfm_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/lfm_small.png -------------------------------------------------------------------------------- /images/no_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/no_image.png -------------------------------------------------------------------------------- /images/no_repeat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/no_repeat.png -------------------------------------------------------------------------------- /images/plus_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/plus_blue.png -------------------------------------------------------------------------------- /images/previous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/previous.png -------------------------------------------------------------------------------- /images/repeat_all.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/repeat_all.png -------------------------------------------------------------------------------- /images/repeat_bw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/repeat_bw.png -------------------------------------------------------------------------------- /images/repeat_one.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/repeat_one.png -------------------------------------------------------------------------------- /images/shuffle_bw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/shuffle_bw.png -------------------------------------------------------------------------------- /images/volume_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/volume_2.png -------------------------------------------------------------------------------- /images/volume_bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/volume_bg.gif -------------------------------------------------------------------------------- /images/folder_music.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/folder_music.png -------------------------------------------------------------------------------- /images/lfm_small_bw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/lfm_small_bw.png -------------------------------------------------------------------------------- /images/skip_forward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/images/skip_forward.png -------------------------------------------------------------------------------- /_locales/en/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "repeat": { 3 | "descrition": "Repeat button", 4 | "message": "repeat" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /css/smoothness/images/ui-anim_basic_16x16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/css/smoothness/images/ui-anim_basic_16x16.gif -------------------------------------------------------------------------------- /css/smoothness/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/css/smoothness/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/css/smoothness/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/css/smoothness/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-icons_888888_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/css/smoothness/images/ui-icons_888888_256x240.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-icons_cd0a0a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/css/smoothness/images/ui-icons_cd0a0a_256x240.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_glass_75_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/chromus/master/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | This repo is not maintained 2 | ====== 3 | 4 | Last.fm free music player 5 | ========================= 6 | 7 | Yes it plays music! Browser as a music player? Why not? Free music player for Google Chrome with Last.fm integration. 8 | -------------------------------------------------------------------------------- /javascript/add_to_any.js: -------------------------------------------------------------------------------- 1 | var a2a_config = a2a_config || {}; 2 | a2a_config.linkname = "Last.fm free music player"; 3 | a2a_config.linkurl = "http://chrome-music.tumblr.com" 4 | a2a_config.static_server = "https://static.addtoany.com/menu" -------------------------------------------------------------------------------- /CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | Changelog 2 | ================================= 3 | 4 | Version 2.9.7 5 | --------------------------------- 6 | 7 | - Remember playlist controls 8 | - Fixes shutdown sometimes 9 | - Replace deprecated calls 10 | - Faster vk.com user login detection 11 | - Some fixes makekup on lastfm and extension 12 | -------------------------------------------------------------------------------- /javascript/lastfm_auth_callback.js: -------------------------------------------------------------------------------- 1 | if(match = window.location.toString().match(/token=(.*)/)){ 2 | console.warn('asdasd'); 3 | 4 | var port = chrome.extension.connect({name: "auth_callback"}) 5 | 6 | document.forms.web.text.style.display = 'none' 7 | 8 | port.postMessage({method:'auth_token', token: match[1]}) 9 | } 10 | 11 | -------------------------------------------------------------------------------- /_locales/ru/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugin_name": { 3 | "message": "\u0411\u0435\u0441\u043F\u043B\u0430\u0442\u043D\u044B\u0439 \u043C\u0443\u0437\u044B\u043A\u0430\u043B\u044C\u043D\u044B\u0439 \u043F\u043B\u0435\u0435\u0440 \u0434\u043B\u044F Last.fm" 4 | }, 5 | "repeat": { 6 | "description": "\u041A\u043D\u043E\u043F\u043A\u0430 \u0440\u0435\u043F\u0438\u0442\u0430", 7 | "message": "\u043F\u043E\u0432\u0442\u043E\u0440\u044F\u0442\u044C" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /javascript/ga.js: -------------------------------------------------------------------------------- 1 | 2 | var _gaq = _gaq || []; 3 | _gaq.push(['_setAccount', 'UA-17915703-4']); 4 | _gaq.push(['_trackPageview']); 5 | _gaq.push(['_trackEvent', 'pageLoad', 'background', '2.8.20']); 6 | 7 | if(BrowserDetect.OS != 'Mac' && BrowserDetect.OS != 'Linux'){ 8 | (function() { 9 | var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; 10 | ga.src = 'https://ssl.google-analytics.com/ga.js'; 11 | (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga); 12 | })(); 13 | } -------------------------------------------------------------------------------- /javascript/ga_popup.js: -------------------------------------------------------------------------------- 1 | var _gaq = _gaq || []; 2 | _gaq.push(['_setAccount', 'UA-17915703-4']); 3 | _gaq.push(['_trackPageview']); 4 | _gaq.push(['_trackEvent', 'pageLoad', 'popup']); 5 | 6 | if(BrowserDetect.OS != 'Mac' && BrowserDetect.OS != 'Linux'){ 7 | (function() { 8 | var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; 9 | ga.src = 'https://ssl.google-analytics.com/ga.js'; 10 | (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga); 11 | })(); 12 | } -------------------------------------------------------------------------------- /javascript/hotkeys.js: -------------------------------------------------------------------------------- 1 | if (!window.hotkey_initialized) { 2 | 3 | $(document).bind('keydown', function(evt) { 4 | if (evt.altKey) { 5 | switch(evt.keyCode) { 6 | case 221: //] 7 | chrome.extension.sendMessage({ method:'nextTrack' }); 8 | break; 9 | 10 | case 219: //[ 11 | chrome.extension.sendMessage({ method:'previousTrack' }); 12 | break; 13 | 14 | case 80: //P 15 | chrome.extension.sendMessage({ method:'toggle' }); 16 | break; 17 | } 18 | } 19 | }, false); 20 | 21 | window.hotkey_initialized = true; 22 | } 23 | -------------------------------------------------------------------------------- /background.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /javascript/cache.js: -------------------------------------------------------------------------------- 1 | CACHE = { 2 | data:{} 3 | } 4 | 5 | CACHE.set = function(key, value, expire_in_seconds){ 6 | if(value == undefined && CACHE.data[key]){ 7 | delete CACHE.data[key] 8 | } else { 9 | CACHE.data[key] = { 10 | value: value, 11 | expire: expire_in_seconds, 12 | created: (new Date().getTime()) 13 | } 14 | } 15 | } 16 | 17 | CACHE.unset = function(key){ 18 | CACHE.set(key) 19 | } 20 | 21 | CACHE.get = function(key) { 22 | var data = CACHE.data[key] 23 | 24 | if(data) 25 | return data['value'] 26 | } 27 | 28 | CACHE.gc = function(){ 29 | var time = new Date().getTime() 30 | var gc_objects = 0 31 | 32 | for(key in CACHE.data){ 33 | if(CACHE.data[key]['expire'] && (time-CACHE.data[key]['created']) > CACHE.data[key]['expire']){ 34 | delete CACHE.data[key] 35 | gc_objects += 1 36 | } 37 | } 38 | 39 | if(gc_objects) 40 | console.log("GC objects collected:", gc_objects) 41 | 42 | setTimeout(CACHE.gc, 100*1000) 43 | } 44 | 45 | CACHE.gc() -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 2, 3 | "name": "Last.fm free music player", 4 | "version": "2.9.700", 5 | "description": "!! Yes it plays music! Browser as a music player? Why not? Free music player for Google Chrome with Last.fm integration.", 6 | "icons": { 7 | "128": "lastfm_128.png" 8 | }, 9 | "default_locale": "en", 10 | "browser_action": { 11 | "default_icon": "lastfm_128.png", 12 | "default_title": "Last.fm free music player", 13 | "default_popup": "popup.html" 14 | }, 15 | "content_scripts": [ { 16 | "css": [ "css/mp3_player_button.css", "css/style.css" ], 17 | "js": [ "javascript/content_scripts/manager.js", "javascript/content_scripts/content_script.js" ], 18 | "matches": [ "http://*.last.fm/*", "http://*.lastfm.ru/*","http://*.lastfm.pt/*", "http://*.lastfm.de/*", "http://*.lastfm.es/*", "http://*.lastfm.fr/*", "http://*.lastfm.it/*", "http://*.lastfm.jp/*", "http://*.lastfm.pl/*", "http://*.lastfm.com.br/*", "http://*.lastfm.se/*", "http://*.lastfm.com.tr/*"] 19 | }, 20 | { 21 | "js": ["javascript/lastfm_auth_callback.js"], 22 | "matches": ["http://ya.ru/white*"] 23 | }, 24 | { 25 | "js": ["javascript/jquery.min.js", "javascript/hotkeys.js"], 26 | "matches": ["http://*/*", "https://*/*"] 27 | } 28 | ], 29 | "background": { 30 | "page":"background.html" 31 | }, 32 | "options_page": "options.html", 33 | "permissions": ["notifications", "tabs", "http://*/", "https://*/"], 34 | "content_security_policy": "script-src 'self' https://ssl.google-analytics.com/ga.js https://www.google.com/buzz/api/button.js https://static.addtoany.com/menu/page.js https://gumroad.com/js/gumroad-button.js https://gumroad.com/js/gumroad-button.js; object-src 'self'; " 35 | } 36 | -------------------------------------------------------------------------------- /javascript/utils.js: -------------------------------------------------------------------------------- 1 | function findParent(element, className){ 2 | var parentNode = element.parentNode 3 | 4 | if(parentNode.className && parentNode.className.match(className)) 5 | return parentNode 6 | else 7 | return findParent(parentNode, className) 8 | } 9 | 10 | function xhrRequest(url, method, data, callback){ 11 | var xhr = new XMLHttpRequest() 12 | 13 | //console.debug('Sending request:', url+'?'+data) 14 | 15 | if(method == "POST"){ 16 | xhr.open(method, url, true) 17 | xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded") 18 | xhr.send(data) 19 | } else { 20 | if(url.match(/\?/)) 21 | xhr.open(method, url+'&'+data, true) 22 | else 23 | xhr.open(method, url+'?'+data, true) 24 | 25 | xhr.send() 26 | } 27 | 28 | xhr.onreadystatechange = function(){ 29 | if(xhr.readyState == 4){ 30 | console.log("Response on "+url+" :", xhr) 31 | // console.log("Response text:", xhr.responseText) 32 | callback(xhr) 33 | } 34 | } 35 | } 36 | 37 | function xhrRedirectUrl(url, callback){ 38 | console.log("ASDASDASD") 39 | 40 | var xhr = new XMLHttpRequest() 41 | xhr.open("GET", url, true) 42 | xhr.send() 43 | 44 | console.log("Sending redirect response:", url) 45 | 46 | xhr.onreadystatechange = function(){ 47 | console.log("Redirect response:", xhr) 48 | } 49 | } 50 | 51 | function prettyTime(seconds){ 52 | seconds = parseInt(seconds) 53 | 54 | var minutes = parseInt(seconds/60) 55 | 56 | var seconds = seconds % 60 57 | if(seconds < 10) 58 | seconds = "0"+seconds 59 | 60 | if(minutes < 10) 61 | minutes = " "+minutes 62 | 63 | return minutes + ":" + seconds 64 | } 65 | 66 | function timeToSeconds(time){ 67 | time = time.split(':') 68 | 69 | return parseInt(time[0])*60 + parseInt(time[1]) 70 | } 71 | 72 | String.prototype.replaceEntities = function(){ 73 | return this.replace(/&/g, '&').replace(/%27/g,"'") 74 | } 75 | 76 | Function.prototype.bind = function(scope) { 77 | var _function = this; 78 | 79 | return function() { 80 | return _function.apply(scope, arguments); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /javascript/popup_footer.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | $("#volume-slider").slider({ 3 | orientation: "vertical", 4 | range: "min", 5 | min: 0, 6 | max: 100, 7 | value: music_manager.getVolume()*100, 8 | slide: function(event, ui) { 9 | music_manager.setVolume(ui.value/100) 10 | } 11 | }); 12 | 13 | 14 | $('button#play_mode_control').click(function(){ 15 | $(this).toggleClass('disabled'); 16 | 17 | music_manager.play_mode = $(this).hasClass('disabled') ? "normal" : "shuffle"; 18 | window.localStorage['play_mode'] = music_manager.play_mode; 19 | 20 | _gaq.push(['_trackEvent', 'controls', 'playMode', music_manager.play_mode]); 21 | }); 22 | 23 | helpOnHover($('button#play_mode_control'), function(){ 24 | if ($(this).hasClass('disabled')) 25 | return "Shuffle mode disabled" 26 | else 27 | return "Shuffle mode enabled" 28 | }) 29 | 30 | $('button#stop_after_control').click(function(){ 31 | $(this).toggleClass('disabled'); 32 | 33 | music_manager.stop_after_playing = $(this).hasClass('disabled') ? "normal" : "stop"; 34 | window.localStorage['stop_after_playing'] = music_manager.stop_after_playing; 35 | 36 | _gaq.push(['_trackEvent', 'controls', 'playMode', music_manager.stop_after_playing]); 37 | }); 38 | 39 | helpOnHover($('button#stop_after_control'), function(){ 40 | if ($(this).hasClass('disabled')) 41 | return "Playing without stopping" 42 | else 43 | return "Stop after playing" 44 | }) 45 | 46 | 47 | 48 | $('button#repeat_mode_control').click(function(){ 49 | if ($(this).hasClass('all')){ 50 | $(this).removeClass('all').addClass('disabled'); 51 | music_manager.repeat_mode = "normal"; 52 | } else if ($(this).hasClass('disabled')){ 53 | $(this).removeClass('disabled all') 54 | music_manager.repeat_mode = "repeat_one"; 55 | } else { 56 | $(this).removeClass('disabled').addClass('all'); 57 | music_manager.repeat_mode = "repeat_all"; 58 | } 59 | 60 | window.localStorage['repeat_mode'] = music_manager.repeat_mode; 61 | _gaq.push(['_trackEvent', 'controls', 'repeatMode', music_manager.repeat_mode]); 62 | }); 63 | 64 | helpOnHover($('button#repeat_mode_control'), function(){ 65 | if($(this).hasClass('all')) 66 | return "Repeat playlist" 67 | else if($(this).hasClass('disabled')) 68 | return "Don't repeat" 69 | else 70 | return "Repeat track" 71 | }) 72 | 73 | 74 | $('button#toggle_scrobbling').click(function(){ 75 | $(this).toggleClass('disabled') 76 | 77 | music_manager.scrobbler.scrobbling = !$(this).hasClass('disabled') 78 | }) 79 | 80 | helpOnHover($('button#toggle_scrobbling'), function(){ 81 | if($(this).hasClass('disabled')) 82 | return "Scrobbling disabled" 83 | else 84 | return "Scrobbling enabled" 85 | }) 86 | }); 87 | 88 | 89 | if (document.addEventListener) 90 | document.addEventListener("DOMContentLoaded", function(){ onLoad(); }, false); -------------------------------------------------------------------------------- /javascript/browser_detect.js: -------------------------------------------------------------------------------- 1 | var BrowserDetect = { 2 | init: function () { 3 | this.browser = this.searchString(this.dataBrowser) || "An unknown browser"; 4 | this.version = this.searchVersion(navigator.userAgent) 5 | || this.searchVersion(navigator.appVersion) 6 | || "an unknown version"; 7 | this.OS = this.searchString(this.dataOS) || "an unknown OS"; 8 | }, 9 | searchString: function (data) { 10 | for (var i=0;i 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 |
21 | Album image 22 | Play 23 |
24 |
25 |
26 | 27 |
28 |  from 29 | 30 |
31 |
32 | 33 | Love! 34 | 37 | 38 |
39 |
40 |
41 |
42 | Volume 43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | 53 |
    54 |
55 | 56 |
57 | 62 |
63 |
64 | 67 | 68 | 69 | 70 | 71 |
72 | 73 | 74 | 75 |
76 |
77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /css/mp3_player_button.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | SoundManager 2: Basic MP3 player CSS 4 | ------------------------------------ 5 | 6 | Clicks on links to MP3s are intercepted via JS, calls are 7 | made to SoundManager to load/play sounds. CSS classes are 8 | appended to the link, which are used to highlight the 9 | current play state and so on. 10 | 11 | Class names are applied in addition to "sm2_button" base. 12 | 13 | Default: 14 | 15 | sm2_button 16 | 17 | Additional states: 18 | 19 | sm2_playing 20 | sm2_paused 21 | 22 | eg. 23 | 24 | 25 | some.mp3 26 | 27 | 28 | some.mp3 29 | 30 | 31 | Note you don't require ul.graphic / ul.flat etc. for your use 32 | if only using one style on a page. You can just use .sm2_button{} 33 | and so on, but isolate the CSS you want. 34 | 35 | Side note: Would do multiple class definitions eg. 36 | 37 | a.sm2_default.sm2_playing{} 38 | 39 | .. except IE 6 has a parsing bug which may break behaviour, 40 | applying sm2_playing {} even when the class is set to sm2_default. 41 | 42 | 43 | If you want to make your own UI from scratch, here is the base: 44 | 45 | Default + hover state, "click to play": 46 | 47 | a.sm2_button {} 48 | a.sm2_button:hover {} 49 | 50 | Playing + hover state, "click to pause": 51 | 52 | a.sm2_playing {} 53 | a.sm2_playing:hover {} 54 | 55 | Paused + hover state, "click to resume": 56 | 57 | a.sm2_paused {} 58 | a.sm2_paused:hover {} 59 | 60 | */ 61 | 62 | a.sm2_button { 63 | position:relative; 64 | display:inline-block; /* If you worry old browser bugs, Firefox 2 might not like this and may need -moz-inline-box instead. :D */ 65 | width:13px; 66 | height:13px; 67 | text-indent:-9999px; /* don't show link text */ 68 | overflow:hidden; /* don't draw inner link text */ 69 | vertical-align:middle; 70 | /* and, a bit of round-ness for the cool browsers. */ 71 | border-radius:13px; 72 | margin-top:-1px; /* vertical align tweak */ 73 | /* safari 3.1+ fun (/W3 working draft extension, TBD.) */ 74 | -webkit-transition-property: hover; 75 | -webkit-transition: background-color 0.15s ease-in-out; 76 | } 77 | 78 | a.sm2_button:focus { 79 | outline:none; /* maybe evil, but don't show the slight border outline on focus. */ 80 | } 81 | 82 | a.sm2_button, 83 | a.sm2_button.paused:hover { 84 | background-color:#3399cc; 85 | /* where possible, use data: and skip the HTTP request. Fancy-pants. Would use short-hand background: for above, but IE 8 doesn't override background-image. */ 86 | background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAKCAYAAABmBXS+AAAAbklEQVQY02NgQAL//v1jZMAF/v//vwuIs9HEUBUBTbj4HwIeA3EGVsVAxtn/qOAVUGM8uknIiv4hsV8A5ZKxKfoLVvnvHwifAzLtMKwDSQLBVSBti27dJajkcSD2RJODO3wtkOOMz/tMSJJYAxMA5dmsL0IfubQAAAAASUVORK5CYII=); 87 | 88 | 89 | background-repeat:no-repeat; 90 | background-position:3px 50%; 91 | background-size: 55%; 92 | } 93 | 94 | a.sm2_button.loading { 95 | background-image:url(data:image/gif;base64,R0lGODlhEAAQAPIAADOZzP///2Kw18nj8f///6/X6pbK5InD4SH+GkNyZWF0ZWQgd2l0aCBhamF4bG9hZC5pbmZvACH5BAAKAAAAIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQACgABACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkEAAoAAgAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkEAAoAAwAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkEAAoABAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQACgAFACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQACgAGACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAAKAAcALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA%3D%3D); 96 | background-size: 100%; 97 | background-position:0px; 98 | } 99 | 100 | a.sm2_button:hover, 101 | a.sm2_button.playing, 102 | a.sm2_button.playing:hover { 103 | background-color:#cc3333; 104 | } 105 | 106 | a.sm2_button.paused, 107 | a.sm2_button.paused:hover { 108 | background-color:#666; 109 | } 110 | 111 | a.sm2_button.disabled, 112 | a.sm2_button.disabled:hover { 113 | background-color:#ccc; 114 | } 115 | 116 | a.sm2_button.playing { 117 | background-image:url(data:image/gif;base64,R0lGODlhEAAQAIAAAP///////yH+EUNyZWF0ZWQgd2l0aCBHSU1QACH5BAEKAAEALAAAAAAQABAAAAIkjI+pu+DogIrwJXpwldnuf3mB1nEGeYroqIqpycIvSMfMjTMFADs%3D); 118 | } 119 | 120 | -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | table.candyStriped.chart td.multibuttonCell, table.candyStriped.chart td.multibuttonCell { 2 | width: 50px; 3 | } 4 | 5 | table.candyStriped.chart .vk_search_button, 6 | table.candyStriped.chart .sm2.button { 7 | vertical-align:middle; 8 | display: inline-block; 9 | } 10 | 11 | table.mediumImageChart .vk_search_button, 12 | #friendsLoved .vk_search_button, 13 | #friendsLoved .sm2_button, 14 | #nowPlaying .vk_search_button, 15 | #nowPlaying .sm2_button, 16 | table.mediumImageChart .sm2_button, 17 | ul.artistsWithInfo .vk_search_button, 18 | ul.artistsWithInfo .sm2_button { 19 | vertical-align:middle; 20 | display: inline-block; 21 | margin-right: 5px; 22 | } 23 | 24 | #nowPlaying .sm2_button, 25 | ul.artistsWithInfo .sm2_button, 26 | ul.artistsWithInfo .vk_search_button { 27 | margin-right: 0px; 28 | } 29 | 30 | ul.mediumChartWithImages .vk_search_button, ul.mediumChartWithImages .sm2_button { 31 | vertical-align:middle; 32 | display: inline; 33 | margin-right: 5px; 34 | padding-left: 0px; 35 | } 36 | 37 | td.playbuttonCell a.sm2_button { 38 | margin: 1px 3px 0 4px; 39 | } 40 | 41 | a.vk_search_button { 42 | position:relative; 43 | display:inline-block; /* If you worry old browser bugs, Firefox 2 might not like this and may need -moz-inline-box instead. :D */ 44 | width:16px; 45 | height:14px; 46 | text-indent:-9999px; /* don't show link text */ 47 | overflow:hidden; /* don't draw inner link text */ 48 | vertical-align:middle; 49 | margin-top:-1px; /* vertical align tweak */ 50 | /* safari 3.1+ fun (/W3 working draft extension, TBD.) */ 51 | -webkit-transition-property: hover; 52 | -webkit-transition: background-color 0.15s ease-in-out; 53 | 54 | background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABIAAAASABGyWs+AAACwklEQVQ4y32T20sUYRjGn2/mm9POtoepNNzKcDXMA4XrAbS9ECq6iOwPMLQU+hP6H7wIiqSLkKALrW4CDQzsxkSEVlcSXRfMw8XYuptou7rMzuzMfF2k5akeeHgvHvjxvg+8BHt6+fwplpeX5Su19ZWKqpZYZmF7ZWlpqfN+526kpRXb2SxOEnevowOMMfCK2tB2++6rYFXdRxoKvz9VUTMaab/1bvLLzI2dbJY86Oo6EUBGR0exrutNocs1rx1PoNolHBgAlwE8GMRCbiP1bfFRd3f3cGtrK6ampg4BeImDpzna/sRbej5aqvnh98jwKtKfyUmKl4JVDbzoHw5XVeUnJiYOAWhDU3O9JxC8fk7zQxYFOC4DA4NpO7AdF7IggGmn6y+FK5sDgcDI0ROoIEohURR9DgNcxsAA5M0idgsWHJeB5ziIkiypXu+FinD4WAc0l8tlieuYluPKlmECABgDFFEAASDyHHaNrLu7k8vqun4csLAwP1939VqytCzUwvEUbL9dMFACEMagb2b01dW16VRq4xiAj01P5z+MjBia33ez5OwZSRUFSDwHWeBBCbC2soy3Q4Nbn8fHh9fX178Hg0Gk0+m/gLm5OXwaG1sMBgI/XMeu5Qn8jl0kP7e3WDKxmHkzNGgmEokySmmjbdsxVVU3fD4fMpnM3qYAqqurkUwmSW9PT+XF8vKooigh0zQ3dV2fjMfjlYqiPKOUhmzbjluW1SvL8mw6nUYikfgN+JcikQhmZmbQ1tbWIUlSP6U0VCwW44VCodfj8czquv5/AAA0NjYiFoshGo12KIrSLwhCyLKsuGEYD3me/7oPIAB4AMIBUwDcXu4CKEYikTuapvWJoliaz+cfa5rWx+8/FQAJgALAA8B7wOpeJqZSqSW/37/IcdyqYRgDqqrmjp5ATvC+GACXEOJyHEcAMMdx8As6nhlfAosvgwAAACJ6VFh0U29mdHdhcmUAAHjaKy8v18vMyy5OTixI1csvSgcANtgGWBBTylwAAAAASUVORK5CYII%3D); 55 | background-repeat:no-repeat; 56 | background-position:0px 50%; 57 | background-size: 90%; 58 | } 59 | 60 | table.tracklist .smallmultibuttonCell { 61 | width: 50px !important; 62 | } 63 | 64 | 65 | div.ex_overload_window { 66 | position: fixed; 67 | top: 30%; 68 | left: 50%; 69 | width: 500px; 70 | height: 200px; 71 | margin-left: -250px; 72 | background: #fff; 73 | z-index: 999; 74 | 75 | opacity: 1; 76 | -webkit-transition: opacity 2s ease-out; 77 | } 78 | 79 | div.ex_overload_window h3.ex_header { 80 | background-position: 10px 3px; 81 | background-repeat: no-repeat; 82 | background-size: 8%; 83 | 84 | font-size: 22px; 85 | 86 | padding-left: 60px; 87 | padding-top: 10px; 88 | padding-bottom: 10px; 89 | 90 | cursor: default; 91 | } 92 | 93 | div.ex_overload_window p.ex_title { 94 | text-align: center; 95 | font-size: 24px; 96 | font-weight: bold; 97 | color: #333; 98 | padding-top: 0px; 99 | margin-top: 0px; 100 | } 101 | 102 | ul.artistsLarge li a.sm2_button { 103 | position: absolute; 104 | top: 81px; 105 | left: 105px; 106 | } 107 | 108 | ul.artistRecs a.sm2_button { 109 | position: absolute; 110 | left: 45px; 111 | top: 34px; 112 | } 113 | ul.artistRecs span.playButton { 114 | display: none; 115 | } 116 | 117 | .ex_artist a.sm2_button { background-color:#ccc; } 118 | .ex_album a.sm2_button { background-color:#ccc; } 119 | 120 | ul.artistsWithInfo a.sm2_button { 121 | position: absolute; 122 | left: 105px; 123 | top: 80px; 124 | } 125 | 126 | ul.albumsMedium a.sm2_button { 127 | position: absolute; 128 | left: 54px; 129 | top:47px; 130 | } 131 | 132 | ul.albumsLarge a.sm2_button { 133 | position: absolute; 134 | left: 115px; 135 | top: 105px; 136 | } 137 | 138 | #albumstrip li a.sm2_button { 139 | height: 13px !important; 140 | width: 13px !important; 141 | display: inline-block !important; 142 | padding: 0px !important; 143 | 144 | position: absolute; 145 | right: 10px; 146 | bottom: 5px; 147 | 148 | z-index: 1; 149 | } 150 | 151 | ul.recentAlbums li a.sm2_button, #newReleases .release a.sm2_button { 152 | left: 50px; 153 | top: 47px; 154 | z-index: 2; 155 | position: absolute; 156 | } 157 | -------------------------------------------------------------------------------- /javascript/banner.js: -------------------------------------------------------------------------------- 1 | (function(window){ 2 | var bannerManager = { 3 | country: "EN", 4 | banners: [], 5 | flashInstalled: false 6 | } 7 | 8 | bannerManager.detectFlash = function() { 9 | if (navigator.plugins && navigator.plugins.length && navigator.plugins["Shockwave Flash"] || 10 | navigator.mimeTypes && navigator.mimeTypes.length && navigator.mimeTypes['application/x-shockwave-flash']) { 11 | 12 | bannerManager.flashInstalled = true; 13 | } 14 | } 15 | bannerManager.detectFlash(); 16 | 17 | bannerManager.guessCountry = function() { 18 | var head = window.document.getElementsByTagName("head")[0]; 19 | var script = document.createElement('script'); 20 | script.type = 'text/javascript'; 21 | script.src = 'http://j.maxmind.com/app/geoip.js'; 22 | 23 | script.onload = function() { 24 | if (typeof(window.geoip_country_code) == "function") { 25 | bannerManager.country = geoip_country_code(); 26 | bannerManager.city = geoip_city(); 27 | } else { 28 | setTimeout(bannerManager.guessCountry, 1000); 29 | } 30 | } 31 | 32 | head.appendChild(script); 33 | } 34 | 35 | window.document.addEventListener('DOMContentLoaded', function(){ 36 | bannerManager.guessCountry(); 37 | }, false); 38 | 39 | bannerManager.addBanner = function(banner) { 40 | this.banners.push(banner); 41 | } 42 | 43 | bannerManager.getBanner = function() { 44 | var banners = this.banners.filter(function(banner) { 45 | if (banner.country) { 46 | if (banner.country.indexOf("-"+bannerManager.country) === -1 && 47 | (banner.country.indexOf('*') !== -1 || banner.country.indexOf(bannerManager.country) !== -1)) 48 | return true; 49 | } else if (banner.lang) { 50 | if (banner.lang === window.navigator.language) { 51 | return true; 52 | } 53 | } 54 | }); 55 | 56 | if (banners.length > 0) { 57 | var banner = banners[Math.floor(Math.random()*banners.length)]; 58 | 59 | return banner.flash && bannerManager.flashInstalled ? banner.flash : banner.html; 60 | } 61 | } 62 | 63 | window.bannerManager = bannerManager; 64 | }(window)) 65 | 66 | /* 67 | // Fotocash 68 | bannerManager.addBanner({ 69 | country: ["RU","UA"], 70 | flash: '', 71 | 72 | html: 'Заведи прикольного питомца онлайн !' 73 | }); 74 | 75 | // sendflowers.ru 76 | bannerManager.addBanner({ 77 | country: ["RU", "UA"], 78 | 79 | html: 'var rand_nm = Math.round(Math.random() * 1000000); document.write(\' 6 | 7 | 8 | 142 | 143 | 144 | http://chrome-music.tumblr.com 145 | hello@chromusapp.com 146 |
147 | 148 | Like it? Rate us with five stars! 149 |
150 |
151 | 152 | Follow chrome_music on Twitter 153 |
154 |
155 |
156 | 157 |
158 |
159 | 160 | 161 |
162 |
163 | 164 |
165 | 166 | Share/Bookmark 167 | 169 | 170 | 171 |
172 | 173 |  Группа ВКонтакте 174 |
175 | 176 |
177 |
178 |

Last.fm free music player settings

179 |
180 | 182 | 184 | 185 |
186 |

Hotkeys

187 | Alt + ]  – Next track
188 | Alt + pToggle playing
189 | * not working on this and some https pages 190 |
191 |
192 |
193 |
194 | 195 | 196 |
197 |
198 | 199 | 200 |
201 |
202 |
NEW VERSION!
203 | We anouncing new version of player! 204 | http://chromus.github.com/chromus 205 |
We still in BETA! Help us to make it awesome!
206 |
Contacts & Questions: hello@chromusapp.com
207 |
208 |
209 |

Latest Changes

210 |
    211 |
  • 212 | 7 Aug 2012: Updated for new Last.fm 213 |
  • 214 |
  • 21 May 2012: Fixed Chrome 19 bug
  • 215 |
  • 11 Mar 2012: Fixed Charts playing
  • 216 |
217 |
218 |
219 |

Your support keeps us on the air!

220 |
221 |
222 | Last.fm free music player donation 223 |
224 | 225 |

Your support of any amount helps us stay on the air, providing free music that can't be found anywhere else. You can donate as little as $2.99 or as much as you'd like. Donating $10-$20 really, really helps us! We accept all major credit cards as well as PayPal. 226 |

227 | 228 |
Other payment methods:
229 |
Yandex.Money 41001903998889
230 |
231 |

Thank you!

232 |
233 |
234 |
 
235 | 236 |
237 | 238 | 239 | 240 | -------------------------------------------------------------------------------- /javascript/vk.js: -------------------------------------------------------------------------------- 1 | var _gaq = _gaq || []; 2 | 3 | /** 4 | VK 5 | 6 | Module for working with vk.com 7 | **/ 8 | var VK = { 9 | determineSearchMethod: function (callback) { 10 | console.log("Trying to determine search method"); 11 | 12 | var xhr = new XMLHttpRequest(); 13 | 14 | 15 | xhr.open('GET', 'https://vk.com/feed', true); 16 | //xhr.setRequestHeader('Accept', "text/html"); 17 | xhr.send(); 18 | 19 | xhr.onreadystatechange = function () { 20 | if (xhr.readyState == xhr.DONE) { 21 | // var redirect = xhr.getResponseHeader('TM-finalUrl') || ''; 22 | 23 | if ( xhr.responseText.indexOf( 'action="https://login.vk.com/"' ) == -1) { 24 | callback({search_method: 'vk.com'}); 25 | } else { 26 | callback({search_method: 'fail_mode'}); 27 | //callback({search_method: 'test_mode'}); 28 | } 29 | } 30 | }; 31 | }, 32 | 33 | /** 34 | VK.#_rawSearch(artist, song, callback) 35 | 36 | Searching by parsing page. Callback function must return hash with url. 37 | **/ 38 | _rawSearch: function(artist, song, duration, callback){ 39 | var track = artist + " " + song; 40 | 41 | var url = "https://"+VK.search_method+"/al_search.php"; 42 | var data = "c%5Bq%5D="+encodeURIComponent(track)+"&al=1&c%5Bsection%5D=audio&c%5Bsort%5D=2"; 43 | 44 | xhrRequest(url, "POST", data, function(xhr){ 45 | 46 | // User logged off from vkontakte 47 | if(xhr.responseText.match(/progress\.gif/)){ 48 | delete VK.search_method; 49 | 50 | VK.search(artist, song, duration, callback); 51 | 52 | return; 53 | } 54 | 55 | var container = document.getElementById('vk_search'); 56 | response = xhr.responseText.replace(/^'); 57 | 58 | container.innerHTML = response.split('').join(''); 59 | 60 | var audio_data = []; 61 | var audio_rows = container.querySelectorAll('div.audio'); 62 | 63 | for(var i=0; i10) break; 65 | 66 | var url_data = audio_rows[i].querySelector('input[type=hidden]').value.split(','); 67 | var url = url_data[0]; 68 | var duration = url_data[1]; 69 | 70 | var title = audio_rows[i].querySelector('td.info span'); 71 | 72 | audio_data.push({ 73 | artist: audio_rows[i].querySelector('td.info a').innerHTML, 74 | title: title.textContent.trim(), 75 | duration: duration, 76 | url: url 77 | }); 78 | } 79 | 80 | console.log("Tracks:", audio_data); 81 | 82 | if(audio_data.length > 0){ 83 | 84 | audio_data.lastIndex = 0; 85 | 86 | for(var i=0;i 0){ 205 | //vk_track.duration = parseInt(vk_track.duration) 206 | 207 | //Caching for 3 hours 208 | CACHE.set(track, vk_tracks, 1000*60*60*3); 209 | 210 | callback(vk_tracks); 211 | } else { 212 | callback({error:'not_found'}); 213 | } 214 | } else { 215 | if(results.error) 216 | callback({error:results.error}); 217 | else{ 218 | console.error("ERROR!:", results); 219 | callback({error:'Unknown error while searching track'}); 220 | } 221 | } 222 | }); 223 | }, 224 | 225 | 226 | /** 227 | VK#search(artist, song, callback) 228 | - artist (String): Artist 229 | - song (String): Song 230 | - callback (Function): Function to be called when search compete, to obtain results. 231 | **/ 232 | search: function(artist, song, duration, callback){ 233 | console.log("Seaching:", artist, " - ", song) 234 | console.log("Search method:", this.search_method) 235 | 236 | if(this.search_method == undefined){ 237 | this.determineSearchMethod(function(response){ 238 | console.log("Search method:", response.search_method) 239 | 240 | VK.search_method = response.search_method 241 | 242 | VK.search(artist, song, duration, callback) 243 | }) 244 | 245 | return 246 | } 247 | 248 | artist = artist.toLowerCase() 249 | song = song.toLowerCase() 250 | 251 | if(duration != undefined) 252 | duration = parseInt(duration) 253 | 254 | var track = artist + " " + song 255 | 256 | if(CACHE.get(track)) 257 | return callback(CACHE.get(track)) 258 | 259 | _gaq.push(['_trackEvent', 'vkontakte_search', this.search_method, artist+'-'+song]); 260 | 261 | if (this.search_method == "fail_mode") { 262 | callback({error: 'cant_search'}); 263 | } else if (this.search_method == "test_mode") { 264 | this._testmodeSearch(artist, song, duration, callback); 265 | } else { 266 | this._rawSearch(artist, song, duration, callback); 267 | } 268 | 269 | 270 | console.log("Setting search method to null"); 271 | this.search_method = undefined; 272 | } 273 | } 274 | -------------------------------------------------------------------------------- /javascript/scrobbler.js: -------------------------------------------------------------------------------- 1 | var _gaq = _gaq || []; 2 | 3 | /** 4 | Class Scrobbler 5 | **/ 6 | var Scrobbler = function(session_key, username){ 7 | this._api_key = "170909e77e67705570080196aca5040b" 8 | this._secret = "516a97ba6f832d9184ae5b32c231a3af" 9 | this._session_key = session_key 10 | this._username = username 11 | this.scrobbling = true 12 | } 13 | 14 | /** 15 | Scrobbler#getSession(token, callback) 16 | **/ 17 | Scrobbler.prototype.getSession = function(token, callback){ 18 | if(!token) 19 | return false 20 | 21 | console.log("Getting session") 22 | 23 | var signature = MD5("api_key"+this._api_key+"methodauth.getSessiontoken"+token+this._secret) 24 | 25 | console.log("TRIAM!") 26 | 27 | xhrRequest("http://ws.audioscrobbler.com/2.0/", "GET", 28 | "method=auth.getSession&api_key="+this._api_key+"&api_sig="+signature+"&token="+token, 29 | function(xhr){ 30 | console.log("Session info:", xhr.responseText) 31 | 32 | if(xhr.responseText.match(/error/)) { 33 | if(callback) 34 | callback({error: xhr.responseText}) 35 | } else { 36 | this._session_key = xhr.responseText.match(/(.*)<\/key>/)[1] 37 | this._username = xhr.responseText.match(/(.*)<\/name>/)[1] 38 | 39 | if(callback) 40 | callback({username:this._username, session: this._session_key}) 41 | } 42 | }.bind(this) 43 | ) 44 | } 45 | 46 | /** 47 | Scrobbler#setNowPlaying(artist, track, duration, callback) 48 | **/ 49 | Scrobbler.prototype.setNowPlaying = function(artist, track, album, duration, callback){ 50 | if(!this.scrobbling) 51 | return false 52 | 53 | _gaq.push(['_trackEvent', 'lastfm', 'setNowPlaying', artist+'-'+track]); 54 | 55 | if(!this._username) 56 | return 57 | 58 | if(!callback) 59 | callback = function(){} 60 | 61 | this.callMethod("track.updateNowPlaying", 62 | {artist:artist, track:track, album:album, duration:duration, sig_call:true, http_method:'POST'}, callback) 63 | } 64 | 65 | 66 | /** 67 | Scrobbler#scrobble(artist, track, duration, callback) 68 | **/ 69 | Scrobbler.prototype.scrobble = function(artist, track, album, duration, callback){ 70 | if(!this.scrobbling) 71 | return false 72 | 73 | if(!this._username) 74 | return false 75 | 76 | _gaq.push(['_trackEvent', 'lastfm', 'scrobble', artist+'-'+track]); 77 | 78 | if(!callback) 79 | callback = function(){} 80 | 81 | var now = new Date() 82 | var timestamp = parseInt(now.getTime()/1000.0) 83 | 84 | this.callMethod("Track.scrobble", 85 | {artist:artist, track:track, album:album, duration:duration, timestamp: timestamp, sig_call:true, http_method:'POST'}, callback) 86 | } 87 | 88 | 89 | /** 90 | Scrobbler#auth() 91 | **/ 92 | Scrobbler.prototype.auth = function(){ 93 | chrome.tabs.create({url:"http://www.last.fm/api/auth/?api_key="+this._api_key}) 94 | } 95 | 96 | 97 | /** 98 | Scrobbler#preview_mp3(track_id, callback) 99 | **/ 100 | Scrobbler.prototype.previewURL = function(track_id){ 101 | return "http://ws.audioscrobbler.com/2.0/?method=track.previewmp3&trackid="+track_id+"&api_key="+this._api_key 102 | } 103 | 104 | 105 | /** 106 | Scrobbler#callMethod(method, params, callback) 107 | **/ 108 | Scrobbler.prototype.callMethod = function(method, params, callback){ 109 | _gaq.push(['_trackEvent', 'lastfm', method]); 110 | 111 | var http_method = 'GET' 112 | if(params['http_method']){ 113 | http_method = params['http_method'] 114 | delete params['http_method'] 115 | } 116 | 117 | params["method"] = method 118 | params["api_key"] = this._api_key 119 | params["format"] = 'json' 120 | 121 | for(key in params) 122 | if(params[key] != undefined && typeof(params[key]) == 'string') 123 | params[key] = params[key].replace(/&/g,'and') 124 | 125 | if(params['sig_call']){ 126 | delete params['sig_call'] 127 | delete params['format'] 128 | 129 | if(this._session_key){ 130 | params['sk'] = this._session_key 131 | 132 | var signature = [] 133 | for(key in params) 134 | if(params[key] != undefined) 135 | signature.push(key+params[key]) 136 | 137 | signature.sort() 138 | 139 | console.log("Sig string:", signature.join('')+this._secret) 140 | 141 | signature = MD5(signature.join('')+this._secret) 142 | 143 | params['api_sig'] = signature 144 | } 145 | } 146 | 147 | var query_string = [] 148 | for(key in params) 149 | if(params[key] != undefined) 150 | query_string.push(key+"="+encodeURIComponent(params[key])) 151 | 152 | query_string.sort() 153 | 154 | query_string = query_string.join('&') 155 | 156 | console.log("Calling method:", method) 157 | 158 | if(params['use_cache'] != false && CACHE.get(query_string)){ 159 | console.info("Using CACHE") 160 | 161 | callback(CACHE.get(query_string)) 162 | return 163 | } 164 | 165 | 166 | var server_url = "http://ws.audioscrobbler.com/2.0/" 167 | 168 | xhrRequest(server_url, http_method, query_string, function(xhr){ 169 | if(!xhr.responseXML){ 170 | try{ 171 | var response = JSON.parse(xhr.responseText) 172 | } catch(e) { 173 | var response = {error: 'Parsing error'} 174 | } 175 | } else { 176 | var response = xhr.responseXML 177 | } 178 | 179 | if(!xhr.responseXML && response.error || xhr.responseXML && xhr.responseText && xhr.status != 200){ 180 | console.error("Error:", xhr.responseText, query_string, xhr) 181 | } else { 182 | //By default caching without expiration (if params['expire_time'] is undefined) 183 | if(params['use_cache'] != false) 184 | CACHE.set(query_string, response, params['expire_time']) 185 | 186 | callback(response) 187 | } 188 | }) 189 | } 190 | 191 | 192 | /** 193 | Scrobbler#artistInfo(artist, callback) 194 | **/ 195 | Scrobbler.prototype.artistInfo = function(artist, callback){ 196 | this.callMethod("artist.getinfo", {artist: artist}, function(response){ 197 | callback({image: response.artist.image[1]["#text"].replace(/serve\/([^\/]*)/,'serve/64s')}) 198 | }) 199 | } 200 | 201 | Scrobbler.prototype.parseXSPFPlaylist = function(response){ 202 | console.log("Tracklist: ", response) 203 | 204 | var tracks = response.playlist.trackList.track 205 | var result_tracks = [] 206 | 207 | if(!(tracks instanceof Array)) 208 | tracks = [tracks] 209 | 210 | for(var i=0; i= track.duration || this.audio.ended){ 65 | console.log(this.audio.currentTime, track.duration, this.audio.ended, track, this.audio.src); 66 | 67 | this.onEnded() 68 | } 69 | 70 | var percent_played = (this.audio.currentTime / track.duration)*100 71 | 72 | if(this.audio.duration > 31 && percent_played > 50 && !track.scrobbled){ 73 | this.scrobbler.scrobble(track.artist, track.song, track.album, track.duration) 74 | track.scrobbled = true 75 | 76 | console.log("Track scrobbled", track) 77 | } 78 | 79 | if(this.audio.duration > 31 && percent_played > 90 && this.stop_after_playing != "stop" && !track.next_song_prefetched){ 80 | var next_track = this.playlist[this.current_track+1] 81 | 82 | track.next_song_prefetched = true 83 | 84 | if(next_track){ 85 | console.log("Prefetching next track") 86 | _gaq.push(['_trackEvent', 'music_manager', 'prefetchingTrack']); 87 | 88 | if(this.play_mode == "shuffle" && this.shuffle_tracks) 89 | this.searchTrack(this.shuffle_tracks[0], false) 90 | else 91 | this.searchTrack(this.current_track+1, false) 92 | } 93 | } 94 | } 95 | 96 | 97 | /** 98 | MusicManager#fireEvent(event_name) 99 | **/ 100 | MusicManager.prototype.fireEvent = function(event_name){ 101 | var evt = document.createEvent("Events") 102 | evt.initEvent(event_name, true, true) 103 | this.dispatcher.dispatchEvent(evt) 104 | } 105 | 106 | 107 | /** 108 | MusicManager#onStartPlaying() 109 | **/ 110 | MusicManager.prototype.onStartPlaying = function(){ 111 | var track = this.playlist[this.current_track] 112 | 113 | console.log("Album:", track.album) 114 | 115 | this.scrobbler.setNowPlaying(track.artist, track.song, track.album, track.duration) 116 | 117 | this.fireEvent("onPlay") 118 | } 119 | 120 | 121 | /** 122 | MusicManager#onEnded() 123 | **/ 124 | MusicManager.prototype.onEnded = function(){ 125 | console.log("onEnded") 126 | 127 | var track = this.playlist[this.current_track] 128 | 129 | if(this.stop_after_playing == "stop" || (this.play_mode != "shuffle" && this.repeat_mode != "repeat_one" && this.current_track == (this.playlist.length-1))) 130 | delete this.current_track 131 | else 132 | this.playNextTrack() 133 | 134 | this.fireEvent("onEnded") 135 | } 136 | 137 | 138 | /** 139 | MusicManager#playArtist(artist, callback) 140 | **/ 141 | MusicManager.prototype.playArtist = function(artist){ 142 | _gaq.push(['_trackEvent', 'music_manager', 'playArtist', artist]); 143 | 144 | this.scrobbler.artistChart(artist, function(response){ 145 | this.playlist = response.tracks 146 | delete this.current_track 147 | 148 | this.playNextTrack() 149 | }.bind(this)) 150 | } 151 | 152 | 153 | /** 154 | MusicManager#playAlbum(artist, album, callback) 155 | **/ 156 | MusicManager.prototype.playAlbum = function(artist, album){ 157 | _gaq.push(['_trackEvent', 'music_manager', 'playAlbum', artist+'-'+album]); 158 | 159 | this.scrobbler.albumPlaylist(artist, album, function(response){ 160 | this.playlist = response.tracks 161 | delete this.current_track 162 | 163 | this.playNextTrack() 164 | }.bind(this)) 165 | } 166 | 167 | 168 | /** 169 | MusicManager#playNextTrack() 170 | **/ 171 | MusicManager.prototype.playNextTrack = function(ignore_repeat, previous){ 172 | console.log("Next track:", this.current_track) 173 | 174 | if(this.play_mode == "shuffle" && this.repeat_mode != "repeat_one"){ 175 | if(this.shuffle_tracks == undefined){ 176 | this.shuffle_tracks = [] 177 | 178 | for(i in this.playlist) 179 | this.shuffle_tracks.push(i) 180 | 181 | this.shuffle_tracks.sort(function() {return 0.5 - Math.random()}) 182 | } 183 | 184 | if(this.shuffle_tracks.length == 0){ 185 | if(this.playlist.length != 0 && (this.repeat_mode == "repeat_all" || ignore_repeat)){ 186 | delete this.shuffle_tracks 187 | this.playNextTrack(ignore_repeat) 188 | } 189 | 190 | return 191 | } 192 | 193 | this.current_track = this.shuffle_tracks[0] 194 | this.shuffle_tracks.splice(0,1) 195 | } else { 196 | if(this.current_track != undefined && (this.repeat_mode != "repeat_one" || ignore_repeat)) 197 | this.current_track += 1 198 | } 199 | 200 | if(!this.current_track || this.current_track > (this.playlist.length-1)) 201 | this.current_track = 0 202 | 203 | this.searchTrack(this.current_track) 204 | } 205 | 206 | 207 | /** 208 | MusicManager#playPreviews() 209 | **/ 210 | MusicManager.prototype.playPreviews = function(){ 211 | return window.localStorage["skip_previews"] == "false" || window.localStorage["skip_previews"] == undefined 212 | } 213 | 214 | 215 | /** 216 | MusicManager#searchTrack(trackIndex) 217 | **/ 218 | MusicManager.prototype.searchTrack = function(trackIndex, playAfterSearch, getNextResult){ 219 | console.log("Searching track:", trackIndex) 220 | 221 | trackIndex = parseInt(trackIndex) 222 | 223 | var track = this.playlist[trackIndex] 224 | 225 | console.log("Track:", track, this.playlist[0]) 226 | 227 | if(!track) { 228 | if(this.repeat_mode == "repeat_all" && this.playlist[0]){ 229 | track = this.playlist[0] 230 | trackIndex = 0 231 | } else 232 | return 233 | } 234 | 235 | console.log("Track:", track) 236 | 237 | if(!track.info){ 238 | this.updateTrackInfo(trackIndex, function(){ 239 | this.searchTrack(trackIndex, playAfterSearch, getNextResult) 240 | }.bind(this)) 241 | 242 | return 243 | } 244 | 245 | track.song = track.song.replaceEntities() 246 | track.artist = track.artist.replaceEntities() 247 | 248 | if(getNextResult == undefined) 249 | getNextResult = false; 250 | 251 | if(playAfterSearch == undefined) 252 | playAfterSearch = true 253 | 254 | VK.search(track.artist, track.song, track.info.duration, function(response){ 255 | if(!playAfterSearch) 256 | return 257 | 258 | console.log("Resp",response) 259 | 260 | if(response.error){ 261 | track.error_type = response.error; 262 | this.canResearch = false; 263 | if(response.error == 'not_found' && track.track_id && track.streamable && this.playPreviews()) { 264 | this.not_found_in_row = 0 265 | 266 | this.current_track = trackIndex 267 | 268 | this.fireEvent("onLoading") 269 | 270 | this.createAudio() 271 | this.audio.playOrLoad(this.scrobbler.previewURL(track.track_id)) 272 | 273 | this.setVolume() 274 | 275 | track.duration = 30 276 | track.audio_url = this.audio.src; 277 | 278 | this.showNotification() 279 | } else { 280 | this.current_track = trackIndex 281 | 282 | track.not_found = true; 283 | 284 | 285 | this.fireEvent("onPlay") 286 | 287 | if(!this.not_found_in_row) 288 | this.not_found_in_row = 0 289 | 290 | this.not_found_in_row += 1 291 | 292 | if(this.not_found_in_row < 10) 293 | setTimeout(this.playNextTrack.bind(this), 1000) 294 | else 295 | this.not_found_in_row = 0 296 | } 297 | } else { 298 | this.canResearch = response.length > 1; 299 | this.current_track = trackIndex 300 | 301 | this.not_found_in_row = 0 302 | this.fireEvent("onLoading") 303 | 304 | console.log("response.lastIndex", response.lastIndex) 305 | if(track.lastIndex == undefined || track.lastIndex == -1){ 306 | this.playlist[trackIndex].lastIndex = response.lastIndex; 307 | track = this.playlist[trackIndex] 308 | } 309 | 310 | if(this.canResearch && getNextResult){ 311 | this.playlist[trackIndex].lastIndex++ 312 | if(this.playlist[trackIndex].lastIndex >= response.length) 313 | this.playlist[trackIndex].lastIndex = 0; 314 | track = this.playlist[trackIndex]; 315 | } 316 | 317 | console.log("nextIndex", track.lastIndex) 318 | 319 | this.createAudio(); 320 | this.audio.playOrLoad(response[track.lastIndex].url) 321 | 322 | this.setVolume() 323 | 324 | track.duration = parseInt(response[track.lastIndex].duration) 325 | track.scrobbled = false 326 | track.next_song_prefetched = false 327 | 328 | track.audio_url = response[track.lastIndex].url; 329 | 330 | this.showNotification() 331 | } 332 | }.bind(this)) 333 | } 334 | 335 | 336 | /** 337 | MusicManager#play(track_info) 338 | **/ 339 | MusicManager.prototype.play = function(track_info){ 340 | 341 | var track = this.playlist[this.current_track] 342 | 343 | console.log("Playing:", track, track_info, this.current_track) 344 | 345 | delete this.shuffle_tracks 346 | 347 | if(track_info.song){ 348 | // If resuming track 349 | track_info.song = track_info.song.replaceEntities() 350 | track_info.artist = track_info.artist.replaceEntities() 351 | 352 | if(track && track_info.song == track.song && track_info.artist == track.artist && track_info.index == track.index){ 353 | this.audio.playOrLoad() 354 | this.setVolume() 355 | 356 | this.fireEvent("onPlay") 357 | } else { 358 | this.searchTrack(track_info.index) 359 | 360 | _gaq.push(['_trackEvent', 'music_manager', 'play', track_info.artist+'-'+track_info.song]); 361 | 362 | _gaq.push(['_trackEvent', 'music_manager', 'play_artist_chart', track_info.artist]); 363 | } 364 | } else { 365 | if(track_info.album) 366 | this.playAlbum(track_info.artist, track_info.album, function(){}) 367 | else 368 | this.playArtist(track_info.artist, function(){}) 369 | } 370 | } 371 | 372 | /** 373 | MusicManager#play(track_info) 374 | **/ 375 | MusicManager.prototype.research = function(track_info){ 376 | 377 | var track = this.playlist[this.current_track] 378 | 379 | console.log("Research:", track, track_info, this.current_track) 380 | 381 | delete this.shuffle_tracks 382 | 383 | if(track_info.song){ 384 | // If resuming track 385 | track_info.song = track_info.song.replaceEntities() 386 | track_info.artist = track_info.artist.replaceEntities() 387 | 388 | this.searchTrack(track_info.index, true, true) 389 | 390 | _gaq.push(['_trackEvent', 'music_manager', 'play', track_info.artist+'-'+track_info.song]); 391 | 392 | _gaq.push(['_trackEvent', 'music_manager', 'play_artist_chart', track_info.artist]); 393 | } 394 | } 395 | /** 396 | MusicManager#pause() 397 | **/ 398 | MusicManager.prototype.pause = function(){ 399 | this.audio.pause() 400 | } 401 | 402 | 403 | /** 404 | MusicManager#showNotification() 405 | **/ 406 | MusicManager.prototype.showNotification = function(){ 407 | var track = this.playlist[this.current_track] 408 | var show_notification = window.localStorage["show_notifications"] == "true" || window.localStorage["show_notifications"] == undefined 409 | 410 | if(!show_notification || !track || !window.webkitNotifications) return 411 | 412 | 413 | var notification = window.webkitNotifications.createNotification(track.image, track.song, track.artist) 414 | notification.show() 415 | setTimeout(function(){notification.cancel()}, 6000) 416 | } 417 | 418 | 419 | /** 420 | * MusicManager#getTrackInfo() 421 | */ 422 | MusicManager.prototype.updateTrackInfo = function(trackIndex, callback){ 423 | var track = this.playlist[trackIndex] 424 | 425 | if(!track.info) 426 | this.scrobbler.trackInfo(track.artist, track.song, function(response){ 427 | if(response.track_info){ 428 | track.info = response.track_info 429 | 430 | if(track.info.album){ 431 | track.album = track.info.album.title 432 | track.image = track.info.album.image 433 | } 434 | } 435 | 436 | if(!track.image) 437 | this.scrobbler.artistInfo(track.artist, function(resp){ 438 | track.image = resp.image 439 | 440 | if(callback) 441 | callback() 442 | }.bind(this)) 443 | else 444 | if(callback) 445 | callback() 446 | }.bind(this)) 447 | else{ 448 | if(callback) 449 | callback() 450 | } 451 | } 452 | 453 | 454 | /** 455 | * MusicManager#setVolume(value) 456 | */ 457 | MusicManager.prototype.setVolume = function(volume){ 458 | if(volume != undefined) 459 | this.volume = volume 460 | 461 | this.audio.volume = 0.000001 462 | this.audio.volume = this.getVolume() 463 | } 464 | 465 | 466 | /** 467 | * MusicManager#getVolume() -> Integer 468 | **/ 469 | MusicManager.prototype.getVolume = function(){ 470 | if(this.volume == undefined) 471 | this.volume = 1 472 | 473 | return this.volume 474 | } 475 | 476 | 477 | /** 478 | * MusicManager#love() 479 | */ 480 | MusicManager.prototype.love = function(){ 481 | var track = this.playlist[this.current_track] 482 | 483 | if(track) 484 | this.scrobbler.loveTrack(track.artist, track.song) 485 | } 486 | 487 | 488 | /** 489 | * MusicManager#ban() 490 | */ 491 | MusicManager.prototype.ban = function(){ 492 | var track = this.playlist[this.current_track] 493 | 494 | if(track) 495 | this.scrobbler.banTrack(track.artist, track.song) 496 | } 497 | -------------------------------------------------------------------------------- /javascript/jquery-ui.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI 1.8.2 3 | * 4 | * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) 5 | * Dual licensed under the MIT (MIT-LICENSE.txt) 6 | * and GPL (GPL-LICENSE.txt) licenses. 7 | * 8 | * http://docs.jquery.com/UI 9 | */ 10 | (function(c){c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.2",plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e=0;e0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a=0)&&c(a).is(":focusable")}})}})(jQuery); 16 | ;/*! 17 | * jQuery UI Widget 1.8.2 18 | * 19 | * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) 20 | * Dual licensed under the MIT (MIT-LICENSE.txt) 21 | * and GPL (GPL-LICENSE.txt) licenses. 22 | * 23 | * http://docs.jquery.com/UI/Widget 24 | */ 25 | (function(b){var j=b.fn.remove;b.fn.remove=function(a,c){return this.each(function(){if(!c)if(!a||b.filter(a,[this]).length)b("*",this).add(this).each(function(){b(this).triggerHandler("remove")});return j.call(b(this),a,c)})};b.widget=function(a,c,d){var e=a.split(".")[0],f;a=a.split(".")[1];f=e+"-"+a;if(!d){d=c;c=b.Widget}b.expr[":"][f]=function(h){return!!b.data(h,a)};b[e]=b[e]||{};b[e][a]=function(h,g){arguments.length&&this._createWidget(h,g)};c=new c;c.options=b.extend({},c.options);b[e][a].prototype= 26 | b.extend(true,c,{namespace:e,widgetName:a,widgetEventPrefix:b[e][a].prototype.widgetEventPrefix||a,widgetBaseClass:f},d);b.widget.bridge(a,b[e][a])};b.widget.bridge=function(a,c){b.fn[a]=function(d){var e=typeof d==="string",f=Array.prototype.slice.call(arguments,1),h=this;d=!e&&f.length?b.extend.apply(null,[true,d].concat(f)):d;if(e&&d.substring(0,1)==="_")return h;e?this.each(function(){var g=b.data(this,a),i=g&&b.isFunction(g[d])?g[d].apply(g,f):g;if(i!==g&&i!==undefined){h=i;return false}}):this.each(function(){var g= 27 | b.data(this,a);if(g){d&&g.option(d);g._init()}else b.data(this,a,new c(d,this))});return h}};b.Widget=function(a,c){arguments.length&&this._createWidget(a,c)};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(a,c){this.element=b(c).data(this.widgetName,this);this.options=b.extend(true,{},this.options,b.metadata&&b.metadata.get(c)[this.widgetName],a);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});this._create(); 28 | this._init()},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(a,c){var d=a,e=this;if(arguments.length===0)return b.extend({},e.options);if(typeof a==="string"){if(c===undefined)return this.options[a];d={};d[a]=c}b.each(d,function(f, 29 | h){e._setOption(f,h)});return e},_setOption:function(a,c){this.options[a]=c;if(a==="disabled")this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",c);return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a= 30 | b.event.props.length;for(var f;a;){f=b.event.props[--a];c[f]=c.originalEvent[f]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery); 31 | ;/*! 32 | * jQuery UI Mouse 1.8.2 33 | * 34 | * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) 35 | * Dual licensed under the MIT (MIT-LICENSE.txt) 36 | * and GPL (GPL-LICENSE.txt) licenses. 37 | * 38 | * http://docs.jquery.com/UI/Mouse 39 | * 40 | * Depends: 41 | * jquery.ui.widget.js 42 | */ 43 | (function(c){c.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var a=this;this.element.bind("mousedown."+this.widgetName,function(b){return a._mouseDown(b)}).bind("click."+this.widgetName,function(b){if(a._preventClickEvent){a._preventClickEvent=false;b.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(a){a.originalEvent=a.originalEvent||{};if(!a.originalEvent.mouseHandled){this._mouseStarted&& 44 | this._mouseUp(a);this._mouseDownEvent=a;var b=this,e=a.which==1,f=typeof this.options.cancel=="string"?c(a.target).parents().add(a.target).filter(this.options.cancel).length:false;if(!e||f||!this._mouseCapture(a))return true;this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet)this._mouseDelayTimer=setTimeout(function(){b.mouseDelayMet=true},this.options.delay);if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a)){this._mouseStarted=this._mouseStart(a)!==false;if(!this._mouseStarted){a.preventDefault(); 45 | return true}}this._mouseMoveDelegate=function(d){return b._mouseMove(d)};this._mouseUpDelegate=function(d){return b._mouseUp(d)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);c.browser.safari||a.preventDefault();return a.originalEvent.mouseHandled=true}},_mouseMove:function(a){if(c.browser.msie&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&& 46 | this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=a.target==this._mouseDownEvent.target;this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX- 47 | a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery); 48 | ;/* 49 | * jQuery UI Slider 1.8.2 50 | * 51 | * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) 52 | * Dual licensed under the MIT (MIT-LICENSE.txt) 53 | * and GPL (GPL-LICENSE.txt) licenses. 54 | * 55 | * http://docs.jquery.com/UI/Slider 56 | * 57 | * Depends: 58 | * jquery.ui.core.js 59 | * jquery.ui.mouse.js 60 | * jquery.ui.widget.js 61 | */ 62 | (function(d){d.widget("ui.slider",d.ui.mouse,{widgetEventPrefix:"slide",options:{animate:false,distance:0,max:100,min:0,orientation:"horizontal",range:false,step:1,value:0,values:null},_create:function(){var a=this,b=this.options;this._mouseSliding=this._keySliding=false;this._animateOff=true;this._handleIndex=null;this._detectOrientation();this._mouseInit();this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget ui-widget-content ui-corner-all");b.disabled&&this.element.addClass("ui-slider-disabled ui-disabled"); 63 | this.range=d([]);if(b.range){if(b.range===true){this.range=d("
");if(!b.values)b.values=[this._valueMin(),this._valueMin()];if(b.values.length&&b.values.length!==2)b.values=[b.values[0],b.values[0]]}else this.range=d("
");this.range.appendTo(this.element).addClass("ui-slider-range");if(b.range==="min"||b.range==="max")this.range.addClass("ui-slider-range-"+b.range);this.range.addClass("ui-widget-header")}d(".ui-slider-handle",this.element).length===0&&d("").appendTo(this.element).addClass("ui-slider-handle"); 64 | if(b.values&&b.values.length)for(;d(".ui-slider-handle",this.element).length").appendTo(this.element).addClass("ui-slider-handle");this.handles=d(".ui-slider-handle",this.element).addClass("ui-state-default ui-corner-all");this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(c){c.preventDefault()}).hover(function(){b.disabled||d(this).addClass("ui-state-hover")},function(){d(this).removeClass("ui-state-hover")}).focus(function(){if(b.disabled)d(this).blur(); 65 | else{d(".ui-slider .ui-state-focus").removeClass("ui-state-focus");d(this).addClass("ui-state-focus")}}).blur(function(){d(this).removeClass("ui-state-focus")});this.handles.each(function(c){d(this).data("index.ui-slider-handle",c)});this.handles.keydown(function(c){var e=true,f=d(this).data("index.ui-slider-handle"),g,h,i;if(!a.options.disabled){switch(c.keyCode){case d.ui.keyCode.HOME:case d.ui.keyCode.END:case d.ui.keyCode.PAGE_UP:case d.ui.keyCode.PAGE_DOWN:case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:e= 66 | false;if(!a._keySliding){a._keySliding=true;d(this).addClass("ui-state-active");g=a._start(c,f);if(g===false)return}break}i=a.options.step;g=a.options.values&&a.options.values.length?(h=a.values(f)):(h=a.value());switch(c.keyCode){case d.ui.keyCode.HOME:h=a._valueMin();break;case d.ui.keyCode.END:h=a._valueMax();break;case d.ui.keyCode.PAGE_UP:h=a._trimAlignValue(g+(a._valueMax()-a._valueMin())/5);break;case d.ui.keyCode.PAGE_DOWN:h=a._trimAlignValue(g-(a._valueMax()-a._valueMin())/5);break;case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:if(g=== 67 | a._valueMax())return;h=a._trimAlignValue(g+i);break;case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:if(g===a._valueMin())return;h=a._trimAlignValue(g-i);break}a._slide(c,f,h);return e}}).keyup(function(c){var e=d(this).data("index.ui-slider-handle");if(a._keySliding){a._keySliding=false;a._stop(c,e);a._change(c,e);d(this).removeClass("ui-state-active")}});this._refreshValue();this._animateOff=false},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider"); 68 | this._mouseDestroy();return this},_mouseCapture:function(a){var b=this.options,c,e,f,g,h,i;if(b.disabled)return false;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();c={x:a.pageX,y:a.pageY};e=this._normValueFromMouse(c);f=this._valueMax()-this._valueMin()+1;h=this;this.handles.each(function(j){var k=Math.abs(e-h.values(j));if(f>k){f=k;g=d(this);i=j}});if(b.range===true&&this.values(1)===b.min){i+=1;g=d(this.handles[i])}if(this._start(a, 69 | i)===false)return false;this._mouseSliding=true;h._handleIndex=i;g.addClass("ui-state-active").focus();b=g.offset();this._clickOffset=!d(a.target).parents().andSelf().is(".ui-slider-handle")?{left:0,top:0}:{left:a.pageX-b.left-g.width()/2,top:a.pageY-b.top-g.height()/2-(parseInt(g.css("borderTopWidth"),10)||0)-(parseInt(g.css("borderBottomWidth"),10)||0)+(parseInt(g.css("marginTop"),10)||0)};e=this._normValueFromMouse(c);this._slide(a,i,e);return this._animateOff=true},_mouseStart:function(){return true}, 70 | _mouseDrag:function(a){var b=this._normValueFromMouse({x:a.pageX,y:a.pageY});this._slide(a,this._handleIndex,b);return false},_mouseStop:function(a){this.handles.removeClass("ui-state-active");this._mouseSliding=false;this._stop(a,this._handleIndex);this._change(a,this._handleIndex);this._clickOffset=this._handleIndex=null;return this._animateOff=false},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(a){var b; 71 | if(this.orientation==="horizontal"){b=this.elementSize.width;a=a.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{b=this.elementSize.height;a=a.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}b=a/b;if(b>1)b=1;if(b<0)b=0;if(this.orientation==="vertical")b=1-b;a=this._valueMax()-this._valueMin();return this._trimAlignValue(this._valueMin()+b*a)},_start:function(a,b){var c={handle:this.handles[b],value:this.value()};if(this.options.values&&this.options.values.length){c.value= 72 | this.values(b);c.values=this.values()}return this._trigger("start",a,c)},_slide:function(a,b,c){var e;if(this.options.values&&this.options.values.length){e=this.values(b?0:1);if(this.options.values.length===2&&this.options.range===true&&(b===0&&c>e||b===1&&c1){this.options.values[a]=this._trimAlignValue(b);this._refreshValue();this._change(null,a)}if(arguments.length)if(d.isArray(arguments[0])){c=this.options.values;e=arguments[0];for(f=0;fthis._valueMax())return this._valueMax();var b=this.options.step>0?this.options.step:1,c=a%b;a=a-c;if(Math.abs(c)*2>=b)a+=c>0?b:-b;return parseFloat(a.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var a= 78 | this.options.range,b=this.options,c=this,e=!this._animateOff?b.animate:false,f,g={},h,i,j,k;if(this.options.values&&this.options.values.length)this.handles.each(function(l){f=(c.values(l)-c._valueMin())/(c._valueMax()-c._valueMin())*100;g[c.orientation==="horizontal"?"left":"bottom"]=f+"%";d(this).stop(1,1)[e?"animate":"css"](g,b.animate);if(c.options.range===true)if(c.orientation==="horizontal"){if(l===0)c.range.stop(1,1)[e?"animate":"css"]({left:f+"%"},b.animate);if(l===1)c.range[e?"animate":"css"]({width:f- 79 | h+"%"},{queue:false,duration:b.animate})}else{if(l===0)c.range.stop(1,1)[e?"animate":"css"]({bottom:f+"%"},b.animate);if(l===1)c.range[e?"animate":"css"]({height:f-h+"%"},{queue:false,duration:b.animate})}h=f});else{i=this.value();j=this._valueMin();k=this._valueMax();f=k!==j?(i-j)/(k-j)*100:0;g[c.orientation==="horizontal"?"left":"bottom"]=f+"%";this.handle.stop(1,1)[e?"animate":"css"](g,b.animate);if(a==="min"&&this.orientation==="horizontal")this.range.stop(1,1)[e?"animate":"css"]({width:f+"%"}, 80 | b.animate);if(a==="max"&&this.orientation==="horizontal")this.range[e?"animate":"css"]({width:100-f+"%"},{queue:false,duration:b.animate});if(a==="min"&&this.orientation==="vertical")this.range.stop(1,1)[e?"animate":"css"]({height:f+"%"},b.animate);if(a==="max"&&this.orientation==="vertical")this.range[e?"animate":"css"]({height:100-f+"%"},{queue:false,duration:b.animate})}}});d.extend(d.ui.slider,{version:"1.8.2"})})(jQuery); 81 | ; -------------------------------------------------------------------------------- /css/smoothness/jquery-ui.css: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery UI CSS Framework 3 | * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) 4 | * Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. 5 | */ 6 | 7 | /* Layout helpers 8 | ----------------------------------*/ 9 | .ui-helper-hidden { display: none; } 10 | .ui-helper-hidden-accessible { position: absolute; left: -99999999px; } 11 | .ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } 12 | .ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } 13 | .ui-helper-clearfix { display: inline-block; } 14 | /* required comment for clearfix to work in Opera \*/ 15 | * html .ui-helper-clearfix { height:1%; } 16 | .ui-helper-clearfix { display:block; } 17 | /* end clearfix */ 18 | .ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } 19 | 20 | 21 | /* Interaction Cues 22 | ----------------------------------*/ 23 | .ui-state-disabled { cursor: default !important; } 24 | 25 | 26 | /* Icons 27 | ----------------------------------*/ 28 | 29 | /* states and images */ 30 | .ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } 31 | 32 | 33 | /* Misc visuals 34 | ----------------------------------*/ 35 | 36 | /* Overlays */ 37 | .ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } 38 | 39 | 40 | /* 41 | * jQuery UI CSS Framework 42 | * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) 43 | * Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. 44 | * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px 45 | */ 46 | 47 | 48 | /* Component containers 49 | ----------------------------------*/ 50 | .ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; } 51 | .ui-widget .ui-widget { font-size: 1em; } 52 | .ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; } 53 | .ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; } 54 | .ui-widget-content a { color: #222222; } 55 | .ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; } 56 | .ui-widget-header a { color: #222222; } 57 | 58 | /* Interaction states 59 | ----------------------------------*/ 60 | .ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; } 61 | .ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; } 62 | .ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } 63 | .ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; } 64 | .ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } 65 | .ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; } 66 | .ui-widget :active { outline: none; } 67 | 68 | /* Interaction Cues 69 | ----------------------------------*/ 70 | .ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; } 71 | .ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } 72 | .ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } 73 | .ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } 74 | .ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } 75 | .ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } 76 | .ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } 77 | .ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } 78 | 79 | /* Icons 80 | ----------------------------------*/ 81 | 82 | /* states and images */ 83 | .ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } 84 | .ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } 85 | .ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } 86 | .ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); } 87 | .ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } 88 | .ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } 89 | .ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } 90 | .ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } 91 | 92 | /* positioning */ 93 | .ui-icon-carat-1-n { background-position: 0 0; } 94 | .ui-icon-carat-1-ne { background-position: -16px 0; } 95 | .ui-icon-carat-1-e { background-position: -32px 0; } 96 | .ui-icon-carat-1-se { background-position: -48px 0; } 97 | .ui-icon-carat-1-s { background-position: -64px 0; } 98 | .ui-icon-carat-1-sw { background-position: -80px 0; } 99 | .ui-icon-carat-1-w { background-position: -96px 0; } 100 | .ui-icon-carat-1-nw { background-position: -112px 0; } 101 | .ui-icon-carat-2-n-s { background-position: -128px 0; } 102 | .ui-icon-carat-2-e-w { background-position: -144px 0; } 103 | .ui-icon-triangle-1-n { background-position: 0 -16px; } 104 | .ui-icon-triangle-1-ne { background-position: -16px -16px; } 105 | .ui-icon-triangle-1-e { background-position: -32px -16px; } 106 | .ui-icon-triangle-1-se { background-position: -48px -16px; } 107 | .ui-icon-triangle-1-s { background-position: -64px -16px; } 108 | .ui-icon-triangle-1-sw { background-position: -80px -16px; } 109 | .ui-icon-triangle-1-w { background-position: -96px -16px; } 110 | .ui-icon-triangle-1-nw { background-position: -112px -16px; } 111 | .ui-icon-triangle-2-n-s { background-position: -128px -16px; } 112 | .ui-icon-triangle-2-e-w { background-position: -144px -16px; } 113 | .ui-icon-arrow-1-n { background-position: 0 -32px; } 114 | .ui-icon-arrow-1-ne { background-position: -16px -32px; } 115 | .ui-icon-arrow-1-e { background-position: -32px -32px; } 116 | .ui-icon-arrow-1-se { background-position: -48px -32px; } 117 | .ui-icon-arrow-1-s { background-position: -64px -32px; } 118 | .ui-icon-arrow-1-sw { background-position: -80px -32px; } 119 | .ui-icon-arrow-1-w { background-position: -96px -32px; } 120 | .ui-icon-arrow-1-nw { background-position: -112px -32px; } 121 | .ui-icon-arrow-2-n-s { background-position: -128px -32px; } 122 | .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } 123 | .ui-icon-arrow-2-e-w { background-position: -160px -32px; } 124 | .ui-icon-arrow-2-se-nw { background-position: -176px -32px; } 125 | .ui-icon-arrowstop-1-n { background-position: -192px -32px; } 126 | .ui-icon-arrowstop-1-e { background-position: -208px -32px; } 127 | .ui-icon-arrowstop-1-s { background-position: -224px -32px; } 128 | .ui-icon-arrowstop-1-w { background-position: -240px -32px; } 129 | .ui-icon-arrowthick-1-n { background-position: 0 -48px; } 130 | .ui-icon-arrowthick-1-ne { background-position: -16px -48px; } 131 | .ui-icon-arrowthick-1-e { background-position: -32px -48px; } 132 | .ui-icon-arrowthick-1-se { background-position: -48px -48px; } 133 | .ui-icon-arrowthick-1-s { background-position: -64px -48px; } 134 | .ui-icon-arrowthick-1-sw { background-position: -80px -48px; } 135 | .ui-icon-arrowthick-1-w { background-position: -96px -48px; } 136 | .ui-icon-arrowthick-1-nw { background-position: -112px -48px; } 137 | .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } 138 | .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } 139 | .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } 140 | .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } 141 | .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } 142 | .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } 143 | .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } 144 | .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } 145 | .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } 146 | .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } 147 | .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } 148 | .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } 149 | .ui-icon-arrowreturn-1-w { background-position: -64px -64px; } 150 | .ui-icon-arrowreturn-1-n { background-position: -80px -64px; } 151 | .ui-icon-arrowreturn-1-e { background-position: -96px -64px; } 152 | .ui-icon-arrowreturn-1-s { background-position: -112px -64px; } 153 | .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } 154 | .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } 155 | .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } 156 | .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } 157 | .ui-icon-arrow-4 { background-position: 0 -80px; } 158 | .ui-icon-arrow-4-diag { background-position: -16px -80px; } 159 | .ui-icon-extlink { background-position: -32px -80px; } 160 | .ui-icon-newwin { background-position: -48px -80px; } 161 | .ui-icon-refresh { background-position: -64px -80px; } 162 | .ui-icon-shuffle { background-position: -80px -80px; } 163 | .ui-icon-transfer-e-w { background-position: -96px -80px; } 164 | .ui-icon-transferthick-e-w { background-position: -112px -80px; } 165 | .ui-icon-folder-collapsed { background-position: 0 -96px; } 166 | .ui-icon-folder-open { background-position: -16px -96px; } 167 | .ui-icon-document { background-position: -32px -96px; } 168 | .ui-icon-document-b { background-position: -48px -96px; } 169 | .ui-icon-note { background-position: -64px -96px; } 170 | .ui-icon-mail-closed { background-position: -80px -96px; } 171 | .ui-icon-mail-open { background-position: -96px -96px; } 172 | .ui-icon-suitcase { background-position: -112px -96px; } 173 | .ui-icon-comment { background-position: -128px -96px; } 174 | .ui-icon-person { background-position: -144px -96px; } 175 | .ui-icon-print { background-position: -160px -96px; } 176 | .ui-icon-trash { background-position: -176px -96px; } 177 | .ui-icon-locked { background-position: -192px -96px; } 178 | .ui-icon-unlocked { background-position: -208px -96px; } 179 | .ui-icon-bookmark { background-position: -224px -96px; } 180 | .ui-icon-tag { background-position: -240px -96px; } 181 | .ui-icon-home { background-position: 0 -112px; } 182 | .ui-icon-flag { background-position: -16px -112px; } 183 | .ui-icon-calendar { background-position: -32px -112px; } 184 | .ui-icon-cart { background-position: -48px -112px; } 185 | .ui-icon-pencil { background-position: -64px -112px; } 186 | .ui-icon-clock { background-position: -80px -112px; } 187 | .ui-icon-disk { background-position: -96px -112px; } 188 | .ui-icon-calculator { background-position: -112px -112px; } 189 | .ui-icon-zoomin { background-position: -128px -112px; } 190 | .ui-icon-zoomout { background-position: -144px -112px; } 191 | .ui-icon-search { background-position: -160px -112px; } 192 | .ui-icon-wrench { background-position: -176px -112px; } 193 | .ui-icon-gear { background-position: -192px -112px; } 194 | .ui-icon-heart { background-position: -208px -112px; } 195 | .ui-icon-star { background-position: -224px -112px; } 196 | .ui-icon-link { background-position: -240px -112px; } 197 | .ui-icon-cancel { background-position: 0 -128px; } 198 | .ui-icon-plus { background-position: -16px -128px; } 199 | .ui-icon-plusthick { background-position: -32px -128px; } 200 | .ui-icon-minus { background-position: -48px -128px; } 201 | .ui-icon-minusthick { background-position: -64px -128px; } 202 | .ui-icon-close { background-position: -80px -128px; } 203 | .ui-icon-closethick { background-position: -96px -128px; } 204 | .ui-icon-key { background-position: -112px -128px; } 205 | .ui-icon-lightbulb { background-position: -128px -128px; } 206 | .ui-icon-scissors { background-position: -144px -128px; } 207 | .ui-icon-clipboard { background-position: -160px -128px; } 208 | .ui-icon-copy { background-position: -176px -128px; } 209 | .ui-icon-contact { background-position: -192px -128px; } 210 | .ui-icon-image { background-position: -208px -128px; } 211 | .ui-icon-video { background-position: -224px -128px; } 212 | .ui-icon-script { background-position: -240px -128px; } 213 | .ui-icon-alert { background-position: 0 -144px; } 214 | .ui-icon-info { background-position: -16px -144px; } 215 | .ui-icon-notice { background-position: -32px -144px; } 216 | .ui-icon-help { background-position: -48px -144px; } 217 | .ui-icon-check { background-position: -64px -144px; } 218 | .ui-icon-bullet { background-position: -80px -144px; } 219 | .ui-icon-radio-off { background-position: -96px -144px; } 220 | .ui-icon-radio-on { background-position: -112px -144px; } 221 | .ui-icon-pin-w { background-position: -128px -144px; } 222 | .ui-icon-pin-s { background-position: -144px -144px; } 223 | .ui-icon-play { background-position: 0 -160px; } 224 | .ui-icon-pause { background-position: -16px -160px; } 225 | .ui-icon-seek-next { background-position: -32px -160px; } 226 | .ui-icon-seek-prev { background-position: -48px -160px; } 227 | .ui-icon-seek-end { background-position: -64px -160px; } 228 | .ui-icon-seek-start { background-position: -80px -160px; } 229 | /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ 230 | .ui-icon-seek-first { background-position: -80px -160px; } 231 | .ui-icon-stop { background-position: -96px -160px; } 232 | .ui-icon-eject { background-position: -112px -160px; } 233 | .ui-icon-volume-off { background-position: -128px -160px; } 234 | .ui-icon-volume-on { background-position: -144px -160px; } 235 | .ui-icon-power { background-position: 0 -176px; } 236 | .ui-icon-signal-diag { background-position: -16px -176px; } 237 | .ui-icon-signal { background-position: -32px -176px; } 238 | .ui-icon-battery-0 { background-position: -48px -176px; } 239 | .ui-icon-battery-1 { background-position: -64px -176px; } 240 | .ui-icon-battery-2 { background-position: -80px -176px; } 241 | .ui-icon-battery-3 { background-position: -96px -176px; } 242 | .ui-icon-circle-plus { background-position: 0 -192px; } 243 | .ui-icon-circle-minus { background-position: -16px -192px; } 244 | .ui-icon-circle-close { background-position: -32px -192px; } 245 | .ui-icon-circle-triangle-e { background-position: -48px -192px; } 246 | .ui-icon-circle-triangle-s { background-position: -64px -192px; } 247 | .ui-icon-circle-triangle-w { background-position: -80px -192px; } 248 | .ui-icon-circle-triangle-n { background-position: -96px -192px; } 249 | .ui-icon-circle-arrow-e { background-position: -112px -192px; } 250 | .ui-icon-circle-arrow-s { background-position: -128px -192px; } 251 | .ui-icon-circle-arrow-w { background-position: -144px -192px; } 252 | .ui-icon-circle-arrow-n { background-position: -160px -192px; } 253 | .ui-icon-circle-zoomin { background-position: -176px -192px; } 254 | .ui-icon-circle-zoomout { background-position: -192px -192px; } 255 | .ui-icon-circle-check { background-position: -208px -192px; } 256 | .ui-icon-circlesmall-plus { background-position: 0 -208px; } 257 | .ui-icon-circlesmall-minus { background-position: -16px -208px; } 258 | .ui-icon-circlesmall-close { background-position: -32px -208px; } 259 | .ui-icon-squaresmall-plus { background-position: -48px -208px; } 260 | .ui-icon-squaresmall-minus { background-position: -64px -208px; } 261 | .ui-icon-squaresmall-close { background-position: -80px -208px; } 262 | .ui-icon-grip-dotted-vertical { background-position: 0 -224px; } 263 | .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } 264 | .ui-icon-grip-solid-vertical { background-position: -32px -224px; } 265 | .ui-icon-grip-solid-horizontal { background-position: -48px -224px; } 266 | .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } 267 | .ui-icon-grip-diagonal-se { background-position: -80px -224px; } 268 | 269 | 270 | /* Misc visuals 271 | ----------------------------------*/ 272 | 273 | /* Corner radius */ 274 | .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; } 275 | .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } 276 | .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } 277 | .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } 278 | .ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } 279 | .ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } 280 | .ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } 281 | .ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } 282 | .ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } 283 | 284 | /* Overlays */ 285 | .ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } 286 | .ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* Slider 287 | ----------------------------------*/ 288 | .ui-slider { position: relative; text-align: left; } 289 | .ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } 290 | .ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } 291 | 292 | .ui-slider-horizontal { height: .8em; } 293 | .ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } 294 | .ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } 295 | .ui-slider-horizontal .ui-slider-range-min { left: 0; } 296 | .ui-slider-horizontal .ui-slider-range-max { right: 0; } 297 | 298 | .ui-slider-vertical { width: .8em; height: 100px; } 299 | .ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } 300 | .ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } 301 | .ui-slider-vertical .ui-slider-range-min { bottom: 0; } 302 | .ui-slider-vertical .ui-slider-range-max { top: 0; } -------------------------------------------------------------------------------- /javascript/popup.js: -------------------------------------------------------------------------------- 1 | function helpOnHover(element, help){ 2 | var help_func = function(){ 3 | var help_text; 4 | 5 | if (typeof(help) == 'string'){ 6 | help_text = help 7 | } else { 8 | help_text = help.call(element) 9 | } 10 | 11 | $('#quick_help').get(0).innerHTML = help_text 12 | $('#quick_help').show() 13 | 14 | element.title = help_text 15 | } 16 | 17 | element.mouseenter(help_func); 18 | element.click(help_func); 19 | element.mouseleave(function(){ 20 | $('#quick_help').hide() 21 | }) 22 | } 23 | 24 | var music_manager = chrome.extension.getBackgroundPage().music_manager; 25 | var banner_manager = chrome.extension.getBackgroundPage().bannerManager; 26 | 27 | music_manager.dispatcher.addEventListener('onPlay', function(){ 28 | var track = music_manager.playlist[music_manager.current_track] 29 | stopCurrentTrack() 30 | 31 | if(music_manager.current_track != undefined) 32 | if(track.not_found) 33 | try{ 34 | document.getElementById("ex_button_"+music_manager.current_track).className = "sm2_button disabled" 35 | document.getElementById("rs_button_"+music_manager.current_track).className = "research" 36 | document.getElementById("rs_button_"+music_manager.current_track).style.display = "none" 37 | }catch(e){} 38 | else 39 | try{ 40 | document.getElementById("ex_button_"+music_manager.current_track).className = "sm2_button playing" 41 | document.getElementById("rs_button_"+music_manager.current_track).className = "research" 42 | document.getElementById("rs_button_"+music_manager.current_track).style.display = "inline-block" 43 | }catch(e){} 44 | }, true) 45 | 46 | music_manager.dispatcher.addEventListener('onEnded', function(){ 47 | stopCurrentTrack() 48 | }, true) 49 | 50 | music_manager.dispatcher.addEventListener('onLoading', function(){ 51 | if(music_manager.current_track != undefined) 52 | try{document.getElementById("ex_button_"+music_manager.current_track).className = "sm2_button loading"}catch(e){} 53 | 54 | updateTrackInfo() 55 | }, true) 56 | 57 | music_manager.dispatcher.addEventListener('onProgress', function(){ 58 | updateLoadProgress() 59 | }) 60 | 61 | music_manager.dispatcher.addEventListener('onTimeupdate', function(){ 62 | updateProgress() 63 | updateLoadProgress() 64 | }, false) 65 | 66 | function updateProgress(){ 67 | var progress = 0 68 | var loaded_progress = 0 69 | 70 | var track = music_manager.playlist[music_manager.current_track] 71 | 72 | if(track) 73 | progress = (music_manager.audio.currentTime/track.duration)*100.0 74 | 75 | document.getElementById('progress').style.width = progress+'%' 76 | 77 | var track_time = document.querySelector('.controls_container .time') 78 | if(track && track.duration) 79 | track_time.innerHTML = prettyTime(music_manager.audio.currentTime)+' /'+prettyTime(track.duration) 80 | else 81 | track_time.innerHTML = "" 82 | 83 | } 84 | 85 | function updateLoadProgress(){ 86 | var track = music_manager.playlist[music_manager.current_track] 87 | 88 | if(track) 89 | try { 90 | loaded_progress = (music_manager.audio.buffered.end()/track.duration)*100.0 91 | } catch(e){ 92 | loaded_progress = 0 93 | } 94 | 95 | document.getElementById('progress_loaded').style.width = loaded_progress+'%' 96 | } 97 | 98 | function removeFromPlaylist(link){ 99 | var index = parseInt(link.getAttribute('data-index-number')); 100 | 101 | 102 | music_manager.playlist.splice(index, 1); 103 | 104 | 105 | for (var i=0; i"+ 146 | ""+ 147 | ""+playlist[i].artist + "" + 148 | ' – '+ 149 | ""+playlist[i].song+""+ 150 | ""+ 151 | ""+ 152 | ""+ 153 | "" 154 | } 155 | 156 | if(playlist.length == 0){ 157 | html = "
  • Find some tracks on Last.fm
  • " 158 | } 159 | 160 | container.innerHTML = html 161 | 162 | $(container).find('.sm2_button').bind('click', function(evt){ 163 | togglePlaying(evt.currentTarget); 164 | }) 165 | 166 | $(container).find('.research').bind('click', function(evt){ 167 | researchTrack(evt.currentTarget); 168 | }) 169 | 170 | $(container).find('.delete').bind('click', function(evt){ 171 | removeFromPlaylist(evt.currentTarget); 172 | }) 173 | 174 | if(music_manager.current_track != undefined && music_manager.current_track > 12) 175 | var playing_link = document.querySelector('a.sm2_button.playing, a.sm2_button.paused') 176 | 177 | if(playing_link) 178 | container.parentNode.scrollTop = playing_link.parentNode.offsetTop-120 179 | } 180 | 181 | 182 | function toggleScrobbling(event){ 183 | var link = event.target 184 | 185 | if(link.className.match(/active/)){ 186 | link.className = 'toggle_lfm' 187 | } else { 188 | link.className = 'toggle_lfm active' 189 | } 190 | 191 | music_manager.scrobbler.scrobbling = link.className.match(/active/) 192 | 193 | _gaq.push(['_trackEvent', 'controls', 'scrobbling', music_manager.scrobbler.scrobbling+'']); 194 | } 195 | 196 | 197 | function trackLinks(track){ 198 | var artist_link = "http://last.fm/music/"+track.artist.replace(/\s/g,'+') 199 | var song_link = artist_link+"/_/"+track.song.replace(/\s/g,'+') 200 | if(track.album) 201 | var album_link = artist_link+"/"+track.album.replace(/\s/g,'+') 202 | 203 | return { 204 | artist: artist_link, 205 | track: song_link, 206 | album: album_link 207 | } 208 | } 209 | 210 | function updateTrackInfo(){ 211 | var track = music_manager.playlist[music_manager.current_track] 212 | var play_btn = document.getElementById('play') 213 | 214 | if(track){ 215 | document.querySelector('.track_info .container').style.visibility = 'visible' 216 | document.querySelector('.controls_container .love').style.visibility = 'visible' 217 | 218 | //document.querySelector('.controls_container .buy_track').style.visibility = 'visible'; 219 | 220 | updateProgress() 221 | 222 | play_btn.style.display = 'inline' 223 | if(!music_manager.audio.paused){ 224 | play_btn.querySelector('img').src = "images/pause.png" 225 | play_btn.className = "playing" 226 | } else { 227 | play_btn.querySelector('img').src = "images/play.png" 228 | play_btn.className = "paused" 229 | } 230 | 231 | if(track.image) 232 | document.querySelector("#controls #album_image").src = track.image 233 | 234 | var container = document.querySelector("#controls .track_info") 235 | var links = trackLinks(track) 236 | 237 | container.querySelector(".track").innerHTML = track.song 238 | container.querySelector(".track").href = links.track 239 | 240 | container.querySelector(".artist").innerHTML = track.artist 241 | container.querySelector(".artist").href = links.artist 242 | 243 | 244 | if(track.album){ 245 | container.querySelector(".album").innerHTML = track.album 246 | container.querySelector(".album").href = links.album 247 | 248 | container.querySelector(".album_prefix").style.display = "inline" 249 | container.querySelector(".album").style.display = "inline" 250 | } else { 251 | container.querySelector(".album_prefix").style.display = "none" 252 | container.querySelector(".album").style.display = "none" 253 | } 254 | } else { 255 | document.querySelector("#controls #album_image").src = "images/no_image.png" 256 | play_btn.style.display = 'none' 257 | 258 | //document.querySelector('.controls_container').style.visibility = 'hidden' 259 | //document.querySelector('.track_info').style.visibility = 'hidden' 260 | 261 | document.querySelector('.track_info .track').innerHTML = "Track not selected" 262 | document.querySelector('.track_info .container').style.visibility = 'hidden' 263 | document.querySelector('.controls_container .love').style.visibility = 'hidden' 264 | 265 | //document.querySelector('.controls_container .buy_track').style.visibility = 'hidden' 266 | } 267 | } 268 | 269 | function onMouseWheel(evt){ 270 | console.log(evt.wheelDelta) 271 | } 272 | window.addEventListener('DOMMouseScroll', onMouseWheel, false) 273 | 274 | function onLoad(){ 275 | updatePlaylist() 276 | updateTrackInfo() 277 | 278 | 279 | /* Love & Ban buttons */ 280 | var love_btn = document.querySelector('.controls_container .love') 281 | love_btn.addEventListener('click', function(evt){ 282 | music_manager.love() 283 | }, false) 284 | 285 | helpOnHover($(love_btn), "Love track") 286 | 287 | 288 | if(music_manager.scrobbler._username){ 289 | var link = document.querySelector('#scrobbling .lfm_link') 290 | link.innerHTML = music_manager.scrobbler._username 291 | link.href = "http://last.fm/user/"+music_manager.scrobbler._username 292 | 293 | 294 | var toggle_link = document.querySelector('#toggle_scrobbling') 295 | 296 | if(!music_manager.scrobbler.scrobbling) 297 | $(toggle_link).addClass('disabled'); 298 | 299 | link.style.display = 'inline' 300 | toggle_link.style.display = 'inline' 301 | } else { 302 | var connect_lfm = document.querySelector('#scrobbling .connect_lfm') 303 | connect_lfm.style.display = 'inline' 304 | love_btn.style.display = 'none' 305 | 306 | connect_lfm.addEventListener('click', function(){music_manager.scrobbler.auth()}, false) 307 | } 308 | 309 | var play_btn = document.getElementById('play') 310 | play_btn.addEventListener('click', togglePlayingBig, false) 311 | 312 | helpOnHover($(play_btn), "Play/Pause") 313 | 314 | 315 | var next_track = document.querySelector('.controls_container .next') 316 | next_track.addEventListener('click', function(){ 317 | music_manager.playNextTrack(true) 318 | 319 | _gaq.push(['_trackEvent', 'controls', 'nextTrack']); 320 | }, false) 321 | 322 | helpOnHover($(next_track), "Next track") 323 | 324 | 325 | var volume_toggle = document.querySelector('.volume_control .volume_link') 326 | volume_toggle.addEventListener('click', function(){ 327 | var volume_range = $('#volume-slider') 328 | volume_range.slider("option", "value", 0) 329 | music_manager.setVolume(0) 330 | 331 | _gaq.push(['_trackEvent', 'controls', 'muteVolume']); 332 | }) 333 | helpOnHover($(volume_toggle), "Mute") 334 | 335 | /* Progress bar */ 336 | var progress = document.getElementById('progress_bar') 337 | progress.addEventListener('click', function(evt){ 338 | var track = music_manager.playlist[music_manager.current_track] 339 | var progress = (evt.clientX/468) 340 | 341 | console.log("X:", track.duration * progress) 342 | 343 | if(track) 344 | music_manager.audio.currentTime = track.duration * progress 345 | 346 | _gaq.push(['_trackEvent', 'controls', 'progressChange']); 347 | }, false) 348 | 349 | 350 | var play_mode = $('#play_mode_control') 351 | var repeat_mode = $('#repeat_mode_control') 352 | var stop_after = $('#stop_after_control') 353 | 354 | if (music_manager.play_mode == "shuffle") 355 | play_mode.removeClass('disabled') 356 | 357 | if (music_manager.repeat_mode && music_manager.repeat_mode != "normal"){ 358 | repeat_mode.removeClass('disabled') 359 | 360 | if (music_manager.repeat_mode == "repeat_all") 361 | repeat_mode.addClass('all') 362 | } 363 | 364 | if (music_manager.stop_after_playing == "stop") 365 | stop_after.removeClass('disabled') 366 | 367 | 368 | var play_source = document.getElementById('play_source'); 369 | if(play_source) 370 | play_source.addEventListener('click', function(evt){ 371 | music_manager.scrobbler.radioTune('lastfm://user/buger_swamp/loved', function(response){ 372 | music_manager.scrobbler.radioGetPlaylist(function(response){ 373 | console.log("ZXCZXC") 374 | /* 375 | var xhr = new XMLHttpRequest() 376 | xhr.open("GET", response.url, true) 377 | xhr.send() 378 | 379 | console.log("Sending redirect response:", response.url) 380 | 381 | xhr.onreadystatechange = function(){ 382 | console.log("Redirect response:", xhr) 383 | } 384 | */ 385 | // music_manager.audio.playOrLoad(response.url) 386 | }) 387 | }) 388 | }) 389 | 390 | $('.buy_track').live('click', function(){ 391 | _gaq.push(['_trackEvent', 'controls', 'buyTrack']); 392 | 393 | var track = music_manager.playlist[music_manager.current_track] 394 | 395 | if (track) { 396 | var keywords = track.artist + ' ' + track.song; 397 | keywords = encodeURIComponent(keywords).replace("'",''); 398 | 399 | if (banner_manager.country === 'US') { 400 | var url = "http://www.amazon.com/gp/search?ie=UTF8&keywords="+keywords+"&tag=chromus-20&index=digital-music&linkCode=ur2&camp=1789&creative=9325"; 401 | } else { 402 | var url = "http://www.amazon.com/gp/search?ie=UTF8&keywords="+keywords+"&tag=chromus-20&index=music&linkCode=ur2&camp=1789&creative=9325"; 403 | } 404 | 405 | chrome.tabs.create({url: url}); 406 | 407 | return true; 408 | } else { 409 | return false; 410 | } 411 | }); 412 | 413 | if (!window.localStorage["new_changes_2.9.692"]) { 414 | $('.new_changes').show() 415 | .bind('click', function() { 416 | window.localStorage["new_changes_2.9.692"] = true; 417 | 418 | chrome.tabs.create({url: chrome.extension.getURL("options.html")}); 419 | }); 420 | } 421 | } 422 | 423 | function getBanner() { 424 | var banner = banner_manager.getBanner(); 425 | var show_banner = window.localStorage["show_banner"] == "true" || window.localStorage["show_banner"] == undefined; 426 | show_banner = false; 427 | 428 | if (show_banner && banner) { 429 | if (banner.match(/\