/*
* @title ☆button
* @description ☆ボタンのないはてなブログに☆ボタン出す
* @include http://*
* @license MIT License
* @require http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js
* @require http://s.hatena.ne.jp/js/HatenaStar.js
*/
(function($) {
var setupStar = function() {
if (!Hatena.Star)
return;
var entryConfig = {
entryNodes: {
// PC, article
'article.entry': {
uri: 'a.bookmark',
title: 'h1.entry-title',
container: 'div.hatena-star-container'
},
// PC, archive
'section.archive-entry': {
uri: 'a.entry-title-link',
title: 'h1.entry-title',
container: 'span.star-container'
},
// touch, article
'li.entry-article': {
uri: 'a.bookmark',
title: '.entry-title',
container: 'div.hatena-star-container'
},
// touch, comment
'li.entry-comment': {
uri: 'p.comment-metadata a.permalink',
title: 'div.comment-content',
container: '.comment-metadata'
}
}
};
var commentConfig = {
entryNodes: {
'li.entry-comment': {
uri: 'p.comment-metadata a.permalink',
title: 'div.comment-content::-ten-truncate',
container: '.comment-metadata'
}
}
};
Hatena.Star.SiteConfig = entryConfig;
Hatena.Star.EntryLoader.intoCommentScope = function(func) {
Hatena.Star.SiteConfig = commentConfig;
func();
Hatena.Star.SiteConfig = entryConfig;
};
Hatena.Star.User.prototype.userPage = function() {
var uri = Hatena.Diary.data('admin-domain') + '/' + this.name + '/';
return uri;
};
var img_src = Hatena.Diary.URLGenerator.static_url('/images/theme/star/hatena-star-add-button.png');
Hatena.Star.AddButton.ImgSrc = img_src;
Hatena.Star.AddButton.SmartPhone.ImgSrc = img_src;
};
setupStar();
Hatena.Diary.Star = {
// スター大きくしてプロフィールアイコン重ねる
initBigStar: function() {
if (!Hatena.Star)
return;
// 体裁変更
Hatena.Star.Star.prototype.generateImg = function() {
var img, star_img, user_img, span, user_icon;
user_icon = function(name) {
return "http://cdn1.www.st-hatena.com/users/" + (encodeURI(name.slice(0, 2))) + "/" + (encodeURI(name)) + "/profile.gif";
};
star_img = Hatena.Star.Star.getImage(this.container);
star_img.alt = this.screen_name;
star_img.title = '';
if (this.color && this.color != 'yellow' && this.color != 'temp') {
star_img.alt = star_img.alt + ' (' + this.color + ')';
}
this.img = star_img;
if (this.screen_name) {
if (!Hatena.Star.Star.gotImage[this.screen_name]) {
Hatena.Star.Star.gotImage[this.screen_name] = {};
}
if (!Hatena.Star.Star.gotImage[this.screen_name][this.color]) {
span = document.createElement('span');
span.className = 'hatena-big-star-star-container';
user_img = document.createElement('img');
user_img.src = user_icon(this.screen_name);
user_img.setAttribute('tabIndex', 0);
user_img.className = 'hatena-star-user';
user_img.style.padding = '0';
user_img.style.border = 'none';
span.appendChild(user_img);
span.appendChild(star_img);
Hatena.Star.Star.gotImage[this.screen_name][this.color] = span;
}
this.img = Hatena.Star.Star.gotImage[this.screen_name][this.color].cloneNode(true);
}
};
// posの値の調整
Hatena.Star.AddButton.prototype.showColorPallet = function(e) {
this.clearSelectedColorTimer();
if (!this.pallet)
this.pallet = new Hatena.Star.Pallet();
var pos = Ten.Geometry.getElementPosition(this.img);
pos.x += 2;
pos.y += 22;
this.pallet.showPallet(pos, this);
};
Hatena.Star.AddButton.SmartPhone.prototype.showColorPallet = function(e) {
this.clearSelectedColorTimer();
if (!this.pallet) {
this.pallet = new Hatena.Star.Pallet.SmartPhone();
}
var pos = Ten.Geometry.getElementPosition(this.img);
pos.x = Ten.Browser.isDSi ? 5 : 15;
pos.y += 30;
this.pallet.showPallet(pos, this);
this.pallet.show(Hatena.Star.UseAnimation ? {x: 0,y: 0} : pos);
};
// スターボタン押されたら必要な情報をはてなブログのサーバーに送る
Hatena.Star.AddButton.prototype.addStar = _.wrap(Hatena.Star.AddButton.prototype.addStar, function(fun, e) {
fun.apply(this, [e]);
Hatena.Diary.trackEvent('hatena-star-add');
});
Hatena.Star.AddButton.SmartPhone.prototype.addStar = _.wrap(Hatena.Star.AddButton.SmartPhone.prototype.addStar, function(fun, e) {
fun.apply(this, [e]);
Hatena.Diary.trackEvent('hatena-star-add-smartphone');
});
},
// スター付けたことない場合、ツールチップを表示する
initStarNavigation: function() {
if (!Hatena.Star)
return;
var TIPSY_ALLOW_OFFSET = 8;
var $tipsy_arrow = $('<div>').addClass('tipsy-arrow blue'),
$star_navigation_tooltip = $('<div>').addClass('star-navigation-tooltip tipsy-n')
.append($('<p>').text(Hatena.Locale.text('star-navigation-message')))
.prepend($tipsy_arrow);
$.getJSON("https://www.hatena.ne.jp/notify/notices.count.json?services=1&callback=?", function(res) {
// スター利用中ならなにもしない
if (res.services.s)
return;
// はてなスター利用中ではないけどスターつけた
Hatena.Star.AddButton.prototype.addStar = _.wrap(Hatena.Star.AddButton.prototype.addStar, function(fun, e) {
fun.apply(this, [e]);
Hatena.Diary.trackEvent('hatena-star-add-first');
});
// 既読かどうかを localStorage に保存する
var localStorageKey = 'Hatena.Diary.Blogs.StarNavigation.Read';
var isRead = function() {
try {
return localStorage[localStorageKey] === 'already';
} catch (ignore) {
}
};
var setIsRead = function(isRead) {
try {
localStorage[localStorageKey] = isRead ? 'already' : 'not yet';
} catch (ignore) {
}
};
// 既読のとき tipsy 出す必要ない
if (isRead())
return;
var wait_for_star_load = function(func) {
setTimeout(function() {
var $star_button = $('.hatena-star-add-button');
if ($star_button.length !== 0) {
func();
return;
}
wait_for_star_load(func);
}, 200);
};
wait_for_star_load(function() {
$('.hatena-star-container').after($star_navigation_tooltip);
$('.tipsy-arrow.blue').each(function() {
$(this).css({left: $(this).parent().siblings().find('.hatena-star-add-button').offset().left - $star_navigation_tooltip.offset().left + TIPSY_ALLOW_OFFSET});
});
$('.star-navigation-tooltip').click(function() {
setIsRead(true);
$(this).fadeOut(1000);
});
$('.hatena-star-add-button').click(function() {
setIsRead(true);
$('.star-navigation-tooltip').fadeOut(1000);
});
});
});
},
initDeleteStar: function() {
if (!Hatena.Star)
return;
Hatena.Star.Star.prototype.setImgObservers = function() {
var self = this;
new Ten.Observer(self.img, 'onmouseover', self, 'showName');
new Ten.Observer(self.img, 'onmouseout', self, 'hideName');
};
Hatena.Star.Star.prototype.asElement = _.wrap(Hatena.Star.Star.prototype.asElement, function(func) {
var self = this;
var element = func.call(self);
if (!Hatena.Star.Config.isStarDeletable)
return element;
// 以下はスターがdocumentにappendされてから実行
// スター削除できるとき成功するDeferredを返す
var checkCanDelete = _.once(function() {
var dfd = $.Deferred();
var uri = Hatena.Star.BaseURL.replace(/^http:/, Hatena.Star.BaseURLProtocol) + 'star.deletable.json';
var data = {
name: self.name,
uri: self.entry.uri
};
if (self.color)
data.color = self.color;
if (self.quote)
data.quote = self.quote;
$.ajax({
type: 'get',
dataType: 'jsonp',
url: uri,
data: data
}).done(function(res) {
var can_delete = res.result && (res.message || res.confirm_html);
if (can_delete) {
dfd.resolve(res);
} else {
dfd.reject(res);
}
});
return dfd;
});
var $star_container = $(self.anchor);
$star_container.hover(
function() {
// 削除可能なとき,右上に削除ボタンを表示
checkCanDelete().done(function(deletion_info) {
var $delete_button = $("<img>").addClass('star-delete-button').attr(
"src", Hatena.Diary.URLGenerator.static_url('/images/theme/star/star-delete.png')
);
$star_container.append($delete_button);
var button_position = $delete_button.position();
$delete_button.css({
left: button_position.left - 9,
top: button_position.top
});
//クリックされたら削除確認
$delete_button.click(function() {
if (deletion_info.confirm_html) {
var pos = Ten.Geometry.getElementPosition(self.anchor);
var scr = new Hatena.Star.DeleteConfirmScreen();
scr.showConfirm(deletion_info.confirm_html, self, pos);
} else if (confirm(deletion_info.message)) {
self.deleteStar();
}
return false;
});
});
},
function() {
$(this).find(".star-delete-button").remove();
});
return element;
});
},
initSelectStar: function() {
if (!Hatena.Star)
return;
var SELECT_STAR_OPACITY = 0.6, SELECT_STAR_OFFSET = 60, SELECT_STAR_SIZE = 32, GET_BIGGER_SIZE = 24.0;
var $target_article;
var $select_star = $('.select_star_button_container');
var $message_box = $('#select-star-message-box');
var using_select_star = false;
var message_fadeout_timer;
// スターボタンをクリックしたとき
Hatena.Star.AddButton.prototype.addStar = _.wrap(Hatena.Star.AddButton.prototype.addStar, function(func, e) {
this.copySelectedText();
func.call(this, e);
if (this.selectedText !== '') {
Hatena.Diary.trackEvent('hatena-star-add-quote');
}
});
// スター投稿の結果が返ってきたとき
Hatena.Star.AddButton.prototype.receiveResult = _.wrap(Hatena.Star.AddButton.prototype.receiveResult, function(func, args) {
// メッセージを出す位置
var message_box_offset = {
top: $select_star.offset().top,
left: $select_star.offset().left + SELECT_STAR_SIZE
};
if (using_select_star) {
// ログインしてるときのみメッセージを出す
if (args.is_guest) {
var pos = {x: message_box_offset.left,y: message_box_offset.top};
// HatenaStar.js本体でウィンドウ出す位置を調整されるので, その分足し引きして調整を打ち消す
pos.x += 10;
pos.y -= 25;
this.lastPosition = pos;
} else {
$message_box
.stop()
.css(_.extend(message_box_offset, {opacity: 1.0}))
.show();
if (message_fadeout_timer) {
clearTimeout(message_fadeout_timer);
}
message_fadeout_timer = setTimeout(function() {
$message_box.fadeOut(1000);
}, 1000);
Hatena.Diary.trackEvent('hatena-star-add-select');
}
}
using_select_star = false;
func.call(this, args);
});
// テキストを選択したとき
$(document).mouseup(function(e) {
var $target = $(e.target);
// deferしないとタイミング的にうまく選択領域を取得できない
_.defer(function() {
var selected_text = Ten.DOM.getSelectedText();
var selection_is_blank = (selected_text === '');
var is_article = $target.closest('article').length > 0;
var is_comment = $target.closest('.comment').length > 0;
var is_select_star = $target.closest('.select_star_button_container').length > 0;
if (is_select_star) {
return;
}
if (!is_article || is_comment || selection_is_blank) {
$select_star.hide();
return;
}
$target_article = $target.closest('article');
$select_star.css({top: e.pageY,left: $target_article.offset().left - SELECT_STAR_OFFSET});
$select_star.show();
});
});
$select_star.on('mouseenter', function() {
$(this).css({opacity: 1.0});
});
$select_star.on('mouseleave', function() {
$(this).css({opacity: SELECT_STAR_OPACITY});
});
$('.select_star_button').on('click', function(e) {
using_select_star = true;
$(this)
.stop()
.animate({
width: SELECT_STAR_SIZE + GET_BIGGER_SIZE,height: SELECT_STAR_SIZE + GET_BIGGER_SIZE,
top: -GET_BIGGER_SIZE / 2,left: -GET_BIGGER_SIZE / 2
}, 80)
.animate({width: SELECT_STAR_SIZE,height: SELECT_STAR_SIZE,top: 0,left: 0}, 400);
});
// HatenaStarから引用スターボタンにクリックハンドラをたてる
Hatena.Star.AddButton.prototype.setupObservers = _.wrap(Hatena.Star.AddButton.prototype.setupObservers, function(func) {
func.call(this);
new Ten.Observer($select_star[0], 'onclick', this, 'beforeAddStar');
});
Hatena.Star.AddButton.prototype.beforeAddStar = function(e) {
if ($target_article.attr('data-uuid') === $(this.entry.entryNode).attr('data-uuid')) {
this.addStar(e);
}
};
},
// サードパーティクッキー送信されてないときmobile用のエントリページを新しいウィンドウで開く
initStarForThirdPartyCookiesDisabled: function(info) {
Hatena.Diary.Util.waitForResource(function() {
return Hatena.Star;
}, function() {
_.extend(Hatena.Star.AddButton.prototype, {
addStar: function() {
var self = this;
// uri: エントリのURI
// location: スターつけたあとのリダイレクト先
var url = 'http://s.hatena.ne.jp/star.add?' + $.param({
uri: self.entry.uri,
location: Hatena.Diary.data('admin-domain') + '/-/close'
});
var position = {
width: 500,
height: 200
};
position.left = Math.floor((screen.width - position.width) / 2);
position.top = Math.floor((screen.height - position.height) / 2);
var position_string = Hatena.Diary.Util.positionToPositionString(position);
var star_window = window.open(url, 'add_star', position_string);
// window閉じられたら読み込みなおす
Hatena.Diary.Util.waitForResource(function() {
return star_window.closed;
}, function() {
Hatena.Diary.Util.updateDynamicPieces([self.entry.entryNode.parentNode]);
});
},
// カラースターつけられないのでパレット開かなくする
showColorPallet: function() {
},
showColorPalletDelay: function() {
}
});
});
}
};
})(jQuery);
(function() {
Hatena.Star.EntryLoader();
Hatena.Diary.Star.initBigStar();
Hatena.Diary.Star.initSelectStar();
Hatena.Diary.Star.initStarNavigation();
Hatena.Diary.Star.initDeleteStar();
}());