二次創作同人サイト&てがろぐで使ったjsとcss公開

サーバーを共同で借りてる友人に頼まれたので置いておきます。

全部Oathであるべきところがouthになってます。
 使ったり参考にするときは直してください。

TOPページで使っているやつ

見たいカテゴリを選択してクッキーに保存するやつ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
const outh_list = document.querySelectorAll(".outh input[type=checkbox]") // div.outhの下にあるcheckbox型inputを取得

var allCookies = document.cookie; // cookie全部取得
var cookieAge = 60 * 60 * 24 * 365; // cookieを1年間有効にする
var is_firstLoad = true;

{
var outhDict = {};
outh_list.forEach(node => {
outhDict[node.id] = node;
})
if (allCookies != false) {
var cookies = cookieGet("outhList"); // cookieを取得
if (cookies != false) {
cookies.forEach(cookie => {
var node = outhDict[cookie]; // 既に許可しているものに
node.click(); // チェックをつける
})

}
}
is_firstLoad = false
};

function cookieGet(searchKey) { // cookie取得して分割して配列にして返すやつ
var returnValue = false
allCookies.split(";").forEach(cookie => {
if (cookie.split("=")[0] == searchKey) {
returnValue = cookie.split("=")[1].split(",");
}
})
return returnValue
}

function cookieSet() { // cookie取得するやつ。
var checkCookieList = [];
outh_list.forEach(node => {
if (node.checked) {
checkCookieList.push(node.id);
}
});
if (checkCookieList.length > 0) {
document.cookie = "outhList=" + checkCookieList + ";path=/;domain=ドメイン;max-age=" + cookieAge + ";";
};
};

function allCheck() { // 全部許可にチェックいれると全部にチェックがはいるやつ。
if (is_firstLoad == false) {
outh_list.forEach(node => {
node.click();
});

}
}

てがろぐで使っているやつ

汎用的なjs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
const categories = ["dream", "cross_over", "oriuma", "nsfw", "cp", "fanart"] // カテゴリ一覧

const authCookie = cookieGet("outhList"); // TOPページで取得したクッキーを取得
const posts = document.querySelectorAll("div.onelogbox"); // ポスト一覧を取得
const postInput = document.querySelector("textarea.tegalogpost"); // 入力欄を取得

{
if (authCookie.length > 0) {
firstLoad(); // 多分いらない。
visiblePost(); // TOPページで許可したものだけ表示するやつ
nsfwImg(); // NSFWイメージ関連の設定するやつ。
imgToVideo(); // てがろぐにアップロードしたmp4を見れるようにするやつ。
if (postInput != null) { // 入力欄の高さを自動調整するやつ。
postInput.addEventListener('keyup', function () {
window.setTimeout(tweetInput, 10)
}, false);

}
if (isMode("mode-gallery") == false) { // てがろぐのギャラリーモードじゃなかった時
postMultiImage(); // ツイッター風の画像表示設定の土台作るやつ。
imageGroup(); // ポストごとに画像設定するやつ。
setTimeout(function () {
const lightbox = GLightbox({
loop: true,
plyr: {
config: {
loop: {
active: true
},
autoplay: true
}
}
});
}, 100)
}
} else {
window.location.href = "TOPページに戻す"
}
}

// てがろぐのモードを取得するやつ
function isMode(mode) {
return document.querySelector("body").classList.contains(mode);
}

// クッキーを取得するやつ
function cookieGet(searchKey) {
let returnValue = false;
document.cookie.split(";").forEach(cookie => { // 全てのクッキーを分割
if (cookie.split("=")[0].trim() == searchKey) { // クッキーのキーの前後の空白を削除し、探しているキーと同じなら
returnValue = cookie.split("=")[1]; // 値を取得して
returnValue = returnValue.split(","); // 配列にして返す。
}
})
return returnValue
}

// 月日分割線消すやつ。多分いらない。
function firstLoad() {
document.querySelectorAll(".dateseparator").forEach(node => {
node.remove();
})
}

// TOPページで許可したコンテンツ以外を削除
function visiblePost() {
posts.forEach(post => {
const categories = post.querySelectorAll("span.categories a")
categories.forEach(cat => {
cat.classList.forEach(catClass => {
if (catClass.indexOf("cat-") === 0) {
let catName = catClass.replace("cat-", "");
if (authCookie.includes(catName) == false) {
post.remove();
}
}

})
})
// NSFW許可してない場合NSFWな画像を含むものを削除
if (post.querySelector("a.nsfw")) {
if (authCookie.includes("nsfw") == false) {
post.remove();
}
}
})
}


// ツイッター風の画像表示にしたかった時に作ったやつ。
function postMultiImage() {
posts.forEach(post => {
const onelogBody = post.querySelector(".onelogbody .comment"); // ポストの内容を取得
let imgLinks = []; // 画像ノードリスト
for (let i = 0; i < onelogBody.children.length; i++) {
let child = onelogBody.children[i]; // ポストの子ノードを取得
if (child.classList.length < 1) { // 画像じゃなかった場合
if (imgLinks.length > 0) { // 画像子ノードが続いていた場合は画像囲むやつに突っ込む。
imageWrap(imgLinks);
imgLinks = []
}

} else if (child.classList.contains("imagelink")) { // 画像だった場合は画像ノードリストに突っ込む
imgLinks.push(child)
} else { // 画像じゃなかった場合
if (imgLinks.length > 0) { // 画像子ノードが続いていた場合は画像囲むやつに突っ込む。
imageWrap(imgLinks);
imgLinks = []
}
}
}
// 画像ノードリストが残っていた場合囲むやつに突っ込む
if (imgLinks.length > 0) {
imageWrap(imgLinks);
}
})
}

