@kangsicj/dcinsideenhancer 1.2.1 → 1.3.0
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/README.en.md +2 -1
- package/README.md +2 -1
- package/dist/DCInsideEnhancer.meta.js +1 -1
- package/dist/DCInsideEnhancer.user.js +449 -42
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -64,7 +64,8 @@ One userscript for DCInside on mobile and PC: smart blocking, endless lists, ima
|
|
|
64
64
|
- Come back from a post and you're **right where you left off**
|
|
65
65
|
- Cleaner read-post colors and a back-to-top button
|
|
66
66
|
- Keyboard shortcuts on PC: **J/K** next/previous post, Enter to open, P to preview, S to scrap, / to search
|
|
67
|
-
- On PC,
|
|
67
|
+
- On PC, **press and hold** a title to preview the whole post, iPhone-style — blocked images and words stay hidden there too
|
|
68
|
+
- **Pin the order** of recently visited galleries — it stays put wherever you go
|
|
68
69
|
|
|
69
70
|
</td>
|
|
70
71
|
</tr>
|
package/README.md
CHANGED
|
@@ -64,7 +64,8 @@
|
|
|
64
64
|
- 글을 보고 돌아오면 **보던 위치 그대로**
|
|
65
65
|
- 읽은 글 색 정리, 맨 위로 버튼
|
|
66
66
|
- PC 키보드 단축키: **J/K** 다음·이전 글, Enter 열기, P 미리보기, S 스크랩, / 검색
|
|
67
|
-
- PC는
|
|
67
|
+
- PC는 아이폰처럼 제목을 **길게 누르면 글 전체 미리보기** — 차단 이미지·단어는 미리보기에서도 가림
|
|
68
|
+
- 최근 방문 갤러리 **순서 고정** — 어디를 가도 정한 순서 그대로
|
|
68
69
|
|
|
69
70
|
</td>
|
|
70
71
|
</tr>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// @name DCInside Enhancer
|
|
3
3
|
// @name:ko 디시 인핸서
|
|
4
4
|
// @namespace https://github.com/kangsicj/DCInsideEnhancer
|
|
5
|
-
// @version 1.
|
|
5
|
+
// @version 1.3.0
|
|
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.
|
|
7
7
|
// @description:ko 디시인사이드 차단·편의 기능 (모바일·PC) - 유저·단어(제목/본문)·말머리·공지 차단, 같은/비슷한 이미지·움짤 모든 글 차단, 디시콘 제거, 차단 미디어 데이터 절약, 목록 자동 보충·무한 스크롤·뒤로 가기 위치 복원, 스크랩, 이미지 확대뷰 개선, 야간모드 자동 연동, 암호화 기기 간 동기화
|
|
8
8
|
// @author kangsicj
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// @name DCInside Enhancer
|
|
3
3
|
// @name:ko 디시 인핸서
|
|
4
4
|
// @namespace https://github.com/kangsicj/DCInsideEnhancer
|
|
5
|
-
// @version 1.
|
|
5
|
+
// @version 1.3.0
|
|
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.
|
|
7
7
|
// @description:ko 디시인사이드 차단·편의 기능 (모바일·PC) - 유저·단어(제목/본문)·말머리·공지 차단, 같은/비슷한 이미지·움짤 모든 글 차단, 디시콘 제거, 차단 미디어 데이터 절약, 목록 자동 보충·무한 스크롤·뒤로 가기 위치 복원, 스크랩, 이미지 확대뷰 개선, 야간모드 자동 연동, 암호화 기기 간 동기화
|
|
8
8
|
// @author kangsicj
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
// 0. 설정·상수
|
|
76
76
|
// =========================================================
|
|
77
77
|
|
|
78
|
-
const SCRIPT_VERSION = '1.
|
|
78
|
+
const SCRIPT_VERSION = '1.3.0';
|
|
79
79
|
const PROJECT_URL = 'https://github.com/kangsicj/DCInsideEnhancer';
|
|
80
80
|
const DONATE_URL = 'https://fairy.hada.io/@jinny#support';
|
|
81
81
|
|
|
@@ -106,6 +106,7 @@
|
|
|
106
106
|
syncLock: 'dc_sync_lock',
|
|
107
107
|
syncRt: 'dc_sync_rt',
|
|
108
108
|
recent: 'dc_recent_galls',
|
|
109
|
+
recentOrder: 'dc_recent_order',
|
|
109
110
|
recentNative: 'dc_recent_native',
|
|
110
111
|
searchHistory: 'dc_search_history',
|
|
111
112
|
blockHits: 'dc_block_hits',
|
|
@@ -221,11 +222,13 @@
|
|
|
221
222
|
hideAdSlots: true,
|
|
222
223
|
hideNewsRows: true,
|
|
223
224
|
hideCommentAds: true,
|
|
225
|
+
hideCommentFab: true,
|
|
224
226
|
hideSilbeAlarm: true,
|
|
225
227
|
alarmBubble: true,
|
|
226
228
|
alarmKeepPolling: true,
|
|
227
229
|
keyboardShortcuts: true,
|
|
228
230
|
hoverPreview: true,
|
|
231
|
+
previewHover: false,
|
|
229
232
|
alarmSystemNotify: false,
|
|
230
233
|
pcFitWidth: true,
|
|
231
234
|
autoHideScrollbar: true,
|
|
@@ -463,14 +466,41 @@
|
|
|
463
466
|
html.dc-pc-fit .dcwrap .stickyunit { display: none !important; }
|
|
464
467
|
html.dc-pc-fit .dcwrap .darkmodebox .pop_tipbox { left: auto !important; right: 0 !important; }
|
|
465
468
|
|
|
466
|
-
html.dc-pc-fit .dcwrap .cmt_info { display: flex !important; align-items: flex-start; }
|
|
467
|
-
html.dc-pc-fit .dcwrap .cmt_info::before,
|
|
468
|
-
html.dc-pc-fit .dcwrap .cmt_info::after { display: none !important; }
|
|
469
|
-
html.dc-pc-fit .dcwrap .cmt_info > .addbox { display: flex; flex: 1 1 auto; min-width: 0; width: auto !important; }
|
|
470
|
-
html.dc-pc-fit .dcwrap .cmt_info > .addbox > .cmt_nickbox { flex: 0 0 auto; float: none !important; }
|
|
471
|
-
html.dc-pc-fit .dcwrap .cmt_info > .addbox > .cmt_txtbox { flex: 1 1 auto; min-width: 0; float: none !important; width: auto !important; }
|
|
472
|
-
html.dc-pc-fit .dcwrap .cmt_info .cmt_txtbox .usertxt { float: none !important; width: auto !important; max-width: 100% !important; }
|
|
473
|
-
html.dc-pc-fit .dcwrap .cmt_info
|
|
469
|
+
html.dc-pc-fit .dcwrap :is(.cmt_info, .reply_info) { display: flex !important; align-items: flex-start; }
|
|
470
|
+
html.dc-pc-fit .dcwrap :is(.cmt_info, .reply_info)::before,
|
|
471
|
+
html.dc-pc-fit .dcwrap :is(.cmt_info, .reply_info)::after { display: none !important; }
|
|
472
|
+
html.dc-pc-fit .dcwrap :is(.cmt_info, .reply_info) > .addbox { display: flex; flex: 1 1 auto; min-width: 0; width: auto !important; }
|
|
473
|
+
html.dc-pc-fit .dcwrap :is(.cmt_info, .reply_info) > .addbox > .cmt_nickbox { flex: 0 0 auto; float: none !important; }
|
|
474
|
+
html.dc-pc-fit .dcwrap :is(.cmt_info, .reply_info) > .addbox > .cmt_txtbox { flex: 1 1 auto; min-width: 0; float: none !important; width: auto !important; }
|
|
475
|
+
html.dc-pc-fit .dcwrap :is(.cmt_info, .reply_info) .cmt_txtbox .usertxt { float: none !important; width: auto !important; max-width: 100% !important; }
|
|
476
|
+
html.dc-pc-fit .dcwrap :is(.cmt_info, .reply_info) .cmt_txtbox .comment_dccon { float: none !important; width: auto !important; max-width: 100% !important; }
|
|
477
|
+
html.dc-pc-fit .dcwrap :is(.cmt_info, .reply_info) > .fr { flex: 0 0 auto; float: none !important; margin-left: 10px; }
|
|
478
|
+
|
|
479
|
+
html.dc-pc-fit .dcwrap .writing_view_box { float: none !important; width: auto !important; }
|
|
480
|
+
html.dc-pc-fit .dcwrap .writing_view_box .write_div {
|
|
481
|
+
width: auto !important;
|
|
482
|
+
max-width: min(100%, 900px) !important;
|
|
483
|
+
margin-left: auto !important;
|
|
484
|
+
margin-right: auto !important;
|
|
485
|
+
}
|
|
486
|
+
html.dc-pc-fit .dcwrap .writing_view_box .write_div :is(img, video, iframe) { margin-left: auto; margin-right: auto; }
|
|
487
|
+
html.dc-pc-fit .dcwrap .writing_view_box .write_div img { display: block; height: auto; }
|
|
488
|
+
|
|
489
|
+
html.dc-pc-fit .dcwrap .comment_count { display: flow-root; }
|
|
490
|
+
html.dc-pc-fit .dcwrap :is(.cmt_list, .comment_box) { clear: both; }
|
|
491
|
+
|
|
492
|
+
html.dc-pc-fit .dcwrap .bottom_paging_wrap {
|
|
493
|
+
display: flex !important;
|
|
494
|
+
justify-content: center;
|
|
495
|
+
align-items: center;
|
|
496
|
+
gap: 10px;
|
|
497
|
+
width: 100% !important;
|
|
498
|
+
padding-left: 0 !important;
|
|
499
|
+
padding-right: 0 !important;
|
|
500
|
+
box-sizing: border-box;
|
|
501
|
+
position: relative;
|
|
502
|
+
}
|
|
503
|
+
html.dc-pc-fit .dcwrap .bottom_paging_wrap > .bottom_paging_box { margin: 0 !important; }
|
|
474
504
|
|
|
475
505
|
html.dc-pc-fit .dcwrap .cmt_write_box > .fl { width: 142px; }
|
|
476
506
|
html.dc-pc-fit .dcwrap .cmt_write_box > .cmt_txt_cont {
|
|
@@ -490,6 +520,7 @@
|
|
|
490
520
|
html.dc-ad-slots-off .dcwrap :is(.stickyunit, .rightbanner, .rightbanner1, .banner_box, .ad_bottom_list, #ad_floating, .kakao_ad_area, .ad_top, .view_ad_wrap, .power_link, .con_banner.writing_banbox, #ad_nv_slot, ins.adsbygoogle),
|
|
491
521
|
html.dc-ad-slots-off :is(.adv-group, li.adv-inner, section.grid.clkhigh, #home-ad, .kakao_ad_area) { display: none !important; }
|
|
492
522
|
html.dc-news-rows-off :is(table.gall_list tr.ub-content[data-type="icon_fnews"], .gall-detail-lst > li:has(.sp-lst-fnews)) { display: none !important; }
|
|
523
|
+
html.dc-comment-fab-off :is(#cmt_fab, .fab-wrap:has(> #cmt_fab)) { display: none !important; }
|
|
493
524
|
html.dc-comment-ads-off :is(.comment_box li.ub-content.dory, .comment_box li.cmt_pw_ad, .all-comment-lst > li.dc-comment-boy) { display: none !important; }
|
|
494
525
|
html.dc-silbe-alarm-off :is(.alarm-popup.silbe-alarm, .rtbAlarmPopup) { display: none !important; }
|
|
495
526
|
html.dc-alarm-bubble :is(.alarm-popup.alarm-default, .alarmPopup) { display: none !important; }
|
|
@@ -1206,6 +1237,9 @@
|
|
|
1206
1237
|
#dc-custom-modal .dc-btn.mini.id-type { color: var(--dc-type-id); }
|
|
1207
1238
|
#dc-custom-modal .dc-btn.mini.nick-type { color: var(--dc-text-dim); }
|
|
1208
1239
|
|
|
1240
|
+
#dc-custom-modal .dc-btn:disabled { opacity: .35; cursor: default; }
|
|
1241
|
+
#dc-custom-modal .dc-btn.on-state { background: var(--dc-success); }
|
|
1242
|
+
|
|
1209
1243
|
#dc-custom-modal .dc-btn.mini.on {
|
|
1210
1244
|
border-color: var(--dc-danger);
|
|
1211
1245
|
background: var(--dc-danger);
|
|
@@ -2013,6 +2047,25 @@
|
|
|
2013
2047
|
font-weight: 700;
|
|
2014
2048
|
}
|
|
2015
2049
|
|
|
2050
|
+
#dc-preview-backdrop {
|
|
2051
|
+
position: fixed;
|
|
2052
|
+
inset: 0;
|
|
2053
|
+
z-index: 99996;
|
|
2054
|
+
background: rgba(0,0,0,.18);
|
|
2055
|
+
-webkit-backdrop-filter: blur(14px) saturate(1.1);
|
|
2056
|
+
backdrop-filter: blur(14px) saturate(1.1);
|
|
2057
|
+
opacity: 0;
|
|
2058
|
+
visibility: hidden;
|
|
2059
|
+
transition: opacity .2s ease, visibility 0s linear .2s;
|
|
2060
|
+
}
|
|
2061
|
+
|
|
2062
|
+
html.dc-dark #dc-preview-backdrop { background: rgba(0,0,0,.4); }
|
|
2063
|
+
#dc-preview-backdrop.show { opacity: 1; visibility: visible; transition: opacity .2s ease, visibility 0s; }
|
|
2064
|
+
|
|
2065
|
+
#dc-preview.dc-pv-peek { transform: var(--dc-pv-from, translate(-50%, -50%) scale(.9)); transition: opacity .18s ease, transform .32s cubic-bezier(.2,.9,.3,1.15), visibility 0s linear .32s; }
|
|
2066
|
+
#dc-preview.dc-pv-peek.show { transform: translate(-50%, -50%); transition: opacity .18s ease, transform .32s cubic-bezier(.2,.9,.3,1.15), visibility 0s; }
|
|
2067
|
+
#dc-preview.dc-pv-peek { box-shadow: 0 24px 80px rgba(0,0,0,.35); }
|
|
2068
|
+
|
|
2016
2069
|
.dc-pv-anchor { text-decoration: underline !important; text-decoration-color: var(--dc-accent-ink) !important; }
|
|
2017
2070
|
|
|
2018
2071
|
.dc-key-cursor { outline: 2px solid var(--dc-accent-ink) !important; outline-offset: -2px; background: var(--dc-accent-soft) !important; }
|
|
@@ -3141,6 +3194,7 @@
|
|
|
3141
3194
|
root.classList.toggle('dc-ad-slots-off', settings.hideAdSlots !== false);
|
|
3142
3195
|
root.classList.toggle('dc-news-rows-off', settings.hideNewsRows !== false);
|
|
3143
3196
|
root.classList.toggle('dc-comment-ads-off', settings.hideCommentAds !== false);
|
|
3197
|
+
root.classList.toggle('dc-comment-fab-off', settings.hideCommentFab !== false);
|
|
3144
3198
|
root.classList.toggle('dc-silbe-alarm-off', settings.hideSilbeAlarm !== false);
|
|
3145
3199
|
root.classList.toggle('dc-alarm-bubble', settings.alarmBubble !== false);
|
|
3146
3200
|
root.classList.toggle('dc-hide-scrollbar', settings.autoHideScrollbar !== false && root.classList.contains('dc-classic-scrollbar'));
|
|
@@ -9490,7 +9544,10 @@
|
|
|
9490
9544
|
link.addEventListener('click', () => closeBlockModal());
|
|
9491
9545
|
actionsEl.appendChild(link);
|
|
9492
9546
|
} else {
|
|
9493
|
-
|
|
9547
|
+
const btn = makeButton(action.label, `mini ${action.className || ''}`, action.onClick);
|
|
9548
|
+
|
|
9549
|
+
btn.disabled = !!action.disabled;
|
|
9550
|
+
actionsEl.appendChild(btn);
|
|
9494
9551
|
}
|
|
9495
9552
|
});
|
|
9496
9553
|
|
|
@@ -10388,6 +10445,14 @@
|
|
|
10388
10445
|
off: '댓글돌이를 그대로 보여 줍니다.',
|
|
10389
10446
|
refresh: 'root'
|
|
10390
10447
|
},
|
|
10448
|
+
{
|
|
10449
|
+
group: 'clean',
|
|
10450
|
+
key: 'hideCommentFab',
|
|
10451
|
+
name: "떠 있는 '댓글로 이동' 버튼 숨기기 (모바일)",
|
|
10452
|
+
on: '글 화면 오른쪽 아래에 떠 있는 댓글 버튼을 숨깁니다. 본문 아래 [댓글] 링크와 차단 관리 버튼은 그대로입니다.',
|
|
10453
|
+
off: '댓글로 이동 버튼을 보여 줍니다.',
|
|
10454
|
+
refresh: 'root'
|
|
10455
|
+
},
|
|
10391
10456
|
{
|
|
10392
10457
|
group: 'clean',
|
|
10393
10458
|
key: 'hideAdSlots',
|
|
@@ -10473,9 +10538,18 @@
|
|
|
10473
10538
|
{
|
|
10474
10539
|
group: 'list',
|
|
10475
10540
|
key: 'hoverPreview',
|
|
10476
|
-
name: '
|
|
10477
|
-
on: '목록
|
|
10478
|
-
off: '
|
|
10541
|
+
name: '제목을 길게 누르면 글 미리보기 (PC)',
|
|
10542
|
+
on: '아이폰처럼 목록 제목을 길게 누르면 화면이 흐려지며 글 전체가 가운데에 떠오릅니다. 짧게 누르면 평소처럼 글로 갑니다. 창에서 본문을 누르면 글로 이동, 바깥을 누르거나 Esc 로 닫습니다. 스크랩·작성자 차단도 바로 할 수 있고, 차단한 이미지·단어는 미리보기에서도 가립니다. 키보드로 고른 글은 P 로 엽니다.',
|
|
10543
|
+
off: '미리보기를 쓰지 않습니다.',
|
|
10544
|
+
refresh: 'root'
|
|
10545
|
+
},
|
|
10546
|
+
{
|
|
10547
|
+
group: 'list',
|
|
10548
|
+
key: 'previewHover',
|
|
10549
|
+
parent: 'hoverPreview',
|
|
10550
|
+
name: '마우스를 올려 멈춰도 미리보기 (PC)',
|
|
10551
|
+
on: '제목 위에 마우스를 잠시 멈추면 누르지 않아도 미리보기가 뜹니다. 창 밖으로 마우스가 나가면 닫힙니다.',
|
|
10552
|
+
off: '길게 눌렀을 때만 미리보기가 뜹니다.',
|
|
10479
10553
|
refresh: 'root'
|
|
10480
10554
|
},
|
|
10481
10555
|
{
|
|
@@ -11742,7 +11816,7 @@
|
|
|
11742
11816
|
{ key: 'words', label: '단어', fields: ['keywords', 'titles'] },
|
|
11743
11817
|
{ key: 'heads', label: '말머리', fields: ['heads'] },
|
|
11744
11818
|
{ key: 'scraps', label: '스크랩', fields: ['scraps'] },
|
|
11745
|
-
{ key: 'recent', label: '최근 갤러리', fields: ['recent'] },
|
|
11819
|
+
{ key: 'recent', label: '최근 갤러리', fields: ['recent', 'recentOrder'] },
|
|
11746
11820
|
{ key: 'search', label: '검색 기록', fields: ['search'] },
|
|
11747
11821
|
{ key: 'settings', label: '설정', fields: ['settings'] }
|
|
11748
11822
|
];
|
|
@@ -11912,6 +11986,7 @@
|
|
|
11912
11986
|
scraps: scraps.map(item => ({ ...item })),
|
|
11913
11987
|
settings: syncedSettings(),
|
|
11914
11988
|
recent: collectRecentForSync(),
|
|
11989
|
+
recentOrder: collectRecentOrderForSync(),
|
|
11915
11990
|
search: collectSearchForSync(),
|
|
11916
11991
|
hits: collectHitsForSync()
|
|
11917
11992
|
});
|
|
@@ -12021,6 +12096,7 @@
|
|
|
12021
12096
|
scraps: mergeScraps(local.scraps, base && base.scraps, remote && remote.scraps),
|
|
12022
12097
|
settings: mergeSettings(local.settings, base && base.settings, remote && remote.settings),
|
|
12023
12098
|
recent: mergeRecent(local.recent, base && base.recent, remote && remote.recent),
|
|
12099
|
+
recentOrder: mergeRecentOrder(local.recentOrder, remote && remote.recentOrder),
|
|
12024
12100
|
search: mergeSearchHistory(local.search, base && base.search, remote && remote.search),
|
|
12025
12101
|
hits: mergeBlockHits(local.hits, remote && remote.hits)
|
|
12026
12102
|
};
|
|
@@ -12076,6 +12152,7 @@
|
|
|
12076
12152
|
const data = collectSyncData();
|
|
12077
12153
|
|
|
12078
12154
|
delete data.recent;
|
|
12155
|
+
delete data.recentOrder;
|
|
12079
12156
|
delete data.search;
|
|
12080
12157
|
delete data.hits;
|
|
12081
12158
|
|
|
@@ -12083,6 +12160,7 @@
|
|
|
12083
12160
|
};
|
|
12084
12161
|
|
|
12085
12162
|
const applySyncData = data => {
|
|
12163
|
+
const orderChanged = data && 'recentOrder' in data ? applyRecentOrderFromSync(data.recentOrder) : false;
|
|
12086
12164
|
const recentChanged = data && 'recent' in data ? applyRecentFromSync(data.recent) : false;
|
|
12087
12165
|
const searchChanged = data && 'search' in data ? applySearchFromSync(data.search) : false;
|
|
12088
12166
|
const hitsChanged = data && 'hits' in data ? applyHitsFromSync(data.hits) : false;
|
|
@@ -12140,7 +12218,7 @@
|
|
|
12140
12218
|
refreshAfterBlockChange();
|
|
12141
12219
|
}
|
|
12142
12220
|
|
|
12143
|
-
return changed || recentChanged || searchChanged || hitsChanged;
|
|
12221
|
+
return changed || recentChanged || orderChanged || searchChanged || hitsChanged;
|
|
12144
12222
|
};
|
|
12145
12223
|
|
|
12146
12224
|
const saveSyncUndo = (before, incoming, summary, from) => {
|
|
@@ -13384,6 +13462,38 @@
|
|
|
13384
13462
|
};
|
|
13385
13463
|
};
|
|
13386
13464
|
|
|
13465
|
+
const readRecentOrder = () => {
|
|
13466
|
+
const stored = readObject(STORAGE.recentOrder);
|
|
13467
|
+
|
|
13468
|
+
return {
|
|
13469
|
+
fixed: stored.fixed === true,
|
|
13470
|
+
keys: Array.isArray(stored.keys) ? stored.keys.filter(key => typeof key === 'string').slice(0, 200) : [],
|
|
13471
|
+
at: Number(stored.at) || 0
|
|
13472
|
+
};
|
|
13473
|
+
};
|
|
13474
|
+
|
|
13475
|
+
let recentOrder = readRecentOrder();
|
|
13476
|
+
|
|
13477
|
+
const saveRecentOrder = patch => {
|
|
13478
|
+
recentOrder = { ...recentOrder, ...patch, at: Date.now() };
|
|
13479
|
+
writeJson(STORAGE.recentOrder, recentOrder);
|
|
13480
|
+
};
|
|
13481
|
+
|
|
13482
|
+
const orderRecent = list => {
|
|
13483
|
+
const byTime = [...list].sort((a, b) => b.at - a.at);
|
|
13484
|
+
|
|
13485
|
+
if (!recentOrder.fixed) {
|
|
13486
|
+
return byTime;
|
|
13487
|
+
}
|
|
13488
|
+
|
|
13489
|
+
const index = new Map(recentOrder.keys.map((key, i) => [key, i]));
|
|
13490
|
+
const known = byTime.filter(item => index.has(recentKeyOf(item))).sort((a, b) => index.get(recentKeyOf(a)) - index.get(recentKeyOf(b)));
|
|
13491
|
+
|
|
13492
|
+
const fresh = byTime.filter(item => !index.has(recentKeyOf(item))).reverse();
|
|
13493
|
+
|
|
13494
|
+
return [...known, ...fresh];
|
|
13495
|
+
};
|
|
13496
|
+
|
|
13387
13497
|
const tidyRecent = list => {
|
|
13388
13498
|
const best = new Map();
|
|
13389
13499
|
|
|
@@ -13396,7 +13506,62 @@
|
|
|
13396
13506
|
}
|
|
13397
13507
|
});
|
|
13398
13508
|
|
|
13399
|
-
|
|
13509
|
+
const kept = [...best.values()].sort((a, b) => b.at - a.at).slice(0, RECENT_LIMIT);
|
|
13510
|
+
const ordered = orderRecent(kept);
|
|
13511
|
+
|
|
13512
|
+
if (recentOrder.fixed) {
|
|
13513
|
+
const keys = ordered.map(recentKeyOf);
|
|
13514
|
+
|
|
13515
|
+
if (JSON.stringify(keys) !== JSON.stringify(recentOrder.keys.filter(key => keys.includes(key)))) {
|
|
13516
|
+
recentOrder = { ...recentOrder, keys };
|
|
13517
|
+
writeJson(STORAGE.recentOrder, recentOrder);
|
|
13518
|
+
}
|
|
13519
|
+
}
|
|
13520
|
+
|
|
13521
|
+
return ordered;
|
|
13522
|
+
};
|
|
13523
|
+
|
|
13524
|
+
const setRecentFixed = fixed => {
|
|
13525
|
+
saveRecentOrder({ fixed, keys: recentGalls.map(recentKeyOf) });
|
|
13526
|
+
recentGalls = tidyRecent(recentGalls);
|
|
13527
|
+
writeJson(STORAGE.recent, recentGalls);
|
|
13528
|
+
exportNativeRecent();
|
|
13529
|
+
reorderNativeRecentDom();
|
|
13530
|
+
};
|
|
13531
|
+
|
|
13532
|
+
const moveRecent = (item, step) => {
|
|
13533
|
+
const list = [...recentGalls];
|
|
13534
|
+
const from = list.indexOf(item);
|
|
13535
|
+
const to = Math.max(0, Math.min(list.length - 1, from + step));
|
|
13536
|
+
|
|
13537
|
+
if (from < 0 || from === to) {
|
|
13538
|
+
return;
|
|
13539
|
+
}
|
|
13540
|
+
|
|
13541
|
+
list.splice(to, 0, ...list.splice(from, 1));
|
|
13542
|
+
saveRecentOrder({ fixed: true, keys: list.map(recentKeyOf) });
|
|
13543
|
+
recentGalls = tidyRecent(list);
|
|
13544
|
+
writeJson(STORAGE.recent, recentGalls);
|
|
13545
|
+
exportNativeRecent();
|
|
13546
|
+
reorderNativeRecentDom();
|
|
13547
|
+
};
|
|
13548
|
+
|
|
13549
|
+
const reorderNativeRecentDom = () => {
|
|
13550
|
+
if (!IS_PC_SITE || !recentOrder.fixed) {
|
|
13551
|
+
return;
|
|
13552
|
+
}
|
|
13553
|
+
|
|
13554
|
+
const index = new Map(recentGalls.map((item, i) => [item.id, i]));
|
|
13555
|
+
|
|
13556
|
+
document.querySelectorAll('#visit_history .vst_listbox, .visit_tablist .under_listbox, #visit_history_lyr .vst_list').forEach(box => {
|
|
13557
|
+
const items = [...box.children].filter(li => li.tagName === 'LI');
|
|
13558
|
+
const idOf = li => li.querySelector('[data-id]')?.getAttribute('data-id') || (/lately_gall_(\S+)/.exec(li.className) || [])[1] || '';
|
|
13559
|
+
const sorted = [...items].sort((a, b) => (index.has(idOf(a)) ? index.get(idOf(a)) : 999) - (index.has(idOf(b)) ? index.get(idOf(b)) : 999));
|
|
13560
|
+
|
|
13561
|
+
if (sorted.some((li, i) => li !== items[i])) {
|
|
13562
|
+
sorted.forEach(li => box.appendChild(li));
|
|
13563
|
+
}
|
|
13564
|
+
});
|
|
13400
13565
|
};
|
|
13401
13566
|
|
|
13402
13567
|
let recentGalls = tidyRecent(readArray(STORAGE.recent));
|
|
@@ -13619,6 +13784,31 @@
|
|
|
13619
13784
|
saveRecent();
|
|
13620
13785
|
};
|
|
13621
13786
|
|
|
13787
|
+
const watchNativeRecentDom = () => {
|
|
13788
|
+
if (!IS_PC_SITE) {
|
|
13789
|
+
return;
|
|
13790
|
+
}
|
|
13791
|
+
|
|
13792
|
+
const target = document.getElementById('visit_history');
|
|
13793
|
+
|
|
13794
|
+
if (!target) {
|
|
13795
|
+
return;
|
|
13796
|
+
}
|
|
13797
|
+
|
|
13798
|
+
let timer = null;
|
|
13799
|
+
|
|
13800
|
+
new MutationObserver(() => {
|
|
13801
|
+
if (!recentOrder.fixed) {
|
|
13802
|
+
return;
|
|
13803
|
+
}
|
|
13804
|
+
|
|
13805
|
+
clearTimeout(timer);
|
|
13806
|
+
timer = setTimeout(reorderNativeRecentDom, 60);
|
|
13807
|
+
}).observe(target, { childList: true, subtree: true });
|
|
13808
|
+
|
|
13809
|
+
reorderNativeRecentDom();
|
|
13810
|
+
};
|
|
13811
|
+
|
|
13622
13812
|
const initRecentEarly = () => {
|
|
13623
13813
|
importNativeRecent();
|
|
13624
13814
|
exportNativeRecent();
|
|
@@ -13628,10 +13818,12 @@
|
|
|
13628
13818
|
importNativeRecent();
|
|
13629
13819
|
recordGalleryVisit();
|
|
13630
13820
|
exportNativeRecent();
|
|
13821
|
+
watchNativeRecentDom();
|
|
13631
13822
|
|
|
13632
13823
|
const follow = () => {
|
|
13633
|
-
if (document.visibilityState === 'visible' && importNativeRecent()) {
|
|
13824
|
+
if (document.visibilityState === 'visible' && (importNativeRecent() || recentOrder.fixed)) {
|
|
13634
13825
|
exportNativeRecent();
|
|
13826
|
+
reorderNativeRecentDom();
|
|
13635
13827
|
}
|
|
13636
13828
|
};
|
|
13637
13829
|
|
|
@@ -13641,6 +13833,31 @@
|
|
|
13641
13833
|
|
|
13642
13834
|
const collectRecentForSync = () => recentGalls.map(item => ({ ...item }));
|
|
13643
13835
|
|
|
13836
|
+
const collectRecentOrderForSync = () => ({ ...recentOrder, keys: [...recentOrder.keys] });
|
|
13837
|
+
|
|
13838
|
+
const mergeRecentOrder = (local, remote) => {
|
|
13839
|
+
if (!remote || typeof remote !== 'object' || !Array.isArray(remote.keys)) {
|
|
13840
|
+
return local;
|
|
13841
|
+
}
|
|
13842
|
+
|
|
13843
|
+
return (Number(remote.at) || 0) > (Number(local && local.at) || 0) ? remote : local;
|
|
13844
|
+
};
|
|
13845
|
+
|
|
13846
|
+
const applyRecentOrderFromSync = data => {
|
|
13847
|
+
if (!data || typeof data !== 'object' || !Array.isArray(data.keys) || (Number(data.at) || 0) <= recentOrder.at) {
|
|
13848
|
+
return false;
|
|
13849
|
+
}
|
|
13850
|
+
|
|
13851
|
+
recentOrder = { fixed: data.fixed === true, keys: data.keys.filter(key => typeof key === 'string').slice(0, 200), at: Number(data.at) };
|
|
13852
|
+
writeJson(STORAGE.recentOrder, recentOrder);
|
|
13853
|
+
recentGalls = tidyRecent(recentGalls);
|
|
13854
|
+
writeJson(STORAGE.recent, recentGalls);
|
|
13855
|
+
exportNativeRecent();
|
|
13856
|
+
reorderNativeRecentDom();
|
|
13857
|
+
|
|
13858
|
+
return true;
|
|
13859
|
+
};
|
|
13860
|
+
|
|
13644
13861
|
const mergeRecent = (local = [], base, remote) => {
|
|
13645
13862
|
if (!Array.isArray(remote)) {
|
|
13646
13863
|
return tidyRecent(local || []);
|
|
@@ -14229,18 +14446,35 @@
|
|
|
14229
14446
|
return;
|
|
14230
14447
|
}
|
|
14231
14448
|
|
|
14449
|
+
const orderRow = h('div', 'dc-btn-row');
|
|
14450
|
+
|
|
14451
|
+
orderRow.appendChild(makeButton(recentOrder.fixed ? '📌 순서 고정 중 · 끄기' : '📌 지금 순서로 고정', recentOrder.fixed ? 'wide on-state' : 'wide', () => {
|
|
14452
|
+
setRecentFixed(!recentOrder.fixed);
|
|
14453
|
+
showToast(recentOrder.fixed ? '📌 최근 방문 순서를 고정했습니다 · ↑↓ 로 바꿀 수 있어요' : '최근 방문 순서 고정을 풀었습니다 (방문한 순서로)');
|
|
14454
|
+
rerenderModal();
|
|
14455
|
+
}));
|
|
14456
|
+
area.appendChild(orderRow);
|
|
14457
|
+
|
|
14458
|
+
if (recentOrder.fixed) {
|
|
14459
|
+
area.appendChild(makeNote('고정한 순서는 디시 화면의 최근 방문 목록에도 그대로 보이고, 어느 갤러리를 가도 바뀌지 않습니다. 처음 가는 갤러리는 맨 뒤에 붙습니다.'));
|
|
14460
|
+
}
|
|
14461
|
+
|
|
14232
14462
|
const filterRow = makeFilterRow(recentGalls.length);
|
|
14233
14463
|
|
|
14234
14464
|
if (filterRow) {
|
|
14235
14465
|
area.appendChild(filterRow);
|
|
14236
14466
|
}
|
|
14237
14467
|
|
|
14238
|
-
recentGalls.forEach(item => {
|
|
14468
|
+
recentGalls.forEach((item, i) => {
|
|
14239
14469
|
area.appendChild(makeRow({
|
|
14240
14470
|
title: item.n || item.id,
|
|
14241
14471
|
chip: RECENT_KIND_LABEL[item.k] || '',
|
|
14242
14472
|
meta: [item.id, item.at ? timeAgo(item.at) : ''].filter(Boolean).join(' · '),
|
|
14243
14473
|
actions: [
|
|
14474
|
+
...(recentOrder.fixed ? [
|
|
14475
|
+
{ label: '↑', className: 'dc-icon-btn', onClick: () => { moveRecent(item, -1); rerenderModal(); }, disabled: i === 0 },
|
|
14476
|
+
{ label: '↓', className: 'dc-icon-btn', onClick: () => { moveRecent(item, 1); rerenderModal(); }, disabled: i === recentGalls.length - 1 }
|
|
14477
|
+
] : []),
|
|
14244
14478
|
{ label: '열기', href: recentUrl(item) },
|
|
14245
14479
|
{
|
|
14246
14480
|
label: '지우기',
|
|
@@ -14508,7 +14742,7 @@
|
|
|
14508
14742
|
|
|
14509
14743
|
// =========================================================
|
|
14510
14744
|
|
|
14511
|
-
const CLEANUP_IDLE_DAYS =
|
|
14745
|
+
const CLEANUP_IDLE_DAYS = 7;
|
|
14512
14746
|
|
|
14513
14747
|
const cleanupSuggestions = () => {
|
|
14514
14748
|
flushBlockHits();
|
|
@@ -14707,7 +14941,8 @@
|
|
|
14707
14941
|
|
|
14708
14942
|
// =========================================================
|
|
14709
14943
|
|
|
14710
|
-
const PREVIEW_DELAY =
|
|
14944
|
+
const PREVIEW_DELAY = 650;
|
|
14945
|
+
const PREVIEW_SWITCH_DELAY = 320;
|
|
14711
14946
|
const PREVIEW_CLOSE_DELAY = 380;
|
|
14712
14947
|
const PREVIEW_CACHE_MS = 5 * 60 * 1000;
|
|
14713
14948
|
const PREVIEW_CACHE_MAX = 30;
|
|
@@ -14744,7 +14979,11 @@
|
|
|
14744
14979
|
'</div>' +
|
|
14745
14980
|
'<div class="dc-pv-body"></div>';
|
|
14746
14981
|
previewEl.addEventListener('mouseenter', () => clearTimeout(previewCloseTimer));
|
|
14747
|
-
previewEl.addEventListener('mouseleave', () =>
|
|
14982
|
+
previewEl.addEventListener('mouseleave', () => {
|
|
14983
|
+
if (previewMode === 'hover') {
|
|
14984
|
+
schedulePreviewClose();
|
|
14985
|
+
}
|
|
14986
|
+
});
|
|
14748
14987
|
document.body.appendChild(previewEl);
|
|
14749
14988
|
|
|
14750
14989
|
return previewEl;
|
|
@@ -14755,10 +14994,14 @@
|
|
|
14755
14994
|
previewThemeObserver = null;
|
|
14756
14995
|
};
|
|
14757
14996
|
|
|
14758
|
-
const closePreview = () => {
|
|
14759
|
-
|
|
14997
|
+
const closePreview = ({ keepHover = false } = {}) => {
|
|
14998
|
+
if (!keepHover) {
|
|
14999
|
+
clearTimeout(previewHoverTimer);
|
|
15000
|
+
}
|
|
15001
|
+
|
|
14760
15002
|
clearTimeout(previewCloseTimer);
|
|
14761
15003
|
stopPreviewTheme();
|
|
15004
|
+
previewBackdrop?.classList.remove('show');
|
|
14762
15005
|
|
|
14763
15006
|
if (previewEl) {
|
|
14764
15007
|
previewEl.classList.remove('show');
|
|
@@ -14774,7 +15017,8 @@
|
|
|
14774
15017
|
|
|
14775
15018
|
const schedulePreviewClose = () => {
|
|
14776
15019
|
clearTimeout(previewCloseTimer);
|
|
14777
|
-
|
|
15020
|
+
|
|
15021
|
+
previewCloseTimer = setTimeout(() => closePreview({ keepHover: true }), PREVIEW_CLOSE_DELAY);
|
|
14778
15022
|
};
|
|
14779
15023
|
|
|
14780
15024
|
const goToPreviewPost = () => {
|
|
@@ -14935,6 +15179,20 @@
|
|
|
14935
15179
|
doc.getElementById('dc-pv-css').textContent = previewFrameCss();
|
|
14936
15180
|
doc.body.appendChild(doc.importNode(body, true));
|
|
14937
15181
|
|
|
15182
|
+
doc.querySelectorAll('img').forEach(img => {
|
|
15183
|
+
let tries = 0;
|
|
15184
|
+
const original = img.getAttribute('src') || '';
|
|
15185
|
+
|
|
15186
|
+
img.addEventListener('error', () => {
|
|
15187
|
+
if (tries >= 4 || !/dcinside\.(com|co\.kr)\//.test(original)) {
|
|
15188
|
+
return;
|
|
15189
|
+
}
|
|
15190
|
+
|
|
15191
|
+
tries += 1;
|
|
15192
|
+
setTimeout(() => img.setAttribute('src', `${original}&${tries + 1}`), 250 * tries);
|
|
15193
|
+
});
|
|
15194
|
+
});
|
|
15195
|
+
|
|
14938
15196
|
doc.querySelectorAll('video[data-src]').forEach(video => {
|
|
14939
15197
|
const gif = video.getAttribute('data-src');
|
|
14940
15198
|
let swapped = false;
|
|
@@ -15198,34 +15456,181 @@
|
|
|
15198
15456
|
}
|
|
15199
15457
|
};
|
|
15200
15458
|
|
|
15459
|
+
const PREVIEW_HOLD_MS = 350;
|
|
15460
|
+
let previewMode = 'peek';
|
|
15461
|
+
let previewBackdrop = null;
|
|
15462
|
+
|
|
15463
|
+
const ensurePreviewBackdrop = () => {
|
|
15464
|
+
if (previewBackdrop && previewBackdrop.isConnected) {
|
|
15465
|
+
return previewBackdrop;
|
|
15466
|
+
}
|
|
15467
|
+
|
|
15468
|
+
previewBackdrop = h('div', 'dc-ui');
|
|
15469
|
+
previewBackdrop.id = 'dc-preview-backdrop';
|
|
15470
|
+
previewBackdrop.addEventListener('mousedown', event => {
|
|
15471
|
+
event.preventDefault();
|
|
15472
|
+
event.stopPropagation();
|
|
15473
|
+
closePreview();
|
|
15474
|
+
});
|
|
15475
|
+
document.body.appendChild(previewBackdrop);
|
|
15476
|
+
|
|
15477
|
+
return previewBackdrop;
|
|
15478
|
+
};
|
|
15479
|
+
|
|
15480
|
+
const openPreview = (anchor, mode) => {
|
|
15481
|
+
previewMode = mode;
|
|
15482
|
+
|
|
15483
|
+
const el = ensurePreviewEl();
|
|
15484
|
+
|
|
15485
|
+
el.classList.toggle('dc-pv-peek', mode === 'peek');
|
|
15486
|
+
|
|
15487
|
+
try {
|
|
15488
|
+
const r = anchor.getBoundingClientRect();
|
|
15489
|
+
const ox = Math.round(r.left + Math.min(r.width, 240) / 2 - window.innerWidth / 2);
|
|
15490
|
+
const oy = Math.round(r.top + r.height / 2 - window.innerHeight / 2);
|
|
15491
|
+
|
|
15492
|
+
el.style.setProperty('--dc-pv-from', `translate(calc(-50% + ${ox}px), calc(-50% + ${oy}px)) scale(.35)`);
|
|
15493
|
+
} catch {
|
|
15494
|
+
el.style.removeProperty('--dc-pv-from');
|
|
15495
|
+
}
|
|
15496
|
+
|
|
15497
|
+
if (mode === 'peek') {
|
|
15498
|
+
ensurePreviewBackdrop().classList.add('show');
|
|
15499
|
+
} else {
|
|
15500
|
+
previewBackdrop?.classList.remove('show');
|
|
15501
|
+
}
|
|
15502
|
+
|
|
15503
|
+
showPreviewFor(anchor);
|
|
15504
|
+
};
|
|
15505
|
+
|
|
15201
15506
|
const initHoverPreview = () => {
|
|
15202
15507
|
if (!IS_PC_SITE) {
|
|
15203
15508
|
return;
|
|
15204
15509
|
}
|
|
15205
15510
|
|
|
15206
|
-
|
|
15207
|
-
|
|
15208
|
-
|
|
15209
|
-
|
|
15511
|
+
const hoverOn = () => previewEnabled() && settings.previewHover === true;
|
|
15512
|
+
|
|
15513
|
+
let hoverAnchor = null;
|
|
15514
|
+
let pressedAnchor = null;
|
|
15515
|
+
let holdTimer = null;
|
|
15516
|
+
let holdStart = null;
|
|
15517
|
+
let swallowClick = null;
|
|
15210
15518
|
|
|
15519
|
+
document.addEventListener('mousedown', event => {
|
|
15211
15520
|
const anchor = event.target instanceof Element ? event.target.closest(PREVIEW_TITLE_SELECTOR) : null;
|
|
15212
15521
|
|
|
15213
15522
|
if (!anchor || anchor.closest('.dc-ui')) {
|
|
15523
|
+
if (previewOpen() && !(event.target instanceof Node && previewEl.contains(event.target))) {
|
|
15524
|
+
closePreview();
|
|
15525
|
+
}
|
|
15526
|
+
|
|
15214
15527
|
return;
|
|
15215
15528
|
}
|
|
15216
15529
|
|
|
15217
|
-
|
|
15218
|
-
|
|
15530
|
+
pressedAnchor = anchor;
|
|
15531
|
+
clearTimeout(previewHoverTimer);
|
|
15532
|
+
|
|
15533
|
+
if (!previewEnabled() || event.button !== 0 || event.ctrlKey || event.metaKey || event.shiftKey || event.altKey) {
|
|
15219
15534
|
return;
|
|
15220
15535
|
}
|
|
15221
15536
|
|
|
15537
|
+
holdStart = { x: event.clientX, y: event.clientY };
|
|
15538
|
+
clearTimeout(holdTimer);
|
|
15539
|
+
holdTimer = setTimeout(() => {
|
|
15540
|
+
holdTimer = null;
|
|
15541
|
+
swallowClick = anchor;
|
|
15542
|
+
|
|
15543
|
+
window.getSelection?.()?.removeAllRanges?.();
|
|
15544
|
+
openPreview(anchor, 'peek');
|
|
15545
|
+
}, PREVIEW_HOLD_MS);
|
|
15546
|
+
}, true);
|
|
15547
|
+
|
|
15548
|
+
document.addEventListener('mousemove', event => {
|
|
15549
|
+
if (holdTimer && holdStart && Math.hypot(event.clientX - holdStart.x, event.clientY - holdStart.y) > 8) {
|
|
15550
|
+
clearTimeout(holdTimer);
|
|
15551
|
+
holdTimer = null;
|
|
15552
|
+
}
|
|
15553
|
+
}, { passive: true, capture: true });
|
|
15554
|
+
|
|
15555
|
+
const cancelHold = () => {
|
|
15556
|
+
clearTimeout(holdTimer);
|
|
15557
|
+
holdTimer = null;
|
|
15558
|
+
};
|
|
15559
|
+
|
|
15560
|
+
document.addEventListener('mouseup', cancelHold, true);
|
|
15561
|
+
document.addEventListener('dragstart', event => {
|
|
15562
|
+
if (swallowClick || holdTimer) {
|
|
15563
|
+
event.preventDefault();
|
|
15564
|
+
}
|
|
15565
|
+
|
|
15566
|
+
cancelHold();
|
|
15567
|
+
}, true);
|
|
15568
|
+
|
|
15569
|
+
document.addEventListener('click', event => {
|
|
15570
|
+
if (!swallowClick) {
|
|
15571
|
+
return;
|
|
15572
|
+
}
|
|
15573
|
+
|
|
15574
|
+
const anchor = event.target instanceof Element ? event.target.closest(PREVIEW_TITLE_SELECTOR) : null;
|
|
15575
|
+
|
|
15576
|
+
if (anchor === swallowClick) {
|
|
15577
|
+
event.preventDefault();
|
|
15578
|
+
event.stopImmediatePropagation();
|
|
15579
|
+
}
|
|
15580
|
+
|
|
15581
|
+
swallowClick = null;
|
|
15582
|
+
}, true);
|
|
15583
|
+
|
|
15584
|
+
const armHover = anchor => {
|
|
15222
15585
|
clearTimeout(previewHoverTimer);
|
|
15586
|
+
|
|
15587
|
+
if (!hoverOn() || anchor === pressedAnchor || (previewOpen() && previewMode === 'peek')) {
|
|
15588
|
+
return;
|
|
15589
|
+
}
|
|
15590
|
+
|
|
15591
|
+
const switching = previewOpen() && anchor !== previewAnchor;
|
|
15592
|
+
|
|
15223
15593
|
previewHoverTimer = setTimeout(() => {
|
|
15594
|
+
if (hoverAnchor !== anchor || pressedAnchor === anchor || !anchor.isConnected) {
|
|
15595
|
+
return;
|
|
15596
|
+
}
|
|
15597
|
+
|
|
15224
15598
|
clearTimeout(previewCloseTimer);
|
|
15225
|
-
|
|
15226
|
-
}, PREVIEW_DELAY);
|
|
15599
|
+
openPreview(anchor, 'hover');
|
|
15600
|
+
}, switching ? PREVIEW_SWITCH_DELAY : PREVIEW_DELAY);
|
|
15601
|
+
};
|
|
15602
|
+
|
|
15603
|
+
document.addEventListener('mouseover', event => {
|
|
15604
|
+
const anchor = event.target instanceof Element ? event.target.closest(PREVIEW_TITLE_SELECTOR) : null;
|
|
15605
|
+
|
|
15606
|
+
if (!anchor || anchor.closest('.dc-ui') || anchor === hoverAnchor) {
|
|
15607
|
+
return;
|
|
15608
|
+
}
|
|
15609
|
+
|
|
15610
|
+
hoverAnchor = anchor;
|
|
15611
|
+
|
|
15612
|
+
if (anchor === previewAnchor && previewOpen()) {
|
|
15613
|
+
clearTimeout(previewCloseTimer);
|
|
15614
|
+
return;
|
|
15615
|
+
}
|
|
15616
|
+
|
|
15617
|
+
if (previewOpen() && previewMode === 'hover') {
|
|
15618
|
+
clearTimeout(previewCloseTimer);
|
|
15619
|
+
}
|
|
15620
|
+
|
|
15621
|
+
armHover(anchor);
|
|
15227
15622
|
});
|
|
15228
15623
|
|
|
15624
|
+
document.addEventListener('mousemove', event => {
|
|
15625
|
+
if (!hoverAnchor || previewAnchor === hoverAnchor) {
|
|
15626
|
+
return;
|
|
15627
|
+
}
|
|
15628
|
+
|
|
15629
|
+
if (event.target instanceof Node && hoverAnchor.contains(event.target)) {
|
|
15630
|
+
armHover(hoverAnchor);
|
|
15631
|
+
}
|
|
15632
|
+
}, { passive: true });
|
|
15633
|
+
|
|
15229
15634
|
document.addEventListener('mouseout', event => {
|
|
15230
15635
|
const anchor = event.target instanceof Element ? event.target.closest(PREVIEW_TITLE_SELECTOR) : null;
|
|
15231
15636
|
|
|
@@ -15233,21 +15638,23 @@
|
|
|
15233
15638
|
return;
|
|
15234
15639
|
}
|
|
15235
15640
|
|
|
15641
|
+
if (hoverAnchor === anchor) {
|
|
15642
|
+
hoverAnchor = null;
|
|
15643
|
+
}
|
|
15644
|
+
|
|
15645
|
+
if (pressedAnchor === anchor) {
|
|
15646
|
+
pressedAnchor = null;
|
|
15647
|
+
}
|
|
15648
|
+
|
|
15236
15649
|
clearTimeout(previewHoverTimer);
|
|
15237
15650
|
|
|
15238
|
-
if (previewOpen() && !(event.relatedTarget instanceof Node && previewEl.contains(event.relatedTarget))) {
|
|
15651
|
+
if (previewOpen() && previewMode === 'hover' && !(event.relatedTarget instanceof Node && previewEl.contains(event.relatedTarget))) {
|
|
15239
15652
|
schedulePreviewClose();
|
|
15240
15653
|
}
|
|
15241
15654
|
});
|
|
15242
15655
|
|
|
15243
|
-
document.addEventListener('mousedown', event => {
|
|
15244
|
-
if (previewOpen() && !(event.target instanceof Node && previewEl.contains(event.target))) {
|
|
15245
|
-
closePreview();
|
|
15246
|
-
}
|
|
15247
|
-
}, true);
|
|
15248
|
-
|
|
15249
15656
|
window.addEventListener('scroll', () => {
|
|
15250
|
-
if (previewOpen() && !previewEl.matches(':hover')) {
|
|
15657
|
+
if (previewOpen() && previewMode === 'hover' && !previewEl.matches(':hover')) {
|
|
15251
15658
|
closePreview();
|
|
15252
15659
|
}
|
|
15253
15660
|
}, { passive: true });
|
|
@@ -15283,7 +15690,7 @@
|
|
|
15283
15690
|
return false;
|
|
15284
15691
|
}
|
|
15285
15692
|
|
|
15286
|
-
|
|
15693
|
+
openPreview(anchor, 'peek');
|
|
15287
15694
|
return true;
|
|
15288
15695
|
};
|
|
15289
15696
|
// =========================================================
|