pinokiod 3.231.0 → 3.233.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.
@@ -0,0 +1,115 @@
1
+ (function () {
2
+ const api = window.PinokioTabLinkPopover
3
+ if (!api) {
4
+ return
5
+ }
6
+ const { renderTabLinkPopover, hideTabLinkPopover, isLocalHostLike } = api
7
+
8
+ const getPopoverEl = () => document.getElementById('tab-link-popover')
9
+
10
+ const ensureHttpUrl = (value) => {
11
+ if (typeof value !== 'string') {
12
+ return ''
13
+ }
14
+ let trimmed = value.trim()
15
+ if (!trimmed) {
16
+ return ''
17
+ }
18
+ if (!/^https?:\/\//i.test(trimmed)) {
19
+ if (/^[a-z]+:\/\//i.test(trimmed)) {
20
+ return ''
21
+ }
22
+ trimmed = `http://${trimmed}`
23
+ }
24
+ try {
25
+ const parsed = new URL(trimmed)
26
+ if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
27
+ return ''
28
+ }
29
+ return parsed.toString()
30
+ } catch (_) {
31
+ return ''
32
+ }
33
+ }
34
+
35
+ const isLocalUrl = (value) => {
36
+ if (!value) {
37
+ return false
38
+ }
39
+ try {
40
+ const parsed = new URL(value)
41
+ return isLocalHostLike(parsed.hostname)
42
+ } catch (_) {
43
+ return false
44
+ }
45
+ }
46
+
47
+ const resolveCurrentUrl = (input) => {
48
+ if (input && typeof input.value === 'string' && input.value.trim().length > 0) {
49
+ const normalized = ensureHttpUrl(input.value)
50
+ if (normalized) {
51
+ return normalized
52
+ }
53
+ }
54
+ const fallback = input?.getAttribute('value')
55
+ return ensureHttpUrl(fallback || '')
56
+ }
57
+
58
+ const showPopoverForAnchor = (anchor, urlInput) => {
59
+ if (!anchor) {
60
+ return
61
+ }
62
+ const currentUrl = resolveCurrentUrl(urlInput)
63
+ if (!currentUrl || !isLocalUrl(currentUrl)) {
64
+ hideTabLinkPopover({ immediate: true })
65
+ return
66
+ }
67
+ renderTabLinkPopover(anchor, {
68
+ hrefOverride: currentUrl,
69
+ requireAlternate: false,
70
+ restrictToBase: true,
71
+ forceCanonicalQr: true,
72
+ allowQrPortMismatch: true,
73
+ skipPeerFallback: true
74
+ })
75
+ }
76
+
77
+ const handleMouseLeave = (anchor, event) => {
78
+ const related = event.relatedTarget
79
+ const popover = getPopoverEl()
80
+ if (related && (anchor.contains(related) || (popover && popover.contains(related)))) {
81
+ return
82
+ }
83
+ hideTabLinkPopover()
84
+ }
85
+
86
+ const init = () => {
87
+ const container = document.querySelector('.url-input-container')
88
+ const urlInput = container ? container.querySelector('input[type="url"]') : null
89
+ const mobileButton = document.getElementById('mobile-link-button')
90
+
91
+ if (container) {
92
+ container.addEventListener('mouseover', () => showPopoverForAnchor(container, urlInput))
93
+ container.addEventListener('mouseout', (event) => handleMouseLeave(container, event))
94
+ const inputFocus = () => showPopoverForAnchor(container, urlInput)
95
+ const inputBlur = (event) => handleMouseLeave(container, event)
96
+ if (urlInput) {
97
+ urlInput.addEventListener('focus', inputFocus)
98
+ urlInput.addEventListener('blur', inputBlur)
99
+ }
100
+ }
101
+
102
+ if (mobileButton) {
103
+ mobileButton.addEventListener('mouseover', () => showPopoverForAnchor(mobileButton, urlInput))
104
+ mobileButton.addEventListener('mouseout', (event) => handleMouseLeave(mobileButton, event))
105
+ mobileButton.addEventListener('focus', () => showPopoverForAnchor(mobileButton, urlInput))
106
+ mobileButton.addEventListener('blur', (event) => handleMouseLeave(mobileButton, event))
107
+ }
108
+ }
109
+
110
+ if (document.readyState === 'loading') {
111
+ document.addEventListener('DOMContentLoaded', init)
112
+ } else {
113
+ init()
114
+ }
115
+ })()
@@ -847,9 +847,11 @@ body {
847
847
  position: relative;
848
848
  }
849
849
  /* Reserve scrollbar space to prevent header layout shift */