// 画像に枚数のクラスを付与するやつ
function imageWrap(imgs) {
if (imgs.length < 1) {
return false
}
if (imgs.length == 1) { // 1枚の場合はone-img
imgs[0].classList.add("one-img")
} else if (imgs.length == 2) {
imgs.forEach(img => { // 2枚の場合はtwo-img
img.classList.add("two-img")
})
} else {
imgs.forEach(img => { // 3枚以上の場合はmulti-img
img.classList.add("multi-img")
})
}
}

// 画像ごとにライトボックスのギャラリーを設定する。Glightbox前提
function imageGroup() {
for (i = 0; i < posts.length; i++) {
let imgs = posts[i].querySelectorAll(".onelogbody .comment a.glightbox");
imgs.forEach(img => {
img.dataset.gallery = "gallery_" + String(i);
})
}
}

// NSFWカテゴリーに入っているまたはNSFWの画像がある場合に使う。
function nsfwImg() {
posts.forEach(post => {
const postCat = post.querySelectorAll("span.categories a");
postCat.forEach(cat => {
if (cat.classList.contains("cat-nsfw")) { // NSFWカテゴリーのポストの画像はすべてNSFW指定する。
post.querySelectorAll("a.imagelink").forEach(img => {
img.classList.add("nsfw");
})
}
if (isMode("onelog")) { // NSFWの場合はOGP画像をNSFW忠告画像に置き換える。
document.querySelector('meta[property="og:image"]').setAttribute("content", "NSFW忠告画像のパス")
}
})
post.querySelectorAll("a.nsfw").forEach(nsfwLink => { // nsfwって書いてあるだけのspanタグを追加。
let nsfwtxt = document.createElement("span");
nsfwtxt.innerText = "NSFW";
nsfwLink.insertAdjacentHTML("beforeend", "<span>NSFW</span>")
})
})
}

// textInputの高さを自動調整するやつ。
// あらかじめcssでline-heightを調整しないとだめ。remがおすすめ。

let beforeRow = 0;

function tweetInput() {
const fontSize = Math.floor(window.getComputedStyle(postInput).getPropertyValue('font-size').replace("px", "")) // フォントサイズ取得
const rowMaxCharacter = Math.floor(postInput.clientWidth / fontSize) + 1; // 一行の長さ取得。計算式はInputの大きさ÷フォントサイズ。
let rowCount = 0;
const rowMatch = new RegExp(".{" + rowMaxCharacter + "}", "g"); // 分割する文字数を定義。
postInput.value.split("\n").forEach(txt => { // 改行ごとに分割
let row = txt.match(rowMatch) // 1行を1行の文字数で分割
if (row != null) { // 分割されていたら
rowCount += row.length + 1 // 分割されていた分+1行をカウント
} else { // 分割されなかった場合
rowCount += 1 // 1行をプラス。
}
})
rowCount += 1 // 最終行に1行プラス
if (beforeRow != rowCount) { // 前回呼び出された時と違ったら続ける
beforeRow = rowCount
rowCount = rowCount * 1.2 // line-heightで設定したremの高さでかける
postInput.style.height = rowCount + "rem"
}
}

// mp4動画をvideoタグに変換するやつ。
// 動作が不安定なので注意。
function imgToVideo() {
posts.forEach(post => {
const imgLinks = post.querySelectorAll("a.imagelink");
imgLinks.forEach(imgLink => {
const img = imgLink.querySelector("img");
const src = img.getAttribute("src");
if (src.endsWith(".mp4")) {
img.remove();
let container = document.createElement("div");
container.classList.add("video-over");
let playIcon = document.createElement("span"); // ここから先はプレイアイコン追加するやつ
playIcon.classList.add("material-symbols-outlined")
playIcon.innerText = "play_circle";
container.appendChild(playIcon); // ここまでプレイアイコン追加するやつ
imgLink.appendChild(container);
let video = document.createElement("video");
video.setAttribute("src", src);
video.classList.add("embeddedimage");
video.setAttribute("loading", "lazy");
video.loop = true;
imgLink.appendChild(video);
imgLink.classList.add("video-container");
}
})
})
}

ギャラリーモードで画像拡大ではなくポストページに飛ばすやつ。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const galleryPosts = document.querySelectorAll(".onelogmain")

{
imageLinkToPost();
}

function imageLinkToPost() {
galleryPosts.forEach(post => {
const glightbox = post.querySelector(".glightbox");
const postURL = post.querySelector(".arrowlink").getAttribute("href");
glightbox.setAttribute("href", postURL);
glightbox.classList.remove("glightbox")
})
}

上記のjsに対応した部分だけ抜き出したcss

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

/* テキストエリアの設定 */
textarea {
width: 100%;
}

textarea.tegalogpost {
height: 100%;
min-height: 3rem;
line-height: 1.2rem;
transition: height 0.05s;
}

/* 画像関連の設定 */

a.imagelink {
display: inline-block;
}

a.one-img {
width: 100%;
max-height: 300px;
margin: auto;
display: block;
}

a.one-img img,
a.one-img video {
display: block;
margin: auto;
}

a.two-img,
a.multi-img {
width: calc(50% - 0.6rem);
margin: 0.2rem;
}

a.two-img img,
a.multi-img img {
width: 100%;
}

a.multi-img img {
aspect-ratio: 4/3;
height: auto;
margin-bottom: 6px;

}

/* NSFW画像を非表示 */

a.imagelink.nsfw img {
display: none;
}

/* 代わりにNSFWとテキストで表示する */

a.imagelink.nsfw {
background-color: #1F2020;
padding: 4rem;
border-radius: 5px;
border: 3px var(--border-color) solid;
}

a.imagelink.nsfw span {
display: block;
font-size: 2rem;
margin: auto;
text-align: center;
}