// ==UserScript==
// @name Narrow_DynamicHeader
// @description 小説家になろうのヘッダーを動的に表示する
// @version 1
// @namespace phodra531
// @include http://ncode.syosetu.com/*
// @include http://novelcom.syosetu.com/*
// @include http://novel18.syosetu.com/*
// @include http://novelcom18.syosetu.com/*
// ==/UserScript==
(function (){
// ユーザーID
// 自分のIDを調べて書き換えてください。
// 通常版のユーザーIDは、ホーム画面の右上に以下のように表示されています。
// (ユーザー名)[ID:000000]でログイン中
// 18禁サイト用のユーザーIDは、Xホーム右側の
// 「評価をつけた作品一覧」のURLから得ることが出来ます。
var myUserID = 0;
var myXUserID = 0;
// 移動ボタンのスタイル
// 直下行の行頭の/を消すとコメント範囲が切り替わります。
//*
// 標準のスタイル
var moveButtonStyle = "\
.move_button{ \
color: #666 !important; \
background-color:#cdd !important; \
} \
.move_button:hover{ \
color: #fff !important; \
background-color:#9bc !important; \
} \
";
/*/
// Stylishテーマ「小説家になろうを見やすく」(kanachan氏 作)
// https://userstyles.org/styles/107606/theme
// に合わせたスタイル
var moveButtonStyle = "\
.move_button{ \
color: #ccc !important; \
background-color:rgba(48, 48, 48, 0.9) !important; \
} \
.move_button:hover{ \
color: #fff !important; \
background-color:#666 !important; \
} \
.move_button:link{ \
color:#ccc !important; \
} \
.move_button:visited{ \
color:#ccc !important; \
} \
";
//*/
// ※そのまま移動させると元の場所が埋め立てられるので、
// ※クローンを作成したのちにオリジナルは visibility = hidden で隠す。
// ヘッダー(オリジナル)
var $header_org = $('#novel_header');
// ヘッダー(クローン)
var $header_cln = $header_org.clone(true);
// 強制的に追従しない設定にする
$header_cln.css( "position", "absolute");
var title = $('.margin_r20').text();
var chapter, cpt_txt;
// 本文がある(作品各話)→情報ラベルを整形
var infoHeight = 0;
if( $('#novel_honbun').size() ){
var $info_org = $('.contents1');
// 情報ラベルにサブタイトルを埋め込む
chapter = $('.chapter_title');
if( chapter.size() ){
cpt_txt = chapter.text();
// 章分けがされている
// チャプタータイトルにサブタイトルを追加
chapter.append( " - " + $('.novel_subtitle').text() );
}else{
// 章分けなし
// サブタイトル用のエレメントを作成
var $subtitle = $('<p class="info_label"/>');
$subtitle.text( $('.novel_subtitle').text() );
$info_org.append($subtitle);
}
// 情報ラベルのクローン
var $info_cln = $info_org.clone(true);
$info_cln.css(
{ "margin": "0 auto",
"opacity": "0.9"
});
infoHeight = $info_org.outerHeight();
// ※$header_clnの兄弟だと設定が面倒なので子にする。
$header_cln.append($info_cln);
$info_org.css("visibility","hidden");
}
// ヘッダーの親になるボックス
var $header_box = $('<div/>');
$header_box.attr( "id", "header_box");
$header_box.css(
{ "position": "fixed",
"top": 0,
"width": "100%",
"height": $header_org.height() + infoHeight,
"zIndex": 1
});
$header_box.append($header_cln);
$('body').append($header_box);
// オリジナルを隠す
$header_org.css("visibility","hidden");
// ボタンのボックス
var $button_box = $('<div />');
$button_box.attr( "id", "button_box");
$button_box.css(
{
"pointerEvents": "none",
"position": "fixed",
"top": 0,
"width": "100%",
"height": $header_org.height(),
"zIndex": 2
});
$('body').append($button_box);
// 表示設定
var $navi_box = $('#novelnavi_right');
if( $navi_box.size() ){
$header_org.find('#novelnavi_right').remove();
$header_cln.find('#novelnavi_right').hide();
var $navi = $('<div />');
$navi.attr("id", "navi_button");
$navi.css(
{
"pointerEvents": "auto",
"position": "absolute",
"display": "block",
"margin": 0,
"top": 16,
"right": 3,
"height": 28,
"width": 10
}
);
var $menu_on = $('<div />');
var $menu_off = $('<div />');
var menuStyle = {
"position": "absolute",
"height": "100%",
"width": "100%"
};
$menu_on.css(menuStyle);
$menu_on.attr(
{
"id": "menu_open",
"class": "move_button"
}
);
$menu_on.click(
function(e){
$('#menu_on').click();
$menu_off.show();
$menu_on.hide();
}
);
$navi.append($menu_on);
$menu_off.css(menuStyle);
$menu_off.attr(
{
"id": "menu_close",
"class": "move_button"
}
);
$menu_off.click(
function(e){
$('#menu_off').click();
$menu_off.hide();
$menu_on.show();
}
);
$navi.append($menu_off);
$menu_off.hide();
$navi.append($('.novelview_navi'));
$button_box.append($navi);
$('#menu_off_2').click(
function(event){
$menu_off.click();
$button_box.fadeOut();
}
);
}
// 移動ボタン群
var $btnDef = $('#pageBottom');
var $moveButton = $('<a />');
$moveButton.attr("class", "move_button");
$moveButton.css(
{
"pointerEvents": "auto",
"position": "absolute",
"padding": "10px",
"margin": "4px",
"top": 0,
"bottom": 0
}
);
var mb_style = $('<style type="text/css" />');
mb_style.append(moveButtonStyle);
$('head').append(mb_style);
// 最下部へ移動
var $pbtm = $moveButton.clone();
$pbtm.attr(
{
"id": "pageBottom2",
"href": "#page_bottom"
}
);
$pbtm.text("↓");
$pbtm.css("right", "15px");
$pbtm.click(
function(e){
$('html,body').animate(
{scrollTop:$('body').height()},
500
);
return event.preventDefault();
});
$button_box.append($pbtm);
// 最上部へ移動
var $ptop = $moveButton.clone();
$ptop.attr(
{
"id": "pageTop2",
"href": "#page_top"
}
);
$ptop.text("↑");
$ptop.css("right", "55px");
$ptop.click(
function(e){
$('html,body').animate(
{scrollTop:0},
500
);
return event.preventDefault();
});
$button_box.append($ptop);
// 前ページ
var bn_p = $('a:contains("<<")');
if( bn_p.size() ){
var $preEp = $moveButton.clone()
$preEp.attr(
{
"id": "pagePrev",
"href": bn_p.attr("href")
}
);
$preEp.text("<");
$preEp.css("left", "15px");
$button_box.append($preEp);
}
// 次ページ
var bn_n = $('a:contains(">>")');
if( bn_n.size() ){
var $nxtEp = $moveButton.clone()
$nxtEp.attr(
{
"id": "pageNext",
"href": bn_n.attr("href")
}
);
$nxtEp.text(">");
$nxtEp.css("left", "55px");
$button_box.append($nxtEp);
}
$('#pageBottom').remove();
$('#pageTop').remove();
// AutoPagerizeのページ移動
if( $('#autopagerize_icon').size() ){
var $pnxt = $moveButton.clone()
$pnxt.attr(
{
"id": "pageNext",
"href": "#page_next"
}
);
$pnxt.text("▽");
$pnxt.css("right", "100px");
// ボタンが押された時
$pnxt.click(function(event){
var tgt_page = now_page+1;
var tgt_posY =
tgt_page>seams.length-1?
$('body').height(): seams[tgt_page]+1;
$('html,body').animate({scrollTop:tgt_posY}, 500);
return event.preventDefault();
});
$button_box.append($pnxt);
var $ppre = $moveButton.clone()
$ppre.attr(
{
"id": "pagePrev",
"href": "#page_prev"
}
);
$ppre.text("△");
$ppre.css("right", "140px");
// ボタンが押された時
$ppre.click(function(event){
var tgt_page = $(window).scrollTop()==seams[now_page]+1?
now_page-1: now_page;
if( tgt_page<0 ) tgt_page=0;
var tgt_posY = tgt_page>0? seams[tgt_page]+1: 0;
$('html,body').animate({scrollTop:tgt_posY}, 500);
return event.preventDefault();
});
$button_box.append($ppre);
}
// AutoPagerize対応
var seams = [0];
document.body.addEventListener('AutoPagerize_DOMNodeInserted',function(e){
var $page_info = $('.autopagerize_page_info:eq(-1)');
var num = parseInt( $page_info.children('a:first').text() );
if( num>1 && seams[num-1]==null ){
seams[num-1] = parseInt($page_info.eq(-1).offset().top)-$header_box.height();
}
}, false);
var now_page=0;
// 最下部で表示固定させるフラグ
var lock = 0;
// ウィンドウのスクロールが発生した時
$(window).scroll(function(event){
var scTop = $(window).scrollTop();
if( moving == 0 ){
SetHboxTop();
}
for( var i=seams.length-1; i>=0; i-- ){
if( scTop > seams[i] ){
if( $('#novel_honbun').size() ){
var sub = $('.novel_subtitle').eq(i).text();
document.title = title + " - " + sub;
if( chapter.size() ){
$('.chapter_title').text( cpt_txt + " - " + sub );
}else{
$('.info_label').text(sub);
}
}
if( lock ){
if( hoving==0 ){
Hbox_Close();
}
lock = 0;
}
now_page = i;
break;
}
}
if( $('#autopagerize_icon').size()<1 ){
var btmline = $('.novel_bn:eq(-1)');
if( btmline.size()<1 ) btmline = $('#footer');
if( btmline.offset().top < scTop + $(window).height() ){
Hbox_Open( true );
moving = 1;
lock = 1;
}
}
});
// $header_boxの状態
// 0:移動していない 1:出現中 -1:消失中 2:表示中
var moving = 0;
// $header_boxにマウスが乗っているか
var hoving = 0;
// 画面上部にポインターを近づける
document.onmousemove = function (e){
// InternetExplorer 用
if(!e) e = window.event;
if( e.clientY <= $header_org.height() ){
if( $(window).scrollTop() > 0 &&
moving < 1 && hoving == 0 ){
Hbox_Open();
}
$button_box.fadeIn("fast");
}else{
if( $(window).scrollTop() > 0 &&
moving != 0 && hoving == 0 && lock==0 ){
Hbox_Close();
}
if( $navi_box.size()? $('.novelview_navi').css("display")=="none": true ){
$button_box.fadeOut("fast");
}
}
};
// ヘッダーボックスに乗せる、外す
$header_box.hover(
function(){
Hbox_Open();
hoving = 1;
},
function(){
if( $(window).scrollTop()>0 ){
if( lock==0 ){
Hbox_Close();
}
}else{
moving = 0;
}
hoving = 0;
}
);
// ヘッダーを表示させる
var Hbox_Open = function(){
if( moving<=0 ){
// 消えている最中でもすぐにまた表示させる
$header_box.stop();
// ヘッダーを表示させるアニメ
$header_box.animate(
{"top": 0},
{ duration : "fast",
easing : "swing",
complete : function(){
moving = 2;
}
}
);
}
moving = 1;
}
// ヘッダーを隠す
var Hbox_Close = function(){
if( moving > 0 ){
// とりあえず画面のすぐ上まで持っていく
var target = -$header_box.height();
$header_box.stop();
// ヘッダーを非表示にするアニメ
$header_box.animate(
{"top": target},
{
duration : "normal",
easing : "linear",
complete : function(){
moving = 0;
},
progress : function(s){
var scTop = $(window).scrollTop();
if( parseInt($(this).css("top")) <= -scTop ){
$(this).stop();
$(this).css("top", -scTop);
moving = 0;
}
}
}
);
}
moving = -1;
}
// ロードした時、ヘッダーが見えない位置なら隠す
$(document).ready(function(){
SetHboxTop();
$button_box.hide();
moving=0;
});
// スクロール位置によってヘッダー位置を調整
var SetHboxTop = function(){
var scTop = $(window).scrollTop();
var hHgt = $header_box.height();
if( scTop <= hHgt ){
// 上端ならスクロール位置に合わせて絶対座標っぽく
$header_box.css( "top", -scTop );
}else if( $header_box.css("top") != -hHgt ){
// 上部の表示される位置でなければ、画面のすぐ上
$header_box.css( "top", -hHgt );
}
}
var href;
// ヘッダーに「目次」を追加
var $index_li = $('<li />');
var $index_node = $('<a />');
var index_href = $('#contents_main>a:first').attr("href");
if( index_href==null ){
// 携帯用のアドレスから生成
var handheld = $('link[media="handheld"]').attr("href");
index_href = handheld.match(/\/n\d+?\w+?\//);
}
$index_node.text("目次");
$index_node.attr("href", index_href);
$index_li.append($index_node);
$('#header_box li:contains("感想")').before($index_li);
var userid;
// ノベルフッターから作者コードを抜く
var user_href = $('.undernavi a:contains("マイページ")').attr("href");
if( user_href==null ){
// よくわからんけど作者コードっぽいので引っこ抜く
var atom = $('link[title="Atom"]').attr("href");
if( atom ){
userid = atom.match(/(\d+|x\d+[^\.]+?)/)[0] + "/";
user_href = "http://mypage.syosetu.com/" + userid;
}else{
userid=null;
user_href=null;
}
}else{
userid = user_href.match(/(\d+\/|x\d+.+)/)[0];
}
// ヘッダーに「作者マイページ」を追加
var $user_li = $('<li />');
var $user_node = $('<a />');
$user_node.text("作者");
if( userid ){
$user_node.attr("href", user_href);
}else{
$user_node.css("cssText", "color: rgba(200,200,200,0.3) !important;");
}
$user_li.append($user_node);
$('#header_box li:contains("感想")').before($user_li);
// ヘッダーに「メール」を追加
var $mail_li = $('<li />');
var $mail_node = $('<a />');
$mail_node.text("メール");
if( userid && userid[0]!="x" ){
$mail_node.attr("href", "http://syosetu.com/message/sendinput/to/" + userid);
}else{
$mail_node.css("cssText", "color: rgba(200,200,200,0.3) !important;");
}
$mail_li.append($mail_node);
$('#header_box li:contains("感想")').before($mail_li);
// N2コードを取得
var dlurl, n2code;
dlurl = $('.undernavi li:contains("ダウンロード")>a');
if( dlurl.size() ){
n2code = dlurl.attr("href").match(/\d+\//);
}
var bm_config = userid && userid[0]=="x"?
"http://syosetu.com/favnovelmain18/updateinput/xidfavncode/" + myXUserID:
"http://syosetu.com/favnovelmain/updateinput/useridfavncode/" + myUserID;
bm_config += "_" + n2code;
var dl_prm = {
'hankaku': "0",
'code': "utf-8",
'kaigyo': "crlf"
};
// テキストダウンロードボタンを追加
var $down_li = $('<li />');
var $down_node = $('<a />');
$down_node.text("DL");
if( n2code ){
var txtdl_url = userid[0]=="x"?
"http://novel18.syosetu.com/txtdownload/dlstart/ncode/":
"http://ncode.syosetu.com/txtdownload/dlstart/ncode/";
$down_node.attr("href",
txtdl_url + n2code +
"?hankaku=" + dl_prm.hankaku +
"&code=" + dl_prm.code +
"&kaigyo=" + dl_prm.kaigyo +
"&no=" + location.href.match( /\d+(?=\/$)/ ));
}else{
$down_node.css("cssText", "color: rgba(200,200,200,0.3) !important;");
}
$down_li.append($down_node);
$('#header_box li:contains("レビュー")').after($down_li);
// 「縦書で読む」を消す
$('#header_box li a.menu').parent().remove();
// 「ブックマークに追加」/「ブックマークを解除」を改変
var $blist = $('#header_box li.booklist>a');
if( $blist.size() ){
$blist.text("☆");
$blist.attr("alt", "ブックマークに追加");
}else{
$blist = $('#header_box li.booklist_now>a');
$blist.text("★");
$blist.attr(
{
"href": bm_config,
"alt": "ブックマーク設定"
}
);
}
$blist.css( "fontSize", "18px");
// しおりを挿む/しおり中ボタンの改変
var $bookmark = $('#header_box li.bookmark_now');
var $bmark_li = $('<li />');
var $bmark_img = $('<img>');
var $bmark_node = $('<a />');
if( $bookmark.size() ){
var $a = $bookmark.children("li>a");
$bmark_node.attr(
{
"href": $a.attr("href"),
"alt": "しおりを挿む"
}
);
$bmark_node.text("挿栞");
$bmark_img.attr("src", "/novelview/img/bookmarker_now.png");
}else{
$bookmark = $('#header_box .bookmark');
$bmark_node.attr(
{
"href": bm_config,
"alt": "ブックマーク設定"
}
);
$bmark_node.text("設定");
$bmark_img.attr("src", "/novelview/img/bookmarker.png");
}
if( $bookmark.size() ){
$bmark_node.attr("class", "bookmark2");
var bmark_style = $('<style type="text/css" />');
bmark_style.append("\
.bookmark2 { \
font-weight: normal !important; \
border-style: none !important; \
padding-left: 34px !important; \
} \
.bookmark2:hover{ \
font-weight: bold !important; \
background: none !important; \
} \
");
$('head').append(bmark_style);
$bmark_img.css(
{
"pointer-events": "none",
"position": "absolute",
"top": 0,
"bottom": 0,
"margin": "auto",
"padding-left": "12px"
}
);
$bmark_li.append($bmark_img);
$bmark_li.append($bmark_node);
$header_cln.children('ul').append($bmark_li);
$bookmark.remove();
}
// 感想ページ
if( location.href.indexOf("impression")>0){
// コメントフォームをコメント一覧の上に持っていく
var parent = document.getElementById('contents_main');
var target = document.getElementsByTagName('h1')[0];
var hyouka = document.getElementById('hyoukalan');
// 横幅いっぱいにする
hyouka.style.boxSizing = "border-box";
hyouka.style.width = "100%";
var textarea = document.getElementsByTagName('textarea');
for( var i=0; i<textarea.length; i++){
textarea[i].style.boxSizing = "border-box";
textarea[i].style.width = "100%";
}
parent.insertBefore( hyouka, target);
parent.insertBefore( document.createElement('hr'), target);
// "▽感想を書く"を消去
document.getElementsByClassName('input')[0].style.display = "none";
}
})();
// 小説メニューバーの振る舞いを変更
window.changeMenuBar = function(fixMenuBar){
// // novel_headerエレメントを取得
// var element = $('#novel_header');
// if(element.size() == 0) return false;
//
// if(isDefined(fixMenuBar)){
// gIsFixMenuBar = fixMenuBar ? true : false;
// }else{
// gIsFixMenuBar = parseInt(CookieManager.get('fix_menu_bar'), 10);
// if(isNaN(gIsFixMenuBar) || (gIsFixMenuBar != 0)){
// gIsFixMenuBar = true;
// }else{
// gIsFixMenuBar = false;
// }
// }
//
// if(gIsFixMenuBar){
// $('#novel_header,#novelnavi_right,#menu_on,#menu_off').css('position', 'fixed');
// $('input[name="fix_menu_bar"]').prop('checked', true);
// }else{
// $('#novel_header,#novelnavi_right,#menu_on,#menu_off').css('position', 'absolute');
// $('.novelview_navi').css('position', 'fixed');
// $('input[name="fix_menu_bar"]').removeProp('checked');
// }
//
// // クッキーに記憶
// fixMenuBar = gIsFixMenuBar ? 1 : 0;
// var expires = 86400 * 1000 * 90; // 90日
// CookieManager.set({key:'fix_menu_bar', value:fixMenuBar, domain:domain, path:'/', expires:expires});
}