<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ja">
	<id>https://tensura-wiki.info/w/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-pcomment.js</id>
	<title>MediaWiki:Gadget-pcomment.js - 版の履歴</title>
	<link rel="self" type="application/atom+xml" href="https://tensura-wiki.info/w/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-pcomment.js"/>
	<link rel="alternate" type="text/html" href="https://tensura-wiki.info/w/index.php?title=MediaWiki:Gadget-pcomment.js&amp;action=history"/>
	<updated>2026-05-12T06:44:33Z</updated>
	<subtitle>このウィキのこのページに関する変更履歴</subtitle>
	<generator>MediaWiki 1.39.3</generator>
	<entry>
		<id>https://tensura-wiki.info/w/index.php?title=MediaWiki:Gadget-pcomment.js&amp;diff=1943&amp;oldid=prev</id>
		<title>ド馬: ページの作成:「/***********************************************  * PukiWiki pcommentプラグイン風コメントボックス  *   * by pneuma01  ***********************************************/ var i18n = {     summary_edit_with_pcomment: &quot;PCommentでコメント&quot;,     send_button_caption: &quot;コメントを追加&quot; };  $(function () {      const intersectionObserver = new IntersectionObserver(function (entries) {         entries.forEach(function (entry) {             //画面内…」</title>
		<link rel="alternate" type="text/html" href="https://tensura-wiki.info/w/index.php?title=MediaWiki:Gadget-pcomment.js&amp;diff=1943&amp;oldid=prev"/>
		<updated>2024-08-06T13:08:07Z</updated>

		<summary type="html">&lt;p&gt;ページの作成:「&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;**********************************************  * PukiWiki pcommentプラグイン風コメントボックス  *   * by pneuma01  **********************************************: &lt;/span&gt; var i18n = {     summary_edit_with_pcomment: &amp;quot;PCommentでコメント&amp;quot;,     send_button_caption: &amp;quot;コメントを追加&amp;quot; };  $(function () {      const intersectionObserver = new IntersectionObserver(function (entries) {         entries.forEach(function (entry) {             //画面内…」&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新規ページ&lt;/b&gt;&lt;/p&gt;&lt;div&gt;/***********************************************&lt;br /&gt;
 * PukiWiki pcommentプラグイン風コメントボックス&lt;br /&gt;
 * &lt;br /&gt;
 * by pneuma01&lt;br /&gt;
 ***********************************************/&lt;br /&gt;
var i18n = {&lt;br /&gt;
    summary_edit_with_pcomment: &amp;quot;PCommentでコメント&amp;quot;,&lt;br /&gt;
    send_button_caption: &amp;quot;コメントを追加&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
$(function () {&lt;br /&gt;
&lt;br /&gt;
    const intersectionObserver = new IntersectionObserver(function (entries) {&lt;br /&gt;
        entries.forEach(function (entry) {&lt;br /&gt;
            //画面内に入った&lt;br /&gt;
            if (entry.isIntersecting) {&lt;br /&gt;
&lt;br /&gt;
                //コメント読み込み&lt;br /&gt;
                loadComment(entry);&lt;br /&gt;
&lt;br /&gt;
                //監視対象の解除&lt;br /&gt;
                intersectionObserver.unobserve(entry.target);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    //監視開始&lt;br /&gt;
    var observe_target = document.querySelectorAll(&amp;quot;.pcomment-widget&amp;quot;);&lt;br /&gt;
    observe_target.forEach(function (element) {&lt;br /&gt;
        intersectionObserver.observe(element);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
//コメント読み込み&lt;br /&gt;
function loadComment(entry) {&lt;br /&gt;
    &lt;br /&gt;
    //トークページ名を取得(存在しない場合でも)&lt;br /&gt;
    var targetPage = entry.target.getAttribute(&amp;quot;data-page&amp;quot;) || mw.config.get('wgPageName');&lt;br /&gt;
    var talkPage = new mw.Title( targetPage ).getTalkPage().getPrefixedText();&lt;br /&gt;
&lt;br /&gt;
    //トークページのwikitextを取得&lt;br /&gt;
    $.when(new mw.Api().get({&lt;br /&gt;
            action: 'query',&lt;br /&gt;
            format: 'json',&lt;br /&gt;
            titles: talkPage,&lt;br /&gt;
            prop: 'revisions',&lt;br /&gt;
            meta: 'tokens',&lt;br /&gt;
            type: 'csrf',&lt;br /&gt;
            rvprop: 'content|ids',&lt;br /&gt;
            indexpageids: 1,&lt;br /&gt;
            formatversion: '2',&lt;br /&gt;
            rvslots: 'main'&lt;br /&gt;
        }),&lt;br /&gt;
        mw.user.getGroups()&lt;br /&gt;
    ).done(function (result, userGroups) {&lt;br /&gt;
        result = result[0].query;&lt;br /&gt;
        var page = result.pages[0];&lt;br /&gt;
&lt;br /&gt;
        //衝突防止のためにリビジョンを記録&lt;br /&gt;
        if(page.revisions){&lt;br /&gt;
            entry.target.dataset.revid = page.revisions[0].revid;&lt;br /&gt;
        }&lt;br /&gt;
        entry.target.dataset.csrftoken = result.tokens.csrftoken;&lt;br /&gt;
&lt;br /&gt;
        //非ログインユーザーにもコメントできるか？&lt;br /&gt;
        var GuestUser = false;&lt;br /&gt;
        if(entry.target.getAttribute(&amp;quot;data-deny-guest&amp;quot;)){&lt;br /&gt;
            GuestUser = (userGroups.indexOf(&amp;quot;user&amp;quot;) == -1);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var wikitext = page.revisions &amp;amp;&amp;amp; page.revisions[0].slots.main.content || &amp;quot;&amp;quot;;&lt;br /&gt;
        var lines = wikitext.split(/\r\n|\n|\r/);&lt;br /&gt;
        var sections = [];&lt;br /&gt;
        var lists = {};&lt;br /&gt;
        var lists_count = 0;&lt;br /&gt;
        var tree = {children: [], level: 0, text: &amp;quot;root&amp;quot;};&lt;br /&gt;
        var curtree = tree;&lt;br /&gt;
        var last_lvl = 1;&lt;br /&gt;
        for (var i = 0; i &amp;lt; lines.length; i++) {&lt;br /&gt;
            //セクションの位置を取得&lt;br /&gt;
            if (lines[i].match(/^=+[^=]+=+$/)) {&lt;br /&gt;
                sections.push({ index: sections.length, line: i, title: lines[i].match(/^=+([^=]+)=+$/)[1].trim() });&lt;br /&gt;
                continue;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            //*(&amp;lt;li&amp;gt;)の行番号を取得&lt;br /&gt;
            if (lines[i].match(/^\*+/)) {&lt;br /&gt;
                lists[i] = { index: lists_count++, line: i, section: sections.length - 1};&lt;br /&gt;
&lt;br /&gt;
                var m = lines[i].match(/^(\*+)/);&lt;br /&gt;
                var astarisk = m[1];&lt;br /&gt;
                &lt;br /&gt;
                //ツリーの始まりを記憶&lt;br /&gt;
                if(astarisk.length == 1){&lt;br /&gt;
                    lists[i].toplevel = true;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                //ツリーを記憶&lt;br /&gt;
                {&lt;br /&gt;
                    var treedata = {line: i, level: astarisk.length, children: []};&lt;br /&gt;
&lt;br /&gt;
                    if(astarisk.length &amp;lt; last_lvl){&lt;br /&gt;
                        do{&lt;br /&gt;
                            curtree = curtree.parent;&lt;br /&gt;
                        } while (curtree &amp;amp;&amp;amp; curtree.level &amp;gt;= astarisk.length);&lt;br /&gt;
                        treedata.parent = curtree;&lt;br /&gt;
                    }&lt;br /&gt;
&lt;br /&gt;
                    if(astarisk.length &amp;gt; last_lvl){&lt;br /&gt;
                        curtree = curtree.children[curtree.children.length-1];&lt;br /&gt;
                    }&lt;br /&gt;
&lt;br /&gt;
                    treedata.parent = curtree;&lt;br /&gt;
&lt;br /&gt;
                    curtree.children.push( treedata );&lt;br /&gt;
                    &lt;br /&gt;
                    lists[i].tree = treedata;&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                last_lvl = astarisk.length;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //セクションがまだ存在しないならデフォルト&lt;br /&gt;
        if (sections.length == 0) {&lt;br /&gt;
            sections.push(&lt;br /&gt;
                { index: 0, line: -1, title: &amp;quot;PComment&amp;quot; }&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //引数を取得&lt;br /&gt;
        var sectionName = entry.target.getAttribute(&amp;quot;data-section&amp;quot;) || sections[sections.length - 1].title;&lt;br /&gt;
        var sectionId = sections.length - 1;&lt;br /&gt;
        var max = entry.target.getAttribute(&amp;quot;data-max&amp;quot;) || 10;&lt;br /&gt;
&lt;br /&gt;
        //引数の名前からセクションを特定する&lt;br /&gt;
        for (i = 0; i &amp;lt; sections.length; i++) {&lt;br /&gt;
            if (sections[i].title == sectionName) {&lt;br /&gt;
                sectionId = sections[i].index;&lt;br /&gt;
                break;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //次のセクションの先頭行を取得(セクション範囲識別に使用)&lt;br /&gt;
        var nextSectionLine = lines.length;&lt;br /&gt;
        if (sectionId &amp;gt; -1 &amp;amp;&amp;amp; sections.length - 1 &amp;gt; sectionId) {&lt;br /&gt;
            nextSectionLine = sections[sectionId + 1].line;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //コメントツリーの最後の行を取得するための関数&lt;br /&gt;
        function getLast(obj){&lt;br /&gt;
            if(obj.children.length){&lt;br /&gt;
                return getLast(obj.children[obj.children.length -1]);&lt;br /&gt;
            }&lt;br /&gt;
            return obj.line;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //wikitextを指定レス分で抽出する&lt;br /&gt;
        var new_lines = [];&lt;br /&gt;
        var count = 1;&lt;br /&gt;
        for (i = lines.length - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
            //関係ないセクションはスキップ&lt;br /&gt;
            if (i &amp;lt;= sections[sectionId].line || i &amp;gt;= nextSectionLine) {&lt;br /&gt;
                continue;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var line = lines[i];&lt;br /&gt;
&lt;br /&gt;
            if (!GuestUser &amp;amp;&amp;amp; lists[i]) {&lt;br /&gt;
                //リスト構文の先頭にラジオボタン(予定地)を挿入する&lt;br /&gt;
                var m = line.match(/^(\*+)([^\*].+)$/);&lt;br /&gt;
                var astarisk = m[1];&lt;br /&gt;
                var comment = m[2];&lt;br /&gt;
&lt;br /&gt;
                //最後のレスの行を取得&lt;br /&gt;
                var lastlinenum = i;&lt;br /&gt;
                if(lists[i].tree){&lt;br /&gt;
                    lastlinenum = getLast(lists[i].tree);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                line = astarisk + &amp;quot;&amp;lt;span class='pcomment-radio' data-group='sec&amp;quot; + lists[i].section + &amp;quot;' data-line='&amp;quot; + lastlinenum + &amp;quot;' data-level='&amp;quot; + astarisk + &amp;quot;'&amp;gt;&amp;lt;/span&amp;gt;&amp;quot; + comment;&lt;br /&gt;
&lt;br /&gt;
                if (lists[i].toplevel) {&lt;br /&gt;
                    count++;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            new_lines.push(line);&lt;br /&gt;
&lt;br /&gt;
            //指定のレス数に達したのでループを抜ける&lt;br /&gt;
            if (count &amp;gt; max) break;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //抜き取った行をwikitextに変換する&lt;br /&gt;
        wikitext = new_lines.reverse().join(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        // APIでWikitextをパースする&lt;br /&gt;
        new mw.Api().parse(wikitext).done(function (data) {&lt;br /&gt;
            //htmlを生成&lt;br /&gt;
            var $html = $(data).removeClass('noscript');&lt;br /&gt;
&lt;br /&gt;
            //OOUIのラジオボタンを生成して挿入&lt;br /&gt;
            $html.find(&amp;quot;span.pcomment-radio&amp;quot;).each(function () {&lt;br /&gt;
&lt;br /&gt;
                var val = {&lt;br /&gt;
                    line: $(this).attr('data-line'),&lt;br /&gt;
                    level: $(this).attr('data-level')&lt;br /&gt;
                };&lt;br /&gt;
&lt;br /&gt;
                $(this).replaceWith(&lt;br /&gt;
                    new OO.ui.RadioInputWidget({ name: $(this).attr('data-group'), value: JSON.stringify(val) }).$element&lt;br /&gt;
                );&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            //テキストボックスと送信ボタンを追加&lt;br /&gt;
            if(!GuestUser){&lt;br /&gt;
                var $text = new OO.ui.TextInputWidget();&lt;br /&gt;
                var $button = new OO.ui.ButtonWidget({ label: i18n.send_button_caption, flags: [&amp;quot;primary&amp;quot;, &amp;quot;progressive&amp;quot;] });&lt;br /&gt;
                $html.append(&lt;br /&gt;
                    $(&amp;quot;&amp;lt;div&amp;gt;&amp;quot;, { class: &amp;quot;pcomment-toolbar&amp;quot;, &amp;quot;data-section-end&amp;quot;: nextSectionLine}).append(&lt;br /&gt;
                        $text.$element.addClass('pcomment-text').css(&amp;quot;display&amp;quot;, &amp;quot;inline-block&amp;quot;),&lt;br /&gt;
                        $button.$element.on('click', function(){&lt;br /&gt;
&lt;br /&gt;
                            var selected = $(this).parents(&amp;quot;.pcomment-widget&amp;quot;).find(&amp;quot;input:checked&amp;quot;);&lt;br /&gt;
                            var section_end = $(this).parents(&amp;quot;.pcomment-toolbar&amp;quot;).attr(&amp;quot;data-section-end&amp;quot;);&lt;br /&gt;
                            var text = $(this).parent().find('.pcomment-text input').val();&lt;br /&gt;
&lt;br /&gt;
                            if(text.trim().length == 0) {&lt;br /&gt;
                                //空送信を防止する&lt;br /&gt;
                                return;&lt;br /&gt;
                            }&lt;br /&gt;
                            $text.setDisabled(true);&lt;br /&gt;
                            $button.setDisabled(true);&lt;br /&gt;
&lt;br /&gt;
                            $(this).parents(&amp;quot;.pcomment-toolbar&amp;quot;).prepend(&lt;br /&gt;
                                new OO.ui.ProgressBarWidget({ progress:false }).$element.addClass(&amp;quot;oo-ui-pendingElement-pending&amp;quot;)&lt;br /&gt;
                            );&lt;br /&gt;
&lt;br /&gt;
                            var comment = {&lt;br /&gt;
                                targetPage: talkPage,&lt;br /&gt;
                                section_end: section_end,&lt;br /&gt;
                                wikitext: &amp;quot;* &amp;quot; + text + &amp;quot;--~&amp;quot; + &amp;quot;~&amp;quot; + &amp;quot;~&amp;quot; + &amp;quot;~&amp;quot;,&lt;br /&gt;
                                entry: entry&lt;br /&gt;
                            };&lt;br /&gt;
&lt;br /&gt;
                            if(selected.length){&lt;br /&gt;
                                var opt = JSON.parse(selected.val());&lt;br /&gt;
                                comment.line = opt.line;&lt;br /&gt;
                                comment.level = opt.level;&lt;br /&gt;
                            }&lt;br /&gt;
&lt;br /&gt;
                            postComment(comment);&lt;br /&gt;
                        })&lt;br /&gt;
                    )&lt;br /&gt;
                );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // できたHTMLの差し込み&lt;br /&gt;
            $(entry.target).html(&amp;quot;&amp;quot;).append($html);&lt;br /&gt;
&lt;br /&gt;
            // 他のスクリプトへ読み込み完了通知&lt;br /&gt;
            mw.hook('wikipage.content').fire($(entry.target));&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    });&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function getRevIndex(revisions, revid){&lt;br /&gt;
    for(var i=0; i&amp;lt;revisions.length; i++) {&lt;br /&gt;
        if(revisions[i].revid == revid){&lt;br /&gt;
            return i;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return -1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//コメント追加用&lt;br /&gt;
function postComment(option) {&lt;br /&gt;
&lt;br /&gt;
    var query = {&lt;br /&gt;
        action: 'query',&lt;br /&gt;
        format: 'json',&lt;br /&gt;
        prop: 'revisions',&lt;br /&gt;
        titles: option.targetPage,&lt;br /&gt;
        rvprop: 'content|ids',&lt;br /&gt;
        rvslots: 'main',&lt;br /&gt;
        indexpageids: 1,&lt;br /&gt;
        formatversion: '2'&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    var oldrevid = option.entry.target.dataset.revid;&lt;br /&gt;
&lt;br /&gt;
    //元の版で取得&lt;br /&gt;
    if(oldrevid) {&lt;br /&gt;
        query.rvendid = oldrevid;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //最後のページ内容を取得&lt;br /&gt;
    new mw.Api().get(query).done(function (result) {&lt;br /&gt;
        result = result.query;&lt;br /&gt;
        var page = result.pages[0];&lt;br /&gt;
        var oldText = &amp;quot;&amp;quot;;&lt;br /&gt;
        var currevid = page.revisions &amp;amp;&amp;amp; page.revisions[0].revid;&lt;br /&gt;
        var linenum = option.line &amp;amp;&amp;amp; option.line*1;&lt;br /&gt;
        var section_end = option.section_end &amp;amp;&amp;amp; option.section_end*1;&lt;br /&gt;
&lt;br /&gt;
        if(page.revisions){&lt;br /&gt;
            oldText = page.revisions[0].slots.main.content;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //行で分割する&lt;br /&gt;
        var new_lines = oldText.split(/\r\n|\n|\r/);&lt;br /&gt;
&lt;br /&gt;
        //リビジョンが更新されていた場合、該当する行番号へ更新&lt;br /&gt;
        if(currevid != oldrevid) {&lt;br /&gt;
            var index = getRevIndex(oldrevid);&lt;br /&gt;
            oldText = page.revisions[ index ].slots.main.content;&lt;br /&gt;
            var old_lines = oldText.split(/\r\n|\n|\r/);&lt;br /&gt;
            var target_line;&lt;br /&gt;
&lt;br /&gt;
            if(option.line) {&lt;br /&gt;
                target_line = old_lines[ linenum ];&lt;br /&gt;
                linenum = new_lines.indexOf( target_line );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            if(option.section_end){&lt;br /&gt;
                if(section_end &amp;lt; old_lines.length - 2){&lt;br /&gt;
                    target_line = old_lines[ section_end + 1 ];&lt;br /&gt;
                    section_end = new_lines.indexOf( target_line ) - 1;&lt;br /&gt;
                } else {&lt;br /&gt;
                    section_end = old_lines.length - 1;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if(linenum){&lt;br /&gt;
            //レスする行が指定されているならコメントを挿入&lt;br /&gt;
            new_lines.splice(linenum + 1, 0, option.level + option.wikitext);&lt;br /&gt;
        } else if(section_end){&lt;br /&gt;
            //レス行未指定&lt;br /&gt;
            new_lines.splice(section_end, 0, option.wikitext);&lt;br /&gt;
        } else {&lt;br /&gt;
            new_lines.push(option.wikitext);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var newText = new_lines.join(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        //あたらしい内容を送信する&lt;br /&gt;
        new mw.Api().post({&lt;br /&gt;
            action: 'edit',&lt;br /&gt;
            title: option.targetPage,&lt;br /&gt;
            text: newText,&lt;br /&gt;
            summary: i18n.summary_edit_with_pcomment,&lt;br /&gt;
            token: option.entry.target.dataset.csrftoken&lt;br /&gt;
        }).always(function () {&lt;br /&gt;
            loadComment(option.entry);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>ド馬</name></author>
	</entry>
</feed>