BetterFetLife

See website

当前为 2015-06-14 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        BetterFetLife
// @namespace   com.fetlife.better
// @include     https://fetlife.com/*
// @version     1
// @grant       none
// @description  See website
// ==/UserScript==

$(document).ready(function(){
			
	// add custom css
	$('head').append('<style type="text/css">' + bfl_css + '</style>');
	
	// === USER POPUP === //
	
	// create user popup
	$('body').append('							' +
		'	<div id="bfl-user">					' +
		'		<a class="avatar-wrap">			' +
		'			<div class="avatar"></div>	' +
		'		</a>							' +
		'		<a class="name"></a>			' +
		'		<span class="status"></span>	' +
		'		<span class="location"></span>	' +
		'		<span class="photos"></span>	' +
		'	</div>								'
	);
	
	// show a user popup on hover
	$('a[href^="/users/"], a[href^="https://fetlife.com/users/"').live('mouseover', $.debounce( 250, function(){
				
		var linkEl = this;
		var href = $(linkEl).attr('href');
			href = href.replace('https://fetlife.com', '');
		
		// prevent non-user links
		if( href.split('/').length != 3 ) return;
		
		// prevent self-links
		if( $(linkEl).closest('#bfl-user').length > 0 ) return;		
		
		// prevent closing
		clearTimeout(hideUserPopupTimeout);	
		
		// reset the popup
		hideUserPopup();
				
		// show the popup
		$('#bfl-user')
			.addClass('loading')
			.css({
				top: $(linkEl).offset().top + $(linkEl).height() + 8,
				left: $(linkEl).offset().left
			})
			.show();
								
		$.ajax({
			url: href,
            dataType: "html",
			
			// cache is OK
			cache: true,
			
			// prevent 503, fetlife don't liking ajax calls
		    beforeSend: function(xhr) {
		        xhr.setRequestHeader(
		            'X-Requested-With',
		            {
		                toString: function() { return ''; }
		            }
		        );
		    },
			success: function(userDOM){
				
				var userAvatarEl = $(userDOM).find('#main_content a img');
				
				// avatar href
				$('#bfl-user')
					.attr('avatar-href', $(userAvatarEl).attr('src'));
									
				// avatar
				$('#bfl-user .avatar-wrap')
					.attr('href', href)
					
				$('#bfl-user .avatar')
					.css('background-image', 'url(' + $(userAvatarEl).attr('src') + ')')

				// name
				$('#bfl-user .name')
					.attr('href', href)
					.html( $(userAvatarEl).attr('alt') );
				
				// status (age+gender+orientation)
				$('#bfl-user .status')
					.html( $(userDOM).find('#profile h2 .small').html() );
				
				// location
				$('#bfl-user .location')
					.html( $(userDOM).find('#profile h2.bottom + p').html() );
				
				window.userDOM = userDOM;
				
				// photos
				var photos = $(userDOM).find('#profile .container a[href^="/users/"][href*="/pictures"]');
				photos = photos.filter(function(){
					return $(this).find('img').length > 0;
				})
				photos = photos.slice(0,5);
				$('#bfl-user .photos')
					.html('')
					.append( photos );
					
				// friends status
				// remove the link first
				$(userDOM).find('.friends_badge').find('a').remove()
				$('#bfl-user .friends_status')
					.html( $(userDOM).find('.friends_badge').text() );	
					
				$('#bfl-user')
					.removeClass('loading')	
			}
		});
		
	})).live('mouseleave', function(e){
		
		var linkEl = this;
		var href = $(linkEl).attr('href');
		
		// prevent non-user links
		if( href.split('/').length != 3 ) return;
		
		clearTimeout(hideUserPopupTimeout);
		console.log('a mouseleave');
		hideUserPopupTimeout = setTimeout(hideUserPopup, hideUserPopupDelay);
	});
	$('#bfl-user').live('mouseover', function(e){
		clearTimeout(hideUserPopupTimeout);
	});
	$('#bfl-user').live('mouseleave', function(e){
		clearTimeout(hideUserPopupTimeout);
		console.log('bfl-user mouseleave');
		hideUserPopupTimeout = setTimeout(hideUserPopup, hideUserPopupDelay);
	});

	var hideUserPopupTimeout = setTimeout('', 0);
	var hideUserPopupDelay = 500;
	
	function hideUserPopup() {
		
		$('#bfl-user .avatar').attr('style', '');
		$('#bfl-user .name').html('').attr('href', '');
		$('#bfl-user .status').html('');
		$('#bfl-user .location').html('');
		$('#bfl-user .friends_badge').html('');
		$('#bfl-user .photos').html('');
		$('#bfl-user').removeClass('loading');
		
		$('#bfl-user').hide();
	}
	
	// === IMAGE POPUP === //
	
	// create image popup
	$('body').append('										' +
		'	<div id="bfl-image">							' +
		'		<span class="header">						' +
		'			<span class="title"></span>				' +
		'			<span class="like-wrap">				' +
		'				<span class="like-count"></span>	' +
		'				<span class="like picto">k</span>	' +
		'			</span>									' +
		'		</span>										' +
		'		<a class="image-wrap">						' +
		'			<img class="image" />					' +
		'		</a>										' +
		'	</div>											'
	);
	
	
	$('a[href^="/users/"][href*="/pictures"], a[href^="https://fetlife.com/users/"][href*="/pictures"]').live('mouseover', $.debounce( 250, function(){
				
		var linkEl = this;
		var href = $(this).attr('href');
			href = href.replace('https://fetlife.com', '');
		
		// prevent non-image links
		if( href.split('/').length != 5 ) return;
		
		// prevent self-links
		if( $(linkEl).closest('#bfl-image').length > 0 ) return;
		
		// reset the popup
		hideImagePopup();
		
		// show the popup
		var css = {
			top: $(linkEl).offset().top + $(linkEl).height() + 8
		}
		
		if( $(linkEl).offset().left > $(window).width()/2 ) {
			css.right = $(window).width() - $(linkEl).offset().left - $(linkEl).width();
			$('#bfl-image').addClass('alignright');
		} else {
			css.left = $(linkEl).offset().left;
		}
		
		$('#bfl-image')
			.addClass('loading')
			.css(css)
			.show();
		
		$.ajax({
            url: href,
            dataType: "html",
            success: function(html){  
               
                var title = $(html).find('.s.i.caption').text();
                
	            var likeUrl = href.split('/');  
	                likeUrl = likeUrl[ likeUrl.length-1 ];
	                likeUrl = "/pictures/" + likeUrl + "/likes"
				
				// extract the image src                                          
                var src = $(html).find('style').first().html().match(/\(\'(.*?)\'\)/);
                    src = src[0];
                    src = src.replace("('", "");
                    src = src.replace("')", "");
                   					
				$('#bfl-image .title')
					.html(title)
					.attr('title', title)
				
				$('#bfl-image .like-wrap')
					.attr('data-href', likeUrl);
				
				$('#bfl-image .image-wrap')
					.attr('href', href);
					
				$('#bfl-image .image')
					.load(function(){
						$('#bfl-image').removeClass('loading')
					})
					.attr('src', src)
               
				// get amount of likes
                $.ajax({
                    url: likeUrl,
                    dataType: "json",
                    success: function(data) {
                        $('#bfl-image .like-wrap').toggle(data.user_can_like);
                        if( data.is_liked_by_user ) {
                            $('#bfl-image .like-wrap').addClass('liked');
                        }
				
						$('#bfl-image .like-count')
							.html(data.total);
                    }
                });
            }
        });
		
	})).live('mouseleave', function(e){
		
		var linkEl = this;
		var href = $(linkEl).attr('href');
		
		// prevent non-user links
		if( href.split('/').length != 3 ) return;
		
		clearTimeout(hideImagePopupTimeout);
		hideImagePopupTimeout = setTimeout(hideImagePopup, hideImagePopupDelay);
	});
	$('#bfl-image').live('mouseover', function(e){
		clearTimeout(hideImagePopupTimeout);	
		clearTimeout(hideUserPopupTimeout);
	});
	$('#bfl-image').live('mouseleave', function(e){
		clearTimeout(hideImagePopupTimeout);
		hideImagePopupTimeout = setTimeout(hideImagePopup, hideImagePopupDelay);
	});

	var hideImagePopupTimeout = setTimeout('', 0);
	var hideImagePopupDelay = 500;
	
	function hideImagePopup() {
		
		$('#bfl-image .title').html('').attr('href', '');
		$('#bfl-image .image').attr('src', '');
		$('#bfl-image .like-wrap').attr('data-href', '');
		$('#bfl-image .like-count').html('');
		$('#bfl-image').removeClass('loading');
		$('#bfl-image').removeClass('alignright');
		$('#bfl-image').hide();
	}
	
	$('#bfl-image .like-wrap').live('click', function(){
        var this_ = this;
        $.ajax({
            url: $(this_).data('href') + '/toggle',
            type: 'post',
            success: function(){
                
                if( $(this_).hasClass('liked') ) {
	                $('#bfl-image .like-count').html( parseInt( $('#bfl-image .like-count').html()) - 1 )
                } else {
	                $('#bfl-image .like-count').html( parseInt( $('#bfl-image .like-count').html()) + 1 )
                }
                
                $(this_).toggleClass('liked');
            }
        });
       
        return false;
    });
	
});

var bfl_css = '' +
'	#bfl-user {' +
'		position: absolute;' +
'		z-index: 100;' +
'		display: none;' +
'		padding: 4px;' +
'		min-width: 180px;' +
'		height: 80px;' +
'		padding-left: 92px;' +
'		padding-right: 8px;' +
'		background: #323232;' +
'		border: 3px solid #171717;' +
'	}' +
'	#bfl-user.loading {' +
'		padding-left: 84px;' +
'		padding-right: 4px;' +
'		min-width: 0;' +
'	}' +
'	#bfl-user:before,' +
'	#bfl-image:before {' +
'		position: absolute;' +
'		z-index: 101;' +
'		display: block;' +
'		content: "";' +
'		left: 7px;' +
'		top: -8px;' +
'		border: 8px solid transparent;' +
'		border-bottom-color: #171717;' +
'		border-top-width: 0;' +
'	}' +
'	#bfl-user:after,' +
'	#bfl-image:after {' +
'		position: absolute;' +
'		z-index: 102;' +
'		display: block;' +
'		content: "";' +
'		left: 10px;' +
'		top: -5px;' +
'		border: 5px solid transparent;' +
'		border-bottom-color: #323232;' +
'		border-top-width: 0;' +
'	}' +
'		#bfl-user .avatar {' +
'			position: absolute;' +
'			left: 4px;' +
'			width: 80px;' +
'			height: 80px;' +
'			padding: 0px;' +
'			margin-right: 8px;' +
'			background-color: transparent;' +
'			background-size: cover;' +
'			background-position: center center;' +
'			background-repeat: no-repeat;' +
'		}' +
'		#bfl-user.loading .avatar {' +
'			background-size: auto;' +
'			background-image: url(https://flassets.a.ssl.fastly.net/std/spinners/circle_big.gif);' +
'			margin-right: 0;' +
'		}' +
'		#bfl-user .name {' +
'			white-space: nowrap;' +
'		}'	+
'		#bfl-user .status {' +
'			white-space: nowrap;' +
'			color: #aaa;' +
'		}'	+
'		#bfl-user .location {' +
'			display: block;' +
'			font-size: 12px;' +
'			white-space: nowrap;' +
'		}' +
'		#bfl-user .friends_status {' +
'			float: right;' +
'			font-size: 12px;' +
'		}' +
'		#bfl-user .photos {' +
'			position: absolute;' +
'			right: 4px;' +
'			bottom: 4px;' +
'			font-size: 12px;' +
'		}' +
'			#bfl-user .photos a {' +
'				float: left;' +
'				font-size: 12px;' +
'			}' +
'				#bfl-user .photos a img {' +
'					float: left;' +
'					margin: 2px;' +
'					width: 25px;' +
'					height: 25px;' +
'					padding: 0;' +
'				}' +
'	#bfl-image {' +
'		position: absolute;' +
'		z-index: 100;' +
'		display: none;' +
'		background: #323232;' +
'		border: 3px solid #171717;' +
'		padding: 4px;' +
'	}' +
'	#bfl-image.alignright:before {' +
'		left: auto;' +
'		right: 7px;' +
'	}' +
'	#bfl-image.alignright:after {' +
'		left: auto;' +
'		right: 10px;' +
'	}' +
'	#bfl-image.loading {' +
'		width: 80px;' +
'		height: 80px;' +
'		background: #323232 url(https://flassets.a.ssl.fastly.net/std/spinners/circle_big.gif) no-repeat center center;' +
'	}' +
'		#bfl-image .header {' +
'			position: absolute;' +
'			left: 0;' +
'			right: 0;' +
'			top: 0;' +
'			background: #323232;' +
'			padding: 4px;' +
'			overflow: hidden;' +
'			font-size: 12px;;' +
'		}'	+
'		#bfl-image.loading .header {' +
'			display: none;' +
'		}' +
'			#bfl-image .title {' +
'				float: left;' +
'				width: 80%;' +
'				white-space: nowrap;' +
'				overflow: hidden;' +
'				text-overflow: ellipsis;' +
'			}'	+
'			#bfl-image .like-wrap {' +
'				float: right;' +
'				width: 10%;' +
'				white-space: nowrap;' +
'				text-align: right;' +
'				cursor: pointer;' +
'			}'	+
'			#bfl-image .like-wrap:hover {' +
'				color: #ffffff;' +
'			}'	+
'			#bfl-image .like-wrap:active {' +
'				color: #bbbbbb;' +
'			}'	+
'			#bfl-image .like-wrap.liked {' +
'				color: #DD0000;' +
'			}'	+
'			#bfl-image .like-wrap.liked:hover {' +
'				color: #FF0000;' +
'			}'	+
'			#bfl-image .like-wrap.liked:active {' +
'				color: #BB0000;' +
'			}'	+
'		#bfl-image .image {' +
'			display: block;' +
'			padding: 0;' +
'		}'	+



/*
 * jQuery throttle / debounce - v1.1 - 3/7/2010
 * http://benalman.com/projects/jquery-throttle-debounce-plugin/
 * 
 * Copyright (c) 2010 "Cowboy" Ben Alman
 * Dual licensed under the MIT and GPL licenses.
 * http://benalman.com/about/license/
 */
(function(b,c){var $=b.jQuery||b.Cowboy||(b.Cowboy={}),a;$.throttle=a=function(e,f,j,i){var h,d=0;if(typeof f!=="boolean"){i=j;j=f;f=c}function g(){var o=this,m=+new Date()-d,n=arguments;function l(){d=+new Date();j.apply(o,n)}function k(){h=c}if(i&&!h){l()}h&&clearTimeout(h);if(i===c&&m>e){l()}else{if(f!==true){h=setTimeout(i?k:l,i===c?e-m:e)}}}if($.guid){g.guid=j.guid=j.guid||$.guid++}return g};$.debounce=function(d,e,f){return f===c?a(d,e,false):a(d,f,e!==false)}})(this);