850
+ /*
850
851
  html {
851
852
  scrollbar-gutter: stable both-edges;
852
853
  }
854
+ */
853
855
  body.dark {
854
856
  color: var(--dark-color);
855
857
  background: var(--dark-bg);
@@ -2816,3 +2818,7 @@ header.navheader.minimized .home .icon {
2816
2818
  header.navheader.transitioning {
2817
2819
  pointer-events: none;
2818
2820
  }
2821
+
2822
+ .shutdown i.fa-stop:hover {
2823
+ color: crimson;
2824
+ }
@@ -0,0 +1,118 @@
1
+ .tab-link-popover {
2
+ position: fixed;
3
+ display: none;
4
+ flex-direction: column;
5
+ gap: 4px;
6
+ padding: 8px 0;
7
+ border-radius: 10px;
8
+ border: 1px solid rgba(0, 0, 0, 0.12);
9
+ background: rgba(255, 255, 255, 0.97);
10
+ box-shadow: 0 12px 32px -8px rgba(15, 23, 42, 0.25);
11
+ z-index: 9999;
12
+ min-width: 240px;
13
+ max-width: 420px;
14
+ backdrop-filter: blur(6px);
15
+ }
16
+ body.dark .tab-link-popover {
17
+ border-color: rgba(255, 255, 255, 0.08);
18
+ background: rgba(17, 24, 39, 0.95);
19
+ box-shadow: 0 12px 36px -12px rgba(15, 23, 42, 0.55);
20
+ }
21
+ .tab-link-popover.visible {
22
+ display: flex;
23
+ }
24
+ .tab-link-popover .tab-link-popover-header {
25
+ display: flex;
26
+ align-items: center;
27
+ gap: 8px;
28
+ padding: 10px 14px 6px;
29
+ font-size: 11px;
30
+ font-weight: 600;
31
+ letter-spacing: 0.05em;
32
+ text-transform: uppercase;
33
+ color: rgba(15, 23, 42, 0.55);
34
+ }
35
+ .tab-link-popover .tab-link-popover-header i {
36
+ font-size: 12px;
37
+ }
38
+ body.dark .tab-link-popover .tab-link-popover-header {
39
+ color: rgba(226, 232, 240, 0.7);
40
+ }
41
+ .tab-link-popover .tab-link-popover-item {
42
+ width: 100%;
43
+ border: none;
44
+ margin: 0;
45
+ padding: 8px 14px;
46
+ display: flex;
47
+ flex-direction: column;
48
+ gap: 2px;
49
+ text-align: left;
50
+ font: inherit;
51
+ color: inherit;
52
+ background: transparent;
53
+ cursor: pointer;
54
+ }
55
+ .tab-link-popover .tab-link-popover-item.qr-inline { flex-direction: row; align-items: center; gap: 10px; }
56
+ .tab-link-popover .tab-link-popover-item.qr-inline .textcol { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; }
57
+ .tab-link-popover .tab-link-popover-item.qr-inline .qr { width: 64px; height: 64px; image-rendering: pixelated; flex: 0 0 auto; margin-left: auto; }
58
+ .tab-link-popover .tab-link-popover-item:hover,
59
+ .tab-link-popover .tab-link-popover-item:focus-visible {
60
+ background: rgba(15, 23, 42, 0.06);
61
+ outline: none;
62
+ }
63
+ body.dark .tab-link-popover .tab-link-popover-item:hover,
64
+ body.dark .tab-link-popover .tab-link-popover-item:focus-visible {
65
+ background: rgba(148, 163, 184, 0.12);
66
+ }
67
+ .tab-link-popover .tab-link-popover-item .label {
68
+ font-size: 11px;
69
+ font-weight: 600;
70
+ letter-spacing: 0.04em;
71
+ text-transform: uppercase;
72
+ color: rgba(15, 23, 42, 0.55);
73
+ }
74
+ body.dark .tab-link-popover .tab-link-popover-item .label {
75
+ color: rgba(226, 232, 240, 0.65);
76
+ }
77
+ .tab-link-popover .tab-link-popover-item .value {
78
+ font-size: 13px;
79
+ line-height: 1.35;
80
+ word-break: break-word;
81
+ color: rgba(15, 23, 42, 0.85);
82
+ }
83
+ body.dark .tab-link-popover .tab-link-popover-item .value {
84
+ color: rgba(226, 232, 240, 0.9);
85
+ }
86
+ .tab-link-popover .tab-link-popover-item .value .muted {
87
+ color: rgba(15, 23, 42, 0.55);
88
+ }
89
+ body.dark .tab-link-popover .tab-link-popover-item .value .muted {
90
+ color: rgba(226, 232, 240, 0.65);
91
+ }
92
+ .tab-link-popover .tab-link-popover-footer {
93
+ border-top: 1px solid rgba(15, 23, 42, 0.08);
94
+ margin-top: 4px;
95
+ padding-top: 12px;
96
+ background: rgba(59, 130, 246, 0.12);
97
+ color: #1d4ed8;
98
+ }
99
+ .tab-link-popover .tab-link-popover-footer .label,
100
+ .tab-link-popover .tab-link-popover-footer .value {
101
+ color: inherit;
102
+ }
103
+ .tab-link-popover .tab-link-popover-footer .value {
104
+ font-weight: 600;
105
+ }
106
+ .tab-link-popover .tab-link-popover-footer:hover,
107
+ .tab-link-popover .tab-link-popover-footer:focus-visible {
108
+ background: rgba(37, 99, 235, 0.2);
109
+ }
110
+ body.dark .tab-link-popover .tab-link-popover-footer {
111
+ border-top-color: rgba(148, 163, 184, 0.2);
112
+ background: rgba(96, 165, 250, 0.22);
113
+ color: #bfdbfe;
114
+ }
115
+ body.dark .tab-link-popover .tab-link-popover-footer:hover,
116
+ body.dark .tab-link-popover .tab-link-popover-footer:focus-visible {
117
+ background: rgba(147, 197, 253, 0.35);
118
+ }