「sandbox/js/2」の編集履歴(バックアップ)一覧はこちら
sandbox/js/2 - (2018/08/05 (日) 00:34:18) の1つ前との変更点
追加された行は緑色になります。
削除された行は赤色になります。
// JSモジュール ID付きコメント・投票型del機能 --------------------------------
#js(){{{{{
<script type="text/javascript">
/* --------------------------------------------------------
■導入の際のwiki構文(この並び以外は未対応)
#divclass(pcomex){{
#pcomment(reply,enableurl,new,20,【ページ名】/コメントログ)
&link_path(コメントログ){すべてのコメントを見る}
#tvote(time=3600,"delリスト[0]")
}}
----
■概要
対象ページと「コメントログ」ページの編集権限を「メンバーと管理者」以上にすると
1.@wikiの仕様でjavascriptなしでは書き込めない。
2.wiki編集でコメントログを改竄できない
3.wiki編集でこのjsのインクルードを取り外せない
4.3600秒の間同一IPから多重投票できない。それ以降もサイトデータを削除するまで投票できない。
となり荒らし従来より楽に排除できる。
■ToDo
tvoteをjsと同じページにしてwiki全体でdelリストを一元管理する
そうすることですべてのコメントを見るでも非表示できる。
ID作成から一定の期間の間連続投稿時間を制限することでシークレットモードでの投稿等に対応する
■問題点
5時間かければ一人で誰かのコメントを削除できてしまう。
またその場合delリストから除去するのが大変かもしれないので非表示されないIDコメント機能が必要かも
利用者が少ないページでは投票が機能しないかもしれない
ID単位で管理してる都合上、荒らしIDの荒らしじゃないコメントも通報x1のように表示されるので他の利用者が混乱するかもしれない
-----------------------------------------------------------*/
var PComEx = {
// 投票数閾値以上で非表示。閾値の半分以上で半透明。
Threshold: 5,
UserTokenKey: 'pcomment_id',
LastWrittenKey: 'pcomment_write',
CreationDateKey: 'pcomment_created',
GetStorage : function(key) { return sessionStorage[key]; },
SetStorage : function(key, val) { sessionStorage[key] = val; },
Keywords : [],
Counts : [],
HalfFunc : function(){},
FullFunc : function(){},
CreateToken : function() {
if (this.GetStorage(this.UserTokenKey))
return this.GetStorage(this.UserTokenKey);
var l = 10;
var c = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"+
"あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん"+
"アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン";
var cl= c.length;
var r = "";
for (var i = 0; i < l; i++) {
r += c[Math.floor(Math.random() * cl)];
}
this.SetStorage(this.UserTokenKey, r);
this.SetStorage(this.CreationDateKey, (new Date()).getTime());
return this.GetStorage(this.UserTokenKey);
},
Update : function() {
this.SetStorage(this.LastWrittenKey, (new Date()).getTime());
},
RegKeywords : function(target) {
var arr = $('.plugin_tvote td:nth-child(2)', target);
arr.splice(-2);
arr.splice(0, 1);
if (!arr || arr.length == 0)
return false;
var keywords = [];
var counts = [];
for (var i = 0; i < arr.length; i++) {
keywords.push(arr[i].innerText.trim());
counts.push(parseInt($(arr[i]).next().text().trim()) || 0);
}
this.Keywords = keywords;
this.Counts = counts;
return true;
},
ParseKey : function(text) {
var m = text.match(/\[ID:(.{10})\] [0-9-]+ [0-9:]+ (?:New!)?/);
return (m) ? m[1] : '';
},
ContainsKey : function(elem) {
var key = $(elem).text();
return this.Keywords.indexOf(key) != -1;
},
Validate : function(target) {
var key = this.ParseKey($(target).text());
var i;
if ((i = this.Keywords.indexOf(key)) != -1) {
if (this.Counts[i] >= this.Threshold) {
this.FullFunc(target);
}
else if (this.Counts[i] >= this.Threshold/2) {
this.HalfFunc(target);
}
return this.Counts[i];
}
return 0;
}
};
$(function() {
$('form.plugin_pcomment_form').on('submit', function() {
$('div#pcomexalert').remove();
var token = PComEx.CreateToken();
if (!token) {
$(this).insertAfter($('<div').css('color','red').attr('id', 'pcomexalert')
.text('IDが作成できませんでした。最新のブラウザを使用して下さい。by FGO Wiki'));
}
var newname = $(this).children('input[name="name"]').val() + ' [ID:' + token + ']';
$(this).children('input[name="name"]').val(newname);
PComEx.Update();
return false;
});
$('.pcomex').each(function() {
var form = $('.plugin_pcomment_form', this);
var voteform = $('.plugin_tvote > form', this);
if (!form || !voteform)
return true;
if (!PComEx.RegKeywords(this))
return true;
// tvoteを隠してチェックしたコメントを通報するボタン(=コメントIDでtvoteに投票)を作成
$('.plugin_tvote', this).hide();
$('.plugin_tvote', this).prev('p').append(' / ').append(
$('<a>', {'href':'#'}).text('選択したコメントを通報する').click(function(){
var check = $('.pcomex input[type="radio"]:checked');
// コメント以外が選択されている場合は無効
if (check.val() == "0") {
return false;
}
var mes = check.parent().text();
var btnname = 'new_tvote';
if (!window.confirm(mes+'を本当に通報しますか?'))
return false;
if (PComEx.ContainsKey(check.parent())) {
btnname = 'tvote_' + encodeURI(PComEx.ParseKey(mes));
} else {
voteform.find('input[name="new"]').val(PComEx.ParseKey(mes));
}
voteform.append($('<input />', {'type': 'hidden', 'name': btnname}).val('投票'));
voteform.submit();
//// tvoteをjsと同じページに置いてwiki全体で投票を一元管理する場合
//// ajaxで投票してリロードする必要がありそう(jsページに飛んでしまうため)
// $["ajax"]({
// url: voteform.attr('action'),
// type: voteform.attr('method'),
// data: voteform.serialize() + '&' + btnname + '=' + encodeURI('投票'),
// timeout: "5000",
// success: function(data) {
// history.go(0);
// }
// });
})
);
// NG処理
PComEx.HalfFunc = function(tgt) { $(tgt).css('opacity', '.5'); };
PComEx.FullFunc = function(tgt) { $(tgt).hide(); };
$('li', form).each(function() {
var count = PComEx.Validate(this);
if (count > 0) {
$(this).append($('<span>').css({
'background-color': '#c0c0c0',
'border-radius': '10px',
'color': 'white',
'display': 'inline-block',
'font-weight': 'bold',
'height': '14px',
'line-height': '14px',
'margin': '0px 3px',
'padding': '2px 8px',
'text-align': 'center',
'text-decoration':'none',
'vertical-align':'middle'
}).text('通報x'+count));
}
});
});
});
</script>
}}}}}
// ここからWIKI 構文 --------------------------------------
-試験的に作ったのでIDはブラウザに保存しない設定になってます。ブラウザかタブを閉じたら消えます。
-投票のその他にIDを入力するか一覧にあるIDに投票して下さい。[ID:abcde12345]ならabcde12345の部分を入力。
-同一IPからは60秒の間連続投票できません。
-投票数が5以上になったコメントは消えます。3以上なら半透明になります。
*コメントIDとdel機能テスト
#divclass(pcomex){{{
#pcomment(reply,enableurl,new,20,sandbox/js/2/コメントログ)
&link_path(コメントログ){すべてのコメントを見る}
#tvote(time=60,"delリスト[0]","たwケtレ3jjキy[5]","NhPゆヨクレわせか[1]")
}}}
*NG機能を無効化したコメント欄(ログは上と共通)
#pcomment(reply,enableurl,new,20,sandbox/js/2/コメントログ)
&link_path(コメントログ){すべてのコメントを見る}
#js(){{{{{
<script type="text/javascript">
$(function(){
/* 今後JSプラグインでstyleが使えなくなるのに備えてインラインcssでスタイル定義する */
var style = '<style type="text/css">'+
'.gallery {display:inline-block;width:600px;height:337px;margin:10px 10px 60px 0px;position:relative;}'+
'.active {display:inline-block;}'+
'.gallery img {display:none;}'+
'.gallery_list > img,.gallery_list > div {position:absolute;overflow:hidden;left:0;top:0;bottom:0;background-color:#C0C0C0;width:100%;height:100%;}'+
'.gallery_list > div {font-size:24px;margin:auto;height:80px;text-align:center;}'+
'/* btn */'+
'div.gallery_btn {position:absolute;right:0;top:calc(100% + 10px);}'+
'div.gallery_btn div {position:relative;cursor:pointer;padding:5px 10px;float:left;border:solid 1px #aaa;margin-left:-1px;background:#eee;background-image:linear-gradient(top, #F6F6F6, #ccc);background-image:-ms-linear-gradient(top, #F6F6F6, #ccc);background-image:-moz-linear-gradient(top, #F6F6F6, #ccc);background-image:-webkit-gradient(linear, left top, left bottom, from(#F6F6F6), to(#ccc));box-shadow:2px 2px 6px #ddd;-moz-box-shadow:2px 2px 6px #ddd;-webkit-box-shadow:2px 2px 6px #ddd;text-shadow:1px 1px 0px #fff;}'+
'div.gallery_btn div:first-child {border-radius:7px 0 0 7px;-webkit-border-radius:7px 0 0 7px;-moz-border-radius:7px 0 0 7px;}'+
'div.gallery_btn div:last-child {border-radius:0 7px 7px 0;-webkit-border-radius:0 7px 7px 0;-moz-border-radius:0 7px 7px 0;}'+
'div.gallery_btn div.checked {color:#fff;background:#C3C3C3;background-image:linear-gradient(top, #C3C3C3, #DBDBDB);background-image:-ms-linear-gradient(top, #C3C3C3, #DBDBDB);background-image:-moz-linear-gradient(top, #C3C3C3, #DBDBDB);background-image:-webkit-gradient(linear, left top, left bottom, from(#C3C3C3), to(#DBDBDB));text-shadow:0px 0px 0px #fff;}'+
'/* for SP page */' +
'@media screen and ( max-width:600px ) {.gallery {margin:10px 0px 60px 0px;width:100%;height:calc((100vw - 20px) / 600 * 337);}}'+
'</style>';
$(style).appendTo('head');
/* 初期値 */
var $width = 600; // 横幅
var $height = 337; // 高さ
var $btn_h = 10; // ボタン位置
var $fade_speed = 800; // フェード処理の早さ(ミリ秒)
var $img_max = 100; // 画像最大枚数
/* 読み込むタイミングをこのJSで管理する */
//$('.gallery img').each(function() {
// $(this).removeClass('lazy atwiki_plugin_ref')
// .attr('data-origin', $(this).attr('data-original'))
// .removeAttr('data-original');
//});
$('.gallery').each(function(){
/* 画像を移動 */
var div1 = $('<div>').addClass('gallery_list');
$(' img', this).each(function(i,img){
$(img).css({'z-index': $img_max - i}).attr('data-loaded', 'true');
$(div1).append($(img));
});
$(this).html($(div1));
$(' div.gallery_list img:first', this).addClass('active').show();
/* 画像の読み込みを開始する */
//$(' div.gallery_list img', this).each(function() {
// $(this).on('error', function() {
// $(this).insertBefore(
// $('<div>').css({
// 'width':$width,
// 'z-index':$(this).css('z-index')
// }).text('画像の読み込みに失敗しました'));
// $(this).remove();
// });
// /* スタイル&要素移動完了後に読み込みを開始する。(src指定)。読込み失敗時の表示を一応追加(コールバックより後に定義) */
// $(this).attr('src', $(this).attr('data-origin'));
//});
/* クリック判定用の透明なdiv作成 */
var prev = $('<div>').addClass('prev');
var next = $('<div>').addClass('next');
$(this).append($(prev)).append($(next));
$(' div.prev', this).css({
'z-index': $img_max + 1,
'width':'50%',
'height':'100%',
'position':'absolute',
'top':0,
'left':0,
});
$(' div.next', this).css({
'z-index': $img_max + 1,
'width':'50%',
'height':'100%',
'position':'absolute',
'top':0,
'right':0,
});
/* ボタン作成 */
var imgNum = $('img', div1).length;
var div2 = $('<div>').addClass('gallery_btn');
for(var i=1; i<=imgNum; i++){
var btn = $('<div>').text(i);
if(i==1){$(btn).addClass('checked');}
$(div2).append($(btn));
}
$(this).append($(div2));
});
/* ひとつ前にフェードする処理 */
$('.gallery div.prev').click(function(){
var aaa = $(this).parent();
var active = $(' div.gallery_list img.active', aaa);
var size = $(' div.gallery_list img', aaa).length;
var index = 1 + $(' div.gallery_list img', aaa).index(active);
if(index == 1){var num = size;}
else{var num = -1 + index;}
gallery_click(aaa, num);
});
/* ひとつ次にフェードする処理 */
$('.gallery div.next').click(function(){
var aaa = $(this).parent();
var active = $(' div.gallery_list img.active', aaa);
var size = $(' div.gallery_list img', aaa).length;
var index = 1 + $(' div.gallery_list img', aaa).index(active);
if(index == size){var num = 1;}
else{var num = 1 + index;}
gallery_click(aaa, num);
});
/* ボタン処理 */
$('div.gallery_btn div').click(function() {
var aaa = $(this).parent().parent();
var num = $(this).text();
if(!($(this).hasClass('checked'))){
gallery_click(aaa, num);
}
});
function gallery_click(aaa, num){
/* アニメーション終了 */
$(' div.gallery_list img', aaa).finish();
/* フェード処理 */
var active = $(' div.gallery_list img.active', aaa);
var next = $(' div.gallery_list img:nth-of-type('+num+')', aaa);
active.fadeOut($fade_speed).removeClass('active');
next.fadeIn($fade_speed).addClass('active');
/* ボタン処理 */
var ccc = $(' div.gallery_btn div:nth-of-type('+num+')', aaa);
$(ccc).parent().each(function() {
$('div', this).removeClass('checked');
});
$(ccc).addClass('checked');
}
});
</script>
}}}}}
#divclass(fgowiki-clearfix){{{
#divclass(srv_menu){
#contents(fromhere=true)}
#divclass(gallery){{
&ref(215-a1.png,スカサハ=スカディ)
&ref(215-b2.png,スカサハ=スカディ)
&ref(215-c3.png,スカサハ=スカディ)
&ref(215-d3.png,スカサハ=スカディ)
}}
}}}
Comments policy & Terms of Use
・ネタバレ自粛期間中はシナリオや真名のネタバレは禁止です!
ネタバレ自粛期間の文字列挿入箇所
・コメントの内容に準じたコメントフォームを利用しましょう!
※報告を扇動したり異なるフォームへの投稿が散見した場合、coや規制対応することがあります
・現在、異なる板へのガチャ報告に利用者が定型文で誘導を行えるようルール改定するか議論中です。
時間がありましたら賛成/反対だけで構わないのでレスの協力お願いします
閉じる