(仮)Wizball の詳細ページを保存用に、ちょっといじる Fork

    @@ -29,7 +29,7 @@ const comments = []; let page = 1; while (true) { - const url = `${url_base}?page=${page}&size=50&sort=LATEST`; + const url = url_base + "?page=" + page + "&size=50&sort=LATEST"; const resp = await fetch(url); const json = await resp.json(); if (json.length > 0) {
    @@ -44,13 +44,30 @@ comments.forEach(c => { let img; if (c.author.image) { - img = `<img src="https://obs.line-scdn.net/${c.author.image.hash}/s150" class="user_20" title="${c.author.nickname}">`; + img = [ + '<img src="https://obs.line-scdn.net/', + c.author.image.hash', + '/s150" class="user_20" title="', + c.author.nickname, + '">' + ].join(""); } else { - img = `<img src="" class="user_20" title="${c.author.nickname}">`; + img = '<img src="" class="user_20" title="' + c.author.nickname + '">'; } const item = Object.assign(d_.createElement("li"), { className: "comment_item", - innerHTML: `<div class="comment_item_inner"><div class="profile_img comment_icon">${img}</div><a href="/users/${c.author.id}" class="user_id">${c.author.nickname}</a> <a href="${orig_url}" class="comment_txt type_space">${c.text}</a></div>`, + innerHTML: [ + '<div class="comment_item_inner"><div class="profile_img comment_icon">', + img, + '</div><a href="/users/', + c.author.id, + '" class="user_id">', + c.author.nickname, + '</a> <a href="', + orig_url, + '" class="comment_txt type_space">', + c.text, + '</a></div>', }); list[i].appendChild(item); });
    @@ -61,14 +78,14 @@ } async function load_q(qid) { - const resp = await fetch(`/apis/v1/questions/${qid}`); + const resp = await fetch("/apis/v1/questions/" + qid); const json = await resp.json(); return json; } async function load_a(qid) { const map = {}; for (let p = 1 ; p <= 300 ; ++p) { - const resp = await fetch(`/apis/v1/questions/${qid}/answers?page=${p}&size=50&sort=POPULAR`); + const resp = await fetch("/apis/v1/questions/" + qid + "/answers?page=" + p + "&size=50&sort=POPULAR"); const json = await resp.json(); if (json.length == 0) { break;
    @@ -82,13 +99,13 @@ async function load_v(a) { let ub; if (a.questionId) { // answer - ub = `/apis/v1/questions/${a.questionId}/answers/${a.id}/voters?size=50&sort=LATEST&`; + ub = "/apis/v1/questions/" + a.questionId + "/answers/" + a.id + "/voters?size=50&sort=LATEST&"; } else { // question - ub = `/apis/v1/questions/${a.id}/votes?size=50&sort=LATEST&`; + ub = "/apis/v1/questions/" + a.id + "/votes?size=50&sort=LATEST&"; } const list = []; for (let p = 1 ; p <= 300 ; ++p) { - const resp = await fetch(ub + `page=${p}`); + const resp = await fetch(ub + "page=" + p); const json = await resp.json(); if (json.length == 0) { break;
    @@ -119,9 +136,9 @@ li.className = "voter_item profile_img"; // li.innerHTML = v.author.nickname + ", "; if (v.author.image) { - li.innerHTML = `<img src="https://obs.line-scdn.net/${v.author.image.hash}/s150" class="user_20" title="${v.author.nickname}">`; + li.innerHTML = '<img src="https://obs.line-scdn.net/' + v.author.image.hash + '/s150" class="user_20" title="' + v.author.nickname + '">'; } else { - li.innerHTML = `<img src="" class="user_20" title="${v.author.nickname}">`; + li.innerHTML = '<img src="" class="user_20" title="' + v.author.nickname + '">'; } }); }
    @@ -157,49 +174,49 @@ console.log(more_btn) if (more_btn) { d_.body.appendChild(Object.assign(d_.createElement("style"), { - innerHTML: ` - body: { - max-width: 640px; - } - .wrap.home_end .content .qna_area_inner .comment_area .comment_item_inner .comment_txt { - max-height: none; - } - .comment_item_inner .comment_icon, .voter_list .voter_item { - width: 20px; - height: 20px; - margin-right: 0.5ex; - } - .comment_item_inner .comment_icon { - float: left; - } - .user_20 { - border-radius: 50%; - width: 100%; - } - .wrap.home_end .content .question_logo { - font-size: inherit; - color: inherit; - font-size: 15px; - color: #959aa5; - } - .wrap.home_end .content .qna_area_inner .comment_area .comment .comment_value { - padding-top: 0; - padding-bottom: 10px; - } - .qna_area.question .vote_area { - padding: 14px 22px 0; - } - .vote_value { - padding-bottom: 10px; - } - .vote_area { - color: #959aa5; - font-size: 15px; - } - .voter_item { - display: inline-block; - } - `, + innerHTML: [ + 'body: {', + ' max-width: 640px;', + '}', + '.wrap.home_end .content .qna_area_inner .comment_area .comment_item_inner .comment_txt {', + ' max-height: none;', + '}', + '.comment_item_inner .comment_icon, .voter_list .voter_item {', + ' width: 20px;', + ' height: 20px;', + ' margin-right: 0.5ex;', + '}', + '.comment_item_inner .comment_icon {', + ' float: left;', + '}', + '.user_20 {', + ' border-radius: 50%;', + ' width: 100%;', + '}', + '.wrap.home_end .content .question_logo {', + ' font-size: inherit;', + ' color: inherit;', + ' font-size: 15px;', + ' color: #959aa5;', + '}', + '.wrap.home_end .content .qna_area_inner .comment_area .comment .comment_value {', + ' padding-top: 0;', + ' padding-bottom: 10px;', + '}', + '.qna_area.question .vote_area {', + ' padding: 14px 22px 0;', + '}', + '.vote_value {', + ' padding-bottom: 10px;', + '}', + '.vote_area {', + ' color: #959aa5;', + ' font-size: 15px;', + '}', + '.voter_item {', + ' display: inline-block;', + '}', + ].join(""), })); let n = 0; const answer_list = d_.querySelector(".answer_list");
  • /*
     * @title (未完成)Wizball の詳細ページを保存用に、ちょっといじる
     * @description (未完成)Wizball の詳細ページを保存用に、ちょっといじる
     * @include https://m.wizball.io/questions/*
     * @license MIT License http://opensource.org/licenses/MIT
     * @javascript_url *
     */
    /*
    	全ページ読み込む
    
    	create 2019-07-03
    */
    (async _ => {
    	const d_ = document;
    	if (location.hostname != "m.wizball.io") {
    		alert("Please use at m.wizball.io !");
    		return;
    	}
    	async function display_comments() {
    		console.log("!!! load comments !!!");
    		const list = d_.querySelectorAll(".comment_list");
    		for (let i = 0 ; i < list.length ; ++i) {
    			const first_item = list[i].querySelector(".comment_txt");
    			if (! first_item) {		// 質問はコメントがなくても UL 要素がある
    				continue;
    			}
    			const orig_url = first_item.href;
    			const url_base = orig_url.replace(/questions/, "apis/v1/questions");
    			const comments = [];
    			let page = 1;
    			while (true) {
    				const url = url_base + "?page=" + page + "&size=50&sort=LATEST";
    				const resp = await fetch(url);
    				const json = await resp.json();
    				if (json.length > 0) {
    					comments.push(... json);
    					page += 1;
    				} else {
    					break;
    				}
    			}
    			console.log(comments);
    			list[i].innerHTML = "";
    			comments.forEach(c => {
    				let img;
    				if (c.author.image) {
    					img = [
    						'<img src="https://obs.line-scdn.net/',
    						c.author.image.hash',
    						'/s150" class="user_20" title="',
    						c.author.nickname,
    						'">'
    					].join("");
    				} else {
    					img = '<img src="" class="user_20" title="' + c.author.nickname + '">';
    				}
    				const item = Object.assign(d_.createElement("li"), {
    					className: "comment_item",
    					innerHTML: [
    						'<div class="comment_item_inner"><div class="profile_img comment_icon">',
    						img,
    						'</div><a href="/users/',
    						c.author.id,
    						'" class="user_id">',
    						c.author.nickname,
    						'</a> <a href="',
    						orig_url,
    						'" class="comment_txt type_space">',
    						c.text,
    						'</a></div>',
    				});
    				list[i].appendChild(item);
    			});
    			const comment_value = list[i].parentNode.querySelector(".comment_list ~ .comment_value");
    			console.log(comment_value);
    			list[i].parentNode.insertBefore(comment_value, list[i]);
    		}
    	}
    
    	async function load_q(qid) {
    		const resp = await fetch("/apis/v1/questions/" + qid);
    		const json = await resp.json();
    		return json;
    	}
    	async function load_a(qid) {
    		const map = {};
    		for (let p = 1 ; p <= 300 ; ++p) {
    			const resp = await fetch("/apis/v1/questions/" + qid + "/answers?page=" + p + "&size=50&sort=POPULAR");
    			const json = await resp.json();
    			if (json.length == 0) {
    				break;
    			}
    			json.forEach(a => {
    				map[a.id] = a;
    			});
    		}
    		return map;
    	}
    	async function load_v(a) {
    		let ub;
    		if (a.questionId) {		// answer
    			ub = "/apis/v1/questions/" + a.questionId + "/answers/" + a.id + "/voters?size=50&sort=LATEST&";
    		} else { // question
    			ub = "/apis/v1/questions/" + a.id + "/votes?size=50&sort=LATEST&";
    		}
    		const list = [];
    		for (let p = 1 ; p <= 300 ; ++p) {
    			const resp = await fetch(ub + "page=" + p);
    			const json = await resp.json();
    			if (json.length == 0) {
    				break;
    			}
    			list.push(... json);
    		}
    		return list;
    	}
    
    	function modify_time(e, q) {
    		const qt = e.querySelector(".user_info_detail.date");
    		qt.innerHTML = (new Date(q.createdAt)).toLocaleString();
    	}
    
    	async function display_voters(e, a) {
    		const eopt = e.querySelector(".qna_option_area");
    		const ea = d_.createElement("div");
    		ea.className = "vote_area";
    		eopt.parentNode.insertBefore(ea, eopt);
    //		eopt.parentNode.insertBefore(eul, eopt);
    		const v = await load_v(a);
    		ea.innerHTML = '<div class="vote_value">Vote : ' + v.length + '</div>';
    		const eul = d_.createElement("ul");
    		ea.appendChild(eul);
    		eul.className = "voter_list";
    		v.forEach(v => {
    			const li = eul.appendChild(d_.createElement("li"));
    			li.className = "voter_item profile_img";
    //			li.innerHTML = v.author.nickname + ", ";
    			if (v.author.image) {
    				li.innerHTML = '<img src="https://obs.line-scdn.net/' + v.author.image.hash + '/s150" class="user_20" title="' + v.author.nickname + '">';
    			} else {
    				li.innerHTML = '<img src="" class="user_20" title="' + v.author.nickname + '">';
    			}
    		});
    	}
    
    	async function modify_data() {
    		const m = /\/questions\/(\d+)/.exec(location.href);
    		const qid = m[1];
    		const q = await load_q(qid);
    		const qe = d_.querySelector(".qna_area.question");
    		modify_time(qe, q);
    //		const qv = await load_v(q);
    		await display_voters(qe, q);
    
    		const a = await load_a(qid);
    		const ae = d_.querySelectorAll(".qna_area.answer .answer_item");
    		console.log(ae);
    		for (let i = 0 ; i < ae.length ; ++i) {
    			const bc = ae[i].querySelector(".btn_comment");
    			const m = /answers\/(\d+)/.exec(bc.href);
    			const aid = m[1];
    			modify_time(ae[i], a[aid]);
    //			const av = await load_v(a);
    			await display_voters(ae[i], a[aid]);
    		}
    	}
    
    	async function modify_window() {
    		await display_comments();
    		await modify_data();
    	}
    
    	const more_btn = d_.querySelector(".qna_area.answer .btn_more_answer");
    	console.log(more_btn)
    	if (more_btn) {
    		d_.body.appendChild(Object.assign(d_.createElement("style"), {
    			innerHTML: [
    'body: {',
    '	max-width: 640px;',
    '}',
    '.wrap.home_end .content .qna_area_inner .comment_area .comment_item_inner .comment_txt {',
    '	max-height: none;',
    '}',
    '.comment_item_inner .comment_icon, .voter_list .voter_item {',
    '	width: 20px;',
    '	height: 20px;',
    '	margin-right: 0.5ex;',
    '}',
    '.comment_item_inner .comment_icon {',
    '	float: left;',
    '}',
    '.user_20 {',
    '	border-radius: 50%;',
    '	width: 100%;',
    '}',
    '.wrap.home_end .content .question_logo {',
    '	font-size: inherit;',
    '	color: inherit;',
    '	font-size: 15px;',
    '	color: #959aa5;',
    '}',
    '.wrap.home_end .content .qna_area_inner .comment_area .comment .comment_value {',
    '	padding-top: 0;',
    '	padding-bottom: 10px;',
    '}',
    '.qna_area.question .vote_area {',
    '	padding: 14px 22px 0;',
    '}',
    '.vote_value {',
    '	padding-bottom: 10px;',
    '}',
    '.vote_area {',
    '	color: #959aa5;',
    '	font-size: 15px;',
    '}',
    '.voter_item {',
    '	display: inline-block;',
    '}',
    		].join(""),
    		}));
    		let n = 0;
    		const answer_list = d_.querySelector(".answer_list");
    		// https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
    		const MutationObserver = window.MutationObserver || window.WebkitMutationObserver;
    		const observer = new MutationObserver(async function (records) {
    			n += 1;
    			console.log(n);
    			if (more_btn.style.display != "none") {
    				more_btn.click();
    				if (n > 10) {
    					observer.disconnect();
    				}
    			} else {
    				await modify_window();
    			}
    		});
    		observer.observe(answer_list, { childList: true, /* subtree: true */ });
    
    		if (more_btn.style.display != "none") {
    			more_btn.click();
    		} else {
    			await modify_window();
    		}
    	}
    })();
    
  • Permalink
    このページへの個別リンクです。
    RAW
    書かれたコードへの直接のリンクです。
    Packed
    文字列が圧縮された書かれたコードへのリンクです。
    Userscript
    Greasemonkey 等で利用する場合の .user.js へのリンクです。
    Loader
    @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
    Metadata
    コード中にコメントで @xxx と書かれたメタデータの JSON です。