@kangsicj/dcinsideenhancer 1.3.3 → 1.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +671 -229
- package/README.en.md +54 -133
- package/README.md +54 -133
- package/dist/DCInsideEnhancer.meta.js +1 -1
- package/dist/DCInsideEnhancer.user.js +115 -207
- package/package.json +5 -5
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// @name DCInside Enhancer
|
|
3
3
|
// @name:ko 디시 인핸서
|
|
4
4
|
// @namespace https://github.com/kangsicj/DCInsideEnhancer
|
|
5
|
-
// @version 1.3.
|
|
5
|
+
// @version 1.3.5
|
|
6
6
|
// @description DCInside filter & enhancer — mobile & PC. Block users/words/heads/notices/images & GIFs across posts, infinite list, zoom viewer, theme sync, encrypted multi-device sync (no account, no tracking).
|
|
7
7
|
// @description:ko 디시인사이드 차단·편의 기능 (모바일·PC) - 유저·단어(제목/본문)·말머리·공지 차단, 같은/비슷한 이미지·움짤 모든 글 차단, 디시콘 제거, 차단 미디어 데이터 절약, 목록 자동 보충·무한 스크롤·뒤로 가기 위치 복원, 스크랩, 이미지 확대뷰 개선, 야간모드 자동 연동, 암호화 기기 간 동기화 (계정 없음·추적 없음)
|
|
8
8
|
// @author kangsicj
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
window.__dcInsideEnhancer = true;
|
|
38
38
|
window.__dcRefinery = true;
|
|
39
39
|
|
|
40
|
-
const SCRIPT_VERSION = '1.3.
|
|
40
|
+
const SCRIPT_VERSION = '1.3.5';
|
|
41
41
|
const PROJECT_URL = 'https://github.com/kangsicj/DCInsideEnhancer';
|
|
42
42
|
const DONATE_URL = 'https://fairy.hada.io/@kangsicj';
|
|
43
43
|
const DONATE_URL_BMC = 'https://buymeacoffee.com/kangsicj';
|
|
@@ -187,7 +187,6 @@
|
|
|
187
187
|
hideCommentAds: true,
|
|
188
188
|
hideCommentFab: true,
|
|
189
189
|
mobileRecentBar: true,
|
|
190
|
-
mobileRecentStrip: true,
|
|
191
190
|
hideSilbeAlarm: true,
|
|
192
191
|
alarmBubble: true,
|
|
193
192
|
alarmKeepPolling: true,
|
|
@@ -2032,17 +2031,16 @@
|
|
|
2032
2031
|
#dc-recent-bar {
|
|
2033
2032
|
display: flex;
|
|
2034
2033
|
align-items: center;
|
|
2035
|
-
gap:
|
|
2036
|
-
height:
|
|
2034
|
+
gap: var(--dc-rb-gap, 30px);
|
|
2035
|
+
height: 40px;
|
|
2037
2036
|
margin: 0;
|
|
2038
|
-
padding: 0
|
|
2037
|
+
padding: 0 var(--dc-rb-pad, 14px);
|
|
2039
2038
|
overflow-x: auto;
|
|
2040
2039
|
overflow-y: hidden;
|
|
2041
2040
|
-webkit-overflow-scrolling: touch;
|
|
2042
2041
|
scrollbar-width: none;
|
|
2043
2042
|
overscroll-behavior-x: contain;
|
|
2044
2043
|
background: var(--dc-rb-bg, #3b4890);
|
|
2045
|
-
border-bottom: 1px solid rgba(255,255,255,.12);
|
|
2046
2044
|
box-sizing: border-box;
|
|
2047
2045
|
}
|
|
2048
2046
|
#dc-recent-bar::-webkit-scrollbar { display: none; }
|
|
@@ -2050,74 +2048,23 @@
|
|
|
2050
2048
|
flex: 0 0 auto;
|
|
2051
2049
|
display: inline-flex;
|
|
2052
2050
|
align-items: center;
|
|
2053
|
-
gap:
|
|
2054
|
-
max-width:
|
|
2055
|
-
height:
|
|
2056
|
-
padding: 0
|
|
2051
|
+
gap: 3px;
|
|
2052
|
+
max-width: 60vw;
|
|
2053
|
+
height: 40px;
|
|
2054
|
+
padding: 0;
|
|
2057
2055
|
overflow: hidden;
|
|
2058
|
-
color:
|
|
2059
|
-
font-
|
|
2060
|
-
font-
|
|
2061
|
-
|
|
2056
|
+
color: var(--dc-rb-color, #fff);
|
|
2057
|
+
font-family: var(--dc-rb-family, inherit);
|
|
2058
|
+
font-size: var(--dc-rb-size, 16px);
|
|
2059
|
+
font-weight: var(--dc-rb-weight, 700);
|
|
2060
|
+
letter-spacing: var(--dc-rb-spacing, normal);
|
|
2062
2061
|
text-decoration: none;
|
|
2063
2062
|
text-overflow: ellipsis;
|
|
2064
2063
|
white-space: nowrap;
|
|
2064
|
+
opacity: .9;
|
|
2065
2065
|
}
|
|
2066
|
-
#dc-recent-bar .dc-rb-item
|
|
2067
|
-
#dc-recent-bar .dc-rb-
|
|
2068
|
-
#dc-recent-bar .dc-rb-kind { font-size: 11px; opacity: .8; }
|
|
2069
|
-
|
|
2070
|
-
html.dc-recent-strip-on #lately_pop.dc-strip-lately #swiper-lately,
|
|
2071
|
-
html.dc-recent-strip-on #lately_pop.dc-strip-lately #lately_paging1 { display: none !important; }
|
|
2072
|
-
.dc-recent-strip {
|
|
2073
|
-
display: flex;
|
|
2074
|
-
gap: 8px;
|
|
2075
|
-
padding: 12px 12px 14px;
|
|
2076
|
-
overflow-x: auto;
|
|
2077
|
-
overflow-y: hidden;
|
|
2078
|
-
-webkit-overflow-scrolling: touch;
|
|
2079
|
-
scroll-snap-type: x proximity;
|
|
2080
|
-
scrollbar-width: none;
|
|
2081
|
-
overscroll-behavior-x: contain;
|
|
2082
|
-
}
|
|
2083
|
-
.dc-recent-strip::-webkit-scrollbar { display: none; }
|
|
2084
|
-
.dc-recent-strip[hidden] { display: none !important; }
|
|
2085
|
-
.dc-recent-strip .dc-rs-chip {
|
|
2086
|
-
flex: 0 0 auto;
|
|
2087
|
-
display: inline-flex;
|
|
2088
|
-
align-items: center;
|
|
2089
|
-
gap: 4px;
|
|
2090
|
-
max-width: 60vw;
|
|
2091
|
-
height: 36px;
|
|
2092
|
-
padding: 0 4px 0 14px;
|
|
2093
|
-
border: 1px solid var(--dc-border);
|
|
2094
|
-
border-radius: 999px;
|
|
2095
|
-
background: var(--dc-surface-2);
|
|
2096
|
-
color: var(--dc-text);
|
|
2097
|
-
font-size: 14px;
|
|
2098
|
-
font-weight: 600;
|
|
2099
|
-
text-decoration: none;
|
|
2100
|
-
white-space: nowrap;
|
|
2101
|
-
scroll-snap-align: start;
|
|
2102
|
-
}
|
|
2103
|
-
.dc-recent-strip .dc-rs-chip.here { border-color: var(--dc-accent-ink); color: var(--dc-accent-ink); background: var(--dc-accent-soft); }
|
|
2104
|
-
.dc-recent-strip .dc-rs-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
|
2105
|
-
.dc-recent-strip .dc-rs-kind { color: var(--dc-text-dim); font-size: 13px; }
|
|
2106
|
-
.dc-recent-strip .dc-rs-del {
|
|
2107
|
-
flex: 0 0 auto;
|
|
2108
|
-
width: 28px;
|
|
2109
|
-
height: 28px;
|
|
2110
|
-
margin: 0;
|
|
2111
|
-
padding: 0;
|
|
2112
|
-
border: none;
|
|
2113
|
-
border-radius: 50%;
|
|
2114
|
-
background: transparent;
|
|
2115
|
-
color: var(--dc-text-dim);
|
|
2116
|
-
font-size: 18px;
|
|
2117
|
-
line-height: 28px;
|
|
2118
|
-
}
|
|
2119
|
-
.dc-recent-strip .dc-rs-pin,
|
|
2120
|
-
.dc-recent-strip .dc-rs-empty { flex: 0 0 auto; align-self: center; padding: 0 6px; color: var(--dc-text-dim); font-size: 12px; white-space: nowrap; }
|
|
2066
|
+
#dc-recent-bar .dc-rb-item.on { color: var(--dc-rb-on, #ffe10a); opacity: 1; }
|
|
2067
|
+
#dc-recent-bar .dc-rb-kind { font-size: .75em; font-weight: 400; opacity: .85; }
|
|
2121
2068
|
|
|
2122
2069
|
.dc-key-cursor { outline: 2px solid var(--dc-accent-ink) !important; outline-offset: -2px; background: var(--dc-accent-soft) !important; }
|
|
2123
2070
|
|
|
@@ -3362,6 +3309,13 @@
|
|
|
3362
3309
|
saveSettings();
|
|
3363
3310
|
}
|
|
3364
3311
|
|
|
3312
|
+
const staleSettings = Object.keys(settings).filter(key => !(key in DEFAULT_SETTINGS) && key !== 'settingsRev');
|
|
3313
|
+
|
|
3314
|
+
if (staleSettings.length) {
|
|
3315
|
+
staleSettings.forEach(key => delete settings[key]);
|
|
3316
|
+
saveSettings();
|
|
3317
|
+
}
|
|
3318
|
+
|
|
3365
3319
|
OBSOLETE_STORAGE.forEach(key => {
|
|
3366
3320
|
try {
|
|
3367
3321
|
localStorage.removeItem(key);
|
|
@@ -9961,6 +9915,17 @@
|
|
|
9961
9915
|
area.querySelectorAll('.dc-row').forEach(row => {
|
|
9962
9916
|
row.hidden = !matchesFilter(row.textContent);
|
|
9963
9917
|
});
|
|
9918
|
+
|
|
9919
|
+
area.querySelectorAll('.dc-setting-row').forEach(row => {
|
|
9920
|
+
row.hidden = !matchesFilter(row.textContent);
|
|
9921
|
+
});
|
|
9922
|
+
area.querySelectorAll('.dc-settings-group[data-dc-group]').forEach(box => {
|
|
9923
|
+
const empty = !!blockFilter.trim() && ![...box.querySelectorAll('.dc-setting-row')].some(row => !row.hidden);
|
|
9924
|
+
|
|
9925
|
+
area.querySelectorAll(`[data-dc-group="${box.dataset.dcGroup}"]`).forEach(el => {
|
|
9926
|
+
el.hidden = empty;
|
|
9927
|
+
});
|
|
9928
|
+
});
|
|
9964
9929
|
};
|
|
9965
9930
|
|
|
9966
9931
|
const matchesFilter = text => !blockFilter || String(text).toLowerCase().includes(blockFilter.trim().toLowerCase());
|
|
@@ -10309,6 +10274,7 @@
|
|
|
10309
10274
|
{ key: 'alarm', title: '🔔 알림', intro: '디시 알림(댓글·답글·힛갤 등)을 보기 쉽게 바꿉니다. 알림 내용은 사이트가 받은 것을 그대로 씁니다.' },
|
|
10310
10275
|
{ key: 'dccon', title: '😶 디시콘', intro: '디시 자체 이모티콘을 다룹니다.' },
|
|
10311
10276
|
{ key: 'list', title: '📜 목록 보기', intro: '게시판 목록을 넘겨 보는 방식을 정합니다.' },
|
|
10277
|
+
{ key: 'handy', title: '✨ 편의 기능', intro: '최근 방문 · 글 미리보기 · 단축키 · 스크랩처럼 사이트를 더 편하게 쓰는 기능입니다.' },
|
|
10312
10278
|
{ key: 'media', title: '🖼 이미지·영상', intro: '본문 이미지 차단과 확대 보기를 다룹니다.' },
|
|
10313
10279
|
{ key: 'data', title: '📶 데이터 절약', intro: '모바일 데이터를 아끼는 기능입니다.' },
|
|
10314
10280
|
{ key: 'theme', title: '🌓 화면 테마', intro: '주간/야간 모드를 기기 설정에 맞춥니다.' },
|
|
@@ -10455,21 +10421,13 @@
|
|
|
10455
10421
|
refresh: 'root'
|
|
10456
10422
|
},
|
|
10457
10423
|
{
|
|
10458
|
-
group: '
|
|
10424
|
+
group: 'handy',
|
|
10459
10425
|
key: 'mobileRecentBar',
|
|
10460
10426
|
name: '메뉴 위에 최근 방문 갤러리 늘 보이기 (모바일)',
|
|
10461
10427
|
on: '검색창과 [갤러리 · 마이너갤 · …] 메뉴 사이에 최근 방문 갤러리를 한 줄로 보여 줍니다. 옆으로 밀어 보고, 누르면 바로 이동합니다. 지금 갤러리는 노란색입니다.',
|
|
10462
10428
|
off: '[최근 방문]을 눌러야 보입니다.',
|
|
10463
10429
|
refresh: 'root'
|
|
10464
10430
|
},
|
|
10465
|
-
{
|
|
10466
|
-
group: 'clean',
|
|
10467
|
-
key: 'mobileRecentStrip',
|
|
10468
|
-
name: "'최근 방문'을 한 줄로 밀어 보기 (모바일)",
|
|
10469
|
-
on: '위쪽 [최근 방문]을 누르면 넓은 표 대신 갤러리가 순서대로 한 줄에 나오고, 옆으로 밀어 봅니다. 고정한 순서를 그대로 따릅니다.',
|
|
10470
|
-
off: '사이트 기본 표(2줄 × 4칸, 넘겨 보기)로 보여 줍니다.',
|
|
10471
|
-
refresh: 'root'
|
|
10472
|
-
},
|
|
10473
10431
|
{
|
|
10474
10432
|
group: 'clean',
|
|
10475
10433
|
key: 'hideAdSlots',
|
|
@@ -10545,7 +10503,7 @@
|
|
|
10545
10503
|
refresh: 'all'
|
|
10546
10504
|
},
|
|
10547
10505
|
{
|
|
10548
|
-
group: '
|
|
10506
|
+
group: 'handy',
|
|
10549
10507
|
key: 'keyboardShortcuts',
|
|
10550
10508
|
name: '키보드 단축키 (PC)',
|
|
10551
10509
|
on: '목록에서 J/K 로 글을 고르고 Enter 로 엽니다. 글에서는 J/K 로 다음·이전 글, S 스크랩, / 검색창, B 차단 관리, ? 안내.',
|
|
@@ -10553,7 +10511,7 @@
|
|
|
10553
10511
|
refresh: 'none'
|
|
10554
10512
|
},
|
|
10555
10513
|
{
|
|
10556
|
-
group: '
|
|
10514
|
+
group: 'handy',
|
|
10557
10515
|
key: 'hoverPreview',
|
|
10558
10516
|
name: '제목을 길게 누르면 글 미리보기 (PC)',
|
|
10559
10517
|
on: '아이폰처럼 목록 제목을 길게 누르면 화면이 흐려지며 글 전체가 가운데에 떠오릅니다. 짧게 누르면 평소처럼 글로 갑니다. 창에서 본문을 누르면 글로 이동, 바깥을 누르거나 Esc 로 닫습니다. 스크랩·작성자 차단도 바로 할 수 있고, 차단한 이미지·단어는 미리보기에서도 가립니다. 키보드로 고른 글은 P 로 엽니다.',
|
|
@@ -10561,7 +10519,7 @@
|
|
|
10561
10519
|
refresh: 'root'
|
|
10562
10520
|
},
|
|
10563
10521
|
{
|
|
10564
|
-
group: '
|
|
10522
|
+
group: 'handy',
|
|
10565
10523
|
key: 'previewHover',
|
|
10566
10524
|
parent: 'hoverPreview',
|
|
10567
10525
|
name: '마우스를 올려 멈춰도 미리보기 (PC)',
|
|
@@ -10606,7 +10564,7 @@
|
|
|
10606
10564
|
refresh: 'root'
|
|
10607
10565
|
},
|
|
10608
10566
|
{
|
|
10609
|
-
group: '
|
|
10567
|
+
group: 'handy',
|
|
10610
10568
|
key: 'autoHideScrollbar',
|
|
10611
10569
|
name: '스크롤바 자동 숨기기',
|
|
10612
10570
|
on: '화면 스크롤바를 숨기고, 스크롤하는 동안만 얇은 표시가 잠깐 나타납니다 (스크롤바가 자리를 차지하는 PC).',
|
|
@@ -10614,7 +10572,7 @@
|
|
|
10614
10572
|
refresh: 'root'
|
|
10615
10573
|
},
|
|
10616
10574
|
{
|
|
10617
|
-
group: '
|
|
10575
|
+
group: 'handy',
|
|
10618
10576
|
key: 'scrapIntercept',
|
|
10619
10577
|
name: '무제한 스크랩',
|
|
10620
10578
|
on: '글의 스크랩 버튼을 누르면 개수 제한 없이 이 기기에 저장합니다. 플로팅 메뉴의 📌 스크랩 탭에서 봅니다.',
|
|
@@ -10622,7 +10580,7 @@
|
|
|
10622
10580
|
refresh: 'none'
|
|
10623
10581
|
},
|
|
10624
10582
|
{
|
|
10625
|
-
group: '
|
|
10583
|
+
group: 'handy',
|
|
10626
10584
|
key: 'showScrollTop',
|
|
10627
10585
|
name: '맨 위로 버튼',
|
|
10628
10586
|
on: '목록을 많이 내려가면 플로팅 버튼 위에 ↑ 버튼이 나타납니다.',
|
|
@@ -10766,10 +10724,6 @@
|
|
|
10766
10724
|
renderRecentBar();
|
|
10767
10725
|
}
|
|
10768
10726
|
|
|
10769
|
-
if (item.key === 'mobileRecentStrip') {
|
|
10770
|
-
renderRecentStrip();
|
|
10771
|
-
}
|
|
10772
|
-
|
|
10773
10727
|
if (item.key === 'alarmBubble') {
|
|
10774
10728
|
paintAlarmBadge();
|
|
10775
10729
|
}
|
|
@@ -11150,7 +11104,7 @@
|
|
|
11150
11104
|
const seg = h('div', 'dc-choice-seg');
|
|
11151
11105
|
|
|
11152
11106
|
head.append(
|
|
11153
|
-
h('span', 'dc-setting-name', item
|
|
11107
|
+
h('span', 'dc-setting-name', settingLabel(item)),
|
|
11154
11108
|
h('span', 'dc-state-badge on', chosen ? chosen.label : String(current))
|
|
11155
11109
|
);
|
|
11156
11110
|
text.append(head, h('span', 'dc-setting-desc', item.on));
|
|
@@ -11186,17 +11140,43 @@
|
|
|
11186
11140
|
return row;
|
|
11187
11141
|
};
|
|
11188
11142
|
|
|
11143
|
+
const settingPlatform = item => (/\(PC\)$/.test(item.name) ? 'pc' : /\(모바일\)$/.test(item.name) ? 'mobile' : 'all');
|
|
11144
|
+
const settingShownHere = item => {
|
|
11145
|
+
const platform = settingPlatform(item);
|
|
11146
|
+
|
|
11147
|
+
return platform === 'all' || (platform === 'pc') === IS_PC_SITE;
|
|
11148
|
+
};
|
|
11149
|
+
const settingLabel = item => item.name.replace(/\s*\((PC|모바일)\)$/, '');
|
|
11150
|
+
|
|
11189
11151
|
const renderSettings = area => {
|
|
11190
11152
|
area.appendChild(
|
|
11191
|
-
makeNote(
|
|
11153
|
+
makeNote(`스위치가 초록색이면 켜짐입니다. 바꾸면 바로 적용되고 자동으로 저장됩니다. ${IS_PC_SITE ? 'PC' : '모바일'}에서 쓰는 설정만 보입니다.`)
|
|
11192
11154
|
);
|
|
11193
11155
|
|
|
11156
|
+
const search = makeFilterRow(99);
|
|
11157
|
+
|
|
11158
|
+
if (search) {
|
|
11159
|
+
search.querySelector('input').placeholder = '🔍 설정에서 찾기';
|
|
11160
|
+
area.appendChild(search);
|
|
11161
|
+
}
|
|
11162
|
+
|
|
11194
11163
|
SETTING_GROUPS.forEach(group => {
|
|
11164
|
+
const items = SETTING_ITEMS.filter(item => item.group === group.key && settingShownHere(item));
|
|
11165
|
+
|
|
11166
|
+
if (!items.length) {
|
|
11167
|
+
return;
|
|
11168
|
+
}
|
|
11169
|
+
|
|
11195
11170
|
const box = h('div', 'dc-settings-group');
|
|
11171
|
+
const title = h('div', 'dc-group-title', group.title);
|
|
11172
|
+
const intro = h('div', 'dc-group-intro', group.intro);
|
|
11196
11173
|
|
|
11197
|
-
|
|
11174
|
+
title.dataset.dcGroup = group.key;
|
|
11175
|
+
intro.dataset.dcGroup = group.key;
|
|
11176
|
+
box.dataset.dcGroup = group.key;
|
|
11177
|
+
area.append(title, intro, box);
|
|
11198
11178
|
|
|
11199
|
-
|
|
11179
|
+
items.forEach(item => {
|
|
11200
11180
|
if (item.choices) {
|
|
11201
11181
|
box.appendChild(renderChoiceSetting(item));
|
|
11202
11182
|
return;
|
|
@@ -11211,7 +11191,7 @@
|
|
|
11211
11191
|
const toggle = h('button', `dc-switch${on ? ' on' : ''}`);
|
|
11212
11192
|
|
|
11213
11193
|
head.append(
|
|
11214
|
-
h('span', 'dc-setting-name', item
|
|
11194
|
+
h('span', 'dc-setting-name', settingLabel(item)),
|
|
11215
11195
|
h('span', `dc-state-badge${on ? ' on' : ''}`, on ? '켜짐' : '꺼짐')
|
|
11216
11196
|
);
|
|
11217
11197
|
text.append(head, h('span', 'dc-setting-desc', on || !item.off ? item.on : item.off));
|
|
@@ -11221,7 +11201,7 @@
|
|
|
11221
11201
|
}
|
|
11222
11202
|
|
|
11223
11203
|
const status = !effective
|
|
11224
|
-
? `위의 '${parent
|
|
11204
|
+
? `위의 '${settingLabel(parent)}' 설정을 먼저 켜 주세요.`
|
|
11225
11205
|
: item.status
|
|
11226
11206
|
? item.status(on)
|
|
11227
11207
|
: null;
|
|
@@ -11233,7 +11213,7 @@
|
|
|
11233
11213
|
toggle.type = 'button';
|
|
11234
11214
|
toggle.disabled = !effective;
|
|
11235
11215
|
toggle.setAttribute('role', 'switch');
|
|
11236
|
-
toggle.setAttribute('aria-label', item
|
|
11216
|
+
toggle.setAttribute('aria-label', settingLabel(item));
|
|
11237
11217
|
toggle.setAttribute('aria-checked', String(on));
|
|
11238
11218
|
|
|
11239
11219
|
toggle.addEventListener('click', () => {
|
|
@@ -11685,7 +11665,13 @@
|
|
|
11685
11665
|
};
|
|
11686
11666
|
|
|
11687
11667
|
const setModalView = view => {
|
|
11688
|
-
|
|
11668
|
+
const next = MODAL_VIEWS[view] ? view : 'overview';
|
|
11669
|
+
|
|
11670
|
+
if (next !== currentView) {
|
|
11671
|
+
blockFilter = '';
|
|
11672
|
+
}
|
|
11673
|
+
|
|
11674
|
+
currentView = next;
|
|
11689
11675
|
|
|
11690
11676
|
document.getElementById('dc-modal-title').textContent = MODAL_VIEWS[currentView].title;
|
|
11691
11677
|
document.querySelectorAll('[data-dc-view]').forEach(btn => {
|
|
@@ -11994,6 +11980,18 @@
|
|
|
11994
11980
|
return out;
|
|
11995
11981
|
};
|
|
11996
11982
|
|
|
11983
|
+
const pickKnownSettings = (source = {}) => {
|
|
11984
|
+
const out = {};
|
|
11985
|
+
|
|
11986
|
+
Object.keys(source || {}).forEach(key => {
|
|
11987
|
+
if (key in DEFAULT_SETTINGS && !SYNC_SETTINGS_SKIP.includes(key)) {
|
|
11988
|
+
out[key] = source[key];
|
|
11989
|
+
}
|
|
11990
|
+
});
|
|
11991
|
+
|
|
11992
|
+
return out;
|
|
11993
|
+
};
|
|
11994
|
+
|
|
11997
11995
|
const collectSyncData = () => ({
|
|
11998
11996
|
users: [...blockedUsers],
|
|
11999
11997
|
images: [...blockedMedia],
|
|
@@ -12153,7 +12151,7 @@
|
|
|
12153
12151
|
if (after.scraps) diff('스크랩', (before.scraps || []).map(scrapKeyOf), after.scraps.map(scrapKeyOf));
|
|
12154
12152
|
|
|
12155
12153
|
if (after.settings) {
|
|
12156
|
-
const changed = Object.keys(after.settings).filter(key => JSON.stringify(after.settings[key]) !== JSON.stringify((before.settings || {})[key])).length;
|
|
12154
|
+
const changed = Object.keys(pickKnownSettings(after.settings)).filter(key => JSON.stringify(after.settings[key]) !== JSON.stringify((before.settings || {})[key])).length;
|
|
12157
12155
|
|
|
12158
12156
|
if (changed) {
|
|
12159
12157
|
parts.push(`설정 ${changed}개`);
|
|
@@ -12575,6 +12573,10 @@
|
|
|
12575
12573
|
delete incoming.devices;
|
|
12576
12574
|
skippedFields(conf.skip).forEach(field => delete incoming[field]);
|
|
12577
12575
|
|
|
12576
|
+
if (incoming.settings) {
|
|
12577
|
+
incoming.settings = pickKnownSettings(incoming.settings);
|
|
12578
|
+
}
|
|
12579
|
+
|
|
12578
12580
|
const mine = {};
|
|
12579
12581
|
|
|
12580
12582
|
Object.keys(incoming).forEach(field => {
|
|
@@ -13887,82 +13889,6 @@
|
|
|
13887
13889
|
}
|
|
13888
13890
|
}
|
|
13889
13891
|
|
|
13890
|
-
const renderRecentStrip = () => {
|
|
13891
|
-
const pop = document.getElementById('lately_pop');
|
|
13892
|
-
|
|
13893
|
-
if (!IS_MOBILE_SITE || !pop || settings.mobileRecentStrip === false) {
|
|
13894
|
-
document.documentElement.classList.remove('dc-recent-strip-on');
|
|
13895
|
-
pop?.querySelector('.dc-recent-strip')?.remove();
|
|
13896
|
-
return;
|
|
13897
|
-
}
|
|
13898
|
-
|
|
13899
|
-
const latelyTab = document.getElementById('lately_gall');
|
|
13900
|
-
const showing = !latelyTab || latelyTab.classList.contains('on');
|
|
13901
|
-
let strip = pop.querySelector('.dc-recent-strip');
|
|
13902
|
-
|
|
13903
|
-
if (!strip) {
|
|
13904
|
-
strip = h('div', 'dc-ui dc-recent-strip');
|
|
13905
|
-
strip.setAttribute('role', 'list');
|
|
13906
|
-
const slider = pop.querySelector('#swiper-lately') || pop.querySelector('.vst-slider');
|
|
13907
|
-
|
|
13908
|
-
(slider ? slider.parentNode : pop).insertBefore(strip, slider || null);
|
|
13909
|
-
}
|
|
13910
|
-
|
|
13911
|
-
document.documentElement.classList.add('dc-recent-strip-on');
|
|
13912
|
-
strip.hidden = !showing;
|
|
13913
|
-
pop.classList.toggle('dc-strip-lately', showing);
|
|
13914
|
-
|
|
13915
|
-
if (!showing) {
|
|
13916
|
-
return;
|
|
13917
|
-
}
|
|
13918
|
-
|
|
13919
|
-
const keepScroll = strip.scrollLeft;
|
|
13920
|
-
|
|
13921
|
-
strip.textContent = '';
|
|
13922
|
-
|
|
13923
|
-
if (!recentGalls.length) {
|
|
13924
|
-
strip.appendChild(h('span', 'dc-rs-empty', '최근 방문한 갤러리가 없습니다'));
|
|
13925
|
-
return;
|
|
13926
|
-
}
|
|
13927
|
-
|
|
13928
|
-
const here = (currentGalleryVisit() || {}).id;
|
|
13929
|
-
|
|
13930
|
-
recentGalls.forEach(item => {
|
|
13931
|
-
const chip = h('a', `dc-rs-chip${item.id === here ? ' here' : ''}`);
|
|
13932
|
-
|
|
13933
|
-
chip.href = recentUrl(item);
|
|
13934
|
-
chip.setAttribute('role', 'listitem');
|
|
13935
|
-
chip.appendChild(h('span', 'dc-rs-name', item.n || item.id));
|
|
13936
|
-
|
|
13937
|
-
if (RECENT_KIND_LABEL[item.k]) {
|
|
13938
|
-
chip.appendChild(h('span', 'dc-rs-kind', item.k === 'M' ? 'ⓜ' : item.k === 'N' ? 'ⓝ' : 'ⓟ'));
|
|
13939
|
-
}
|
|
13940
|
-
|
|
13941
|
-
const del = h('button', 'dc-rs-del', '×');
|
|
13942
|
-
|
|
13943
|
-
del.type = 'button';
|
|
13944
|
-
del.setAttribute('aria-label', `${item.n || item.id} 지우기`);
|
|
13945
|
-
del.addEventListener('click', event => {
|
|
13946
|
-
event.preventDefault();
|
|
13947
|
-
event.stopPropagation();
|
|
13948
|
-
recentGalls = recentGalls.filter(other => other !== item);
|
|
13949
|
-
saveRecent();
|
|
13950
|
-
exportNativeRecent();
|
|
13951
|
-
renderRecentStrip();
|
|
13952
|
-
});
|
|
13953
|
-
chip.appendChild(del);
|
|
13954
|
-
strip.appendChild(chip);
|
|
13955
|
-
});
|
|
13956
|
-
|
|
13957
|
-
if (recentOrder.fixed) {
|
|
13958
|
-
strip.appendChild(h('span', 'dc-rs-pin', '📌 순서 고정'));
|
|
13959
|
-
}
|
|
13960
|
-
|
|
13961
|
-
strip.scrollLeft = keepScroll;
|
|
13962
|
-
|
|
13963
|
-
strip.querySelector('.dc-rs-chip.here')?.scrollIntoView?.({ block: 'nearest', inline: 'nearest' });
|
|
13964
|
-
};
|
|
13965
|
-
|
|
13966
13892
|
const renderRecentBar = () => {
|
|
13967
13893
|
const nav = IS_MOBILE_SITE ? document.querySelector('nav.nav') : null;
|
|
13968
13894
|
let bar = document.getElementById('dc-recent-bar');
|
|
@@ -13982,9 +13908,21 @@
|
|
|
13982
13908
|
try {
|
|
13983
13909
|
const cs = getComputedStyle(nav);
|
|
13984
13910
|
const active = nav.querySelector('li.on a') || nav.querySelector('a');
|
|
13985
|
-
|
|
13986
|
-
|
|
13987
|
-
|
|
13911
|
+
const plain = nav.querySelector('li:not(.on) a') || active;
|
|
13912
|
+
const items = [...nav.querySelectorAll('li')].filter(li => li.getBoundingClientRect().width);
|
|
13913
|
+
const gap = items.length > 1 ? Math.round(items[1].getBoundingClientRect().left - items[0].getBoundingClientRect().right) : 30;
|
|
13914
|
+
const ps = plain ? getComputedStyle(plain) : null;
|
|
13915
|
+
const set = (name, value) => value && bar.style.setProperty(name, value);
|
|
13916
|
+
|
|
13917
|
+
set('--dc-rb-bg', cs.backgroundColor);
|
|
13918
|
+
set('--dc-rb-on', active ? getComputedStyle(active).color : '');
|
|
13919
|
+
set('--dc-rb-color', ps ? ps.color : '');
|
|
13920
|
+
set('--dc-rb-size', ps ? ps.fontSize : '');
|
|
13921
|
+
set('--dc-rb-weight', ps ? ps.fontWeight : '');
|
|
13922
|
+
set('--dc-rb-family', ps ? ps.fontFamily : '');
|
|
13923
|
+
set('--dc-rb-spacing', ps ? ps.letterSpacing : '');
|
|
13924
|
+
set('--dc-rb-gap', `${Math.max(16, Math.min(40, gap))}px`);
|
|
13925
|
+
set('--dc-rb-pad', items[0] ? `${Math.round(items[0].getBoundingClientRect().left - nav.getBoundingClientRect().left)}px` : '');
|
|
13988
13926
|
} catch {
|
|
13989
13927
|
}
|
|
13990
13928
|
|
|
@@ -14019,41 +13957,11 @@
|
|
|
14019
13957
|
}
|
|
14020
13958
|
};
|
|
14021
13959
|
|
|
14022
|
-
const watchRecentStrip = () => {
|
|
14023
|
-
const pop = document.getElementById('lately_pop');
|
|
14024
|
-
|
|
14025
|
-
if (!IS_MOBILE_SITE || !pop) {
|
|
14026
|
-
return;
|
|
14027
|
-
}
|
|
14028
|
-
|
|
14029
|
-
let timer = null;
|
|
14030
|
-
const refresh = () => {
|
|
14031
|
-
clearTimeout(timer);
|
|
14032
|
-
timer = setTimeout(() => {
|
|
14033
|
-
if (pop.style.display !== 'none') {
|
|
14034
|
-
importNativeRecent();
|
|
14035
|
-
renderRecentStrip();
|
|
14036
|
-
}
|
|
14037
|
-
}, 30);
|
|
14038
|
-
};
|
|
14039
|
-
|
|
14040
|
-
new MutationObserver(refresh).observe(pop, { attributes: true, attributeFilter: ['style'] });
|
|
14041
|
-
|
|
14042
|
-
const tabs = pop.querySelector('.tab-lst');
|
|
14043
|
-
|
|
14044
|
-
if (tabs) {
|
|
14045
|
-
new MutationObserver(refresh).observe(tabs, { attributes: true, subtree: true, attributeFilter: ['class'] });
|
|
14046
|
-
}
|
|
14047
|
-
|
|
14048
|
-
renderRecentStrip();
|
|
14049
|
-
};
|
|
14050
|
-
|
|
14051
13960
|
const initRecent = () => {
|
|
14052
13961
|
importNativeRecent();
|
|
14053
13962
|
recordGalleryVisit();
|
|
14054
13963
|
exportNativeRecent();
|
|
14055
13964
|
watchNativeRecentDom();
|
|
14056
|
-
watchRecentStrip();
|
|
14057
13965
|
renderRecentBar();
|
|
14058
13966
|
|
|
14059
13967
|
const follow = () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kangsicj/dcinsideenhancer",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.5",
|
|
4
4
|
"description": "DCInside filter & enhancer userscript for mobile and PC (디시인사이드 차단·편의 유저스크립트)",
|
|
5
5
|
"license": "GPL-3.0-only",
|
|
6
6
|
"author": "kangsicj",
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
"bugs": {
|
|
13
13
|
"url": "https://github.com/kangsicj/DCInsideEnhancer/issues"
|
|
14
14
|
},
|
|
15
|
-
"funding":
|
|
16
|
-
"type": "individual",
|
|
17
|
-
"url": "https://
|
|
18
|
-
|
|
15
|
+
"funding": [
|
|
16
|
+
{ "type": "individual", "url": "https://fairy.hada.io/@kangsicj" },
|
|
17
|
+
{ "type": "individual", "url": "https://buymeacoffee.com/kangsicj" }
|
|
18
|
+
],
|
|
19
19
|
"keywords": [
|
|
20
20
|
"userscript",
|
|
21
21
|
"tampermonkey",
|