Browse Source

Add instant.page

biotorrents 4 years ago
parent
commit
f3643602ee

+ 6
- 1
design/privatefooter.php View File

125
     }
125
     }
126
 }
126
 }
127
 
127
 
128
-echo $HTML = '</footer></body></html>';
128
+echo $HTML = <<<HTML
129
+    </footer>
130
+    <script src="$ENV->STATIC_SERVER/functions/vendor/instantpage.js" type="module"></script>
131
+  </body>
132
+</html>
133
+HTML;

+ 1
- 0
design/publicfooter.php View File

6
   <a href="/legal.php?p=dmca">DMCA</a>
6
   <a href="/legal.php?p=dmca">DMCA</a>
7
 </footer>
7
 </footer>
8
 
8
 
9
+<script src="$ENV->STATIC_SERVER/functions/vendor/instantpage.js" type="module"></script>
9
 </body>
10
 </body>
10
 
11
 
11
 </html>
12
 </html>

+ 236
- 0
static/functions/vendor/instantpage.js View File

1
+/*! instant.page v5.1.0 - (C) 2019-2020 Alexandre Dieulot - https://instant.page/license */
2
+
3
+let mouseoverTimer
4
+let lastTouchTimestamp
5
+const prefetches = new Set()
6
+const prefetchElement = document.createElement('link')
7
+const isSupported = prefetchElement.relList && prefetchElement.relList.supports && prefetchElement.relList.supports('prefetch')
8
+                    && window.IntersectionObserver && 'isIntersecting' in IntersectionObserverEntry.prototype
9
+const allowQueryString = 'instantAllowQueryString' in document.body.dataset
10
+const allowExternalLinks = 'instantAllowExternalLinks' in document.body.dataset
11
+const useWhitelist = 'instantWhitelist' in document.body.dataset
12
+const mousedownShortcut = 'instantMousedownShortcut' in document.body.dataset
13
+const DELAY_TO_NOT_BE_CONSIDERED_A_TOUCH_INITIATED_ACTION = 1111
14
+
15
+let delayOnHover = 65
16
+let useMousedown = false
17
+let useMousedownOnly = false
18
+let useViewport = false
19
+
20
+if ('instantIntensity' in document.body.dataset) {
21
+  const intensity = document.body.dataset.instantIntensity
22
+
23
+  if (intensity.substr(0, 'mousedown'.length) == 'mousedown') {
24
+    useMousedown = true
25
+    if (intensity == 'mousedown-only') {
26
+      useMousedownOnly = true
27
+    }
28
+  }
29
+  else if (intensity.substr(0, 'viewport'.length) == 'viewport') {
30
+    if (!(navigator.connection && (navigator.connection.saveData || (navigator.connection.effectiveType && navigator.connection.effectiveType.includes('2g'))))) {
31
+      if (intensity == "viewport") {
32
+        /* Biggest iPhone resolution (which we want): 414 × 896 = 370944
33
+         * Small 7" tablet resolution (which we don’t want): 600 × 1024 = 614400
34
+         * Note that the viewport (which we check here) is smaller than the resolution due to the UI’s chrome */
35
+        if (document.documentElement.clientWidth * document.documentElement.clientHeight < 450000) {
36
+          useViewport = true
37
+        }
38
+      }
39
+      else if (intensity == "viewport-all") {
40
+        useViewport = true
41
+      }
42
+    }
43
+  }
44
+  else {
45
+    const milliseconds = parseInt(intensity)
46
+    if (!isNaN(milliseconds)) {
47
+      delayOnHover = milliseconds
48
+    }
49
+  }
50
+}
51
+
52
+if (isSupported) {
53
+  const eventListenersOptions = {
54
+    capture: true,
55
+    passive: true,
56
+  }
57
+
58
+  if (!useMousedownOnly) {
59
+    document.addEventListener('touchstart', touchstartListener, eventListenersOptions)
60
+  }
61
+
62
+  if (!useMousedown) {
63
+    document.addEventListener('mouseover', mouseoverListener, eventListenersOptions)
64
+  }
65
+  else if (!mousedownShortcut) {
66
+      document.addEventListener('mousedown', mousedownListener, eventListenersOptions)
67
+  }
68
+
69
+  if (mousedownShortcut) {
70
+    document.addEventListener('mousedown', mousedownShortcutListener, eventListenersOptions)
71
+  }
72
+
73
+  if (useViewport) {
74
+    let triggeringFunction
75
+    if (window.requestIdleCallback) {
76
+      triggeringFunction = (callback) => {
77
+        requestIdleCallback(callback, {
78
+          timeout: 1500,
79
+        })
80
+      }
81
+    }
82
+    else {
83
+      triggeringFunction = (callback) => {
84
+        callback()
85
+      }
86
+    }
87
+
88
+    triggeringFunction(() => {
89
+      const intersectionObserver = new IntersectionObserver((entries) => {
90
+        entries.forEach((entry) => {
91
+          if (entry.isIntersecting) {
92
+            const linkElement = entry.target
93
+            intersectionObserver.unobserve(linkElement)
94
+            preload(linkElement.href)
95
+          }
96
+        })
97
+      })
98
+
99
+      document.querySelectorAll('a').forEach((linkElement) => {
100
+        if (isPreloadable(linkElement)) {
101
+          intersectionObserver.observe(linkElement)
102
+        }
103
+      })
104
+    })
105
+  }
106
+}
107
+
108
+function touchstartListener(event) {
109
+  /* Chrome on Android calls mouseover before touchcancel so `lastTouchTimestamp`
110
+   * must be assigned on touchstart to be measured on mouseover. */
111
+  lastTouchTimestamp = performance.now()
112
+
113
+  const linkElement = event.target.closest('a')
114
+
115
+  if (!isPreloadable(linkElement)) {
116
+    return
117
+  }
118
+
119
+  preload(linkElement.href)
120
+}
121
+
122
+function mouseoverListener(event) {
123
+  if (performance.now() - lastTouchTimestamp < DELAY_TO_NOT_BE_CONSIDERED_A_TOUCH_INITIATED_ACTION) {
124
+    return
125
+  }
126
+
127
+  const linkElement = event.target.closest('a')
128
+
129
+  if (!isPreloadable(linkElement)) {
130
+    return
131
+  }
132
+
133
+  linkElement.addEventListener('mouseout', mouseoutListener, {passive: true})
134
+
135
+  mouseoverTimer = setTimeout(() => {
136
+    preload(linkElement.href)
137
+    mouseoverTimer = undefined
138
+  }, delayOnHover)
139
+}
140
+
141
+function mousedownListener(event) {
142
+  const linkElement = event.target.closest('a')
143
+
144
+  if (!isPreloadable(linkElement)) {
145
+    return
146
+  }
147
+
148
+  preload(linkElement.href)
149
+}
150
+
151
+function mouseoutListener(event) {
152
+  if (event.relatedTarget && event.target.closest('a') == event.relatedTarget.closest('a')) {
153
+    return
154
+  }
155
+
156
+  if (mouseoverTimer) {
157
+    clearTimeout(mouseoverTimer)
158
+    mouseoverTimer = undefined
159
+  }
160
+}
161
+
162
+function mousedownShortcutListener(event) {
163
+  if (performance.now() - lastTouchTimestamp < DELAY_TO_NOT_BE_CONSIDERED_A_TOUCH_INITIATED_ACTION) {
164
+    return
165
+  }
166
+
167
+  const linkElement = event.target.closest('a')
168
+
169
+  if (event.which > 1 || event.metaKey || event.ctrlKey) {
170
+    return
171
+  }
172
+
173
+  if (!linkElement) {
174
+    return
175
+  }
176
+
177
+  linkElement.addEventListener('click', function (event) {
178
+    if (event.detail == 1337) {
179
+      return
180
+    }
181
+
182
+    event.preventDefault()
183
+  }, {capture: true, passive: false, once: true})
184
+
185
+  const customEvent = new MouseEvent('click', {view: window, bubbles: true, cancelable: false, detail: 1337})
186
+  linkElement.dispatchEvent(customEvent)
187
+}
188
+
189
+function isPreloadable(linkElement) {
190
+  if (!linkElement || !linkElement.href) {
191
+    return
192
+  }
193
+
194
+  if (useWhitelist && !('instant' in linkElement.dataset)) {
195
+    return
196
+  }
197
+
198
+  if (!allowExternalLinks && linkElement.origin != location.origin && !('instant' in linkElement.dataset)) {
199
+    return
200
+  }
201
+
202
+  if (!['http:', 'https:'].includes(linkElement.protocol)) {
203
+    return
204
+  }
205
+
206
+  if (linkElement.protocol == 'http:' && location.protocol == 'https:') {
207
+    return
208
+  }
209
+
210
+  if (!allowQueryString && linkElement.search && !('instant' in linkElement.dataset)) {
211
+    return
212
+  }
213
+
214
+  if (linkElement.hash && linkElement.pathname + linkElement.search == location.pathname + location.search) {
215
+    return
216
+  }
217
+
218
+  if ('noInstant' in linkElement.dataset) {
219
+    return
220
+  }
221
+
222
+  return true
223
+}
224
+
225
+function preload(url) {
226
+  if (prefetches.has(url)) {
227
+    return
228
+  }
229
+
230
+  const prefetcher = document.createElement('link')
231
+  prefetcher.rel = 'prefetch'
232
+  prefetcher.href = url
233
+  document.head.appendChild(prefetcher)
234
+
235
+  prefetches.add(url)
236
+}

+ 3
- 3
static/styles/postmod/scss/postmod.scss View File

1162
 
1162
 
1163
 input[type="button"],
1163
 input[type="button"],
1164
 input[type="submit"] {
1164
 input[type="submit"] {
1165
-    background: #111 url(images/alert-overlay.png) repeat-x;
1165
+    background: #111 /*url(images/alert-overlay.png)*/ repeat-x;
1166
     display: inline-block;
1166
     display: inline-block;
1167
     padding: 3px 6px 4px;
1167
     padding: 3px 6px 4px;
1168
     margin: 3px;
1168
     margin: 3px;
1213
 input[type="email"],
1213
 input[type="email"],
1214
 input[type="password"],
1214
 input[type="password"],
1215
 input[type="search"] {
1215
 input[type="search"] {
1216
-    background: #111 url(images/alert-overlay.png) repeat-x;
1216
+    background: #111 /*url(images/alert-overlay.png)*/ repeat-x;
1217
     display: inline-block;
1217
     display: inline-block;
1218
     padding: 3px;
1218
     padding: 3px;
1219
     margin: 3px;
1219
     margin: 3px;
1244
 }
1244
 }
1245
 
1245
 
1246
 input[disabled="disabled"] {
1246
 input[disabled="disabled"] {
1247
-    background: #4f4f4f url(images/alert-overlay.png) repeat-x;
1247
+    background: #4f4f4f /*url(images/alert-overlay.png)*/ repeat-x;
1248
     color: #dfdfdf;
1248
     color: #dfdfdf;
1249
 }
1249
 }
1250
 input[disabled="disabled"]:hover,
1250
 input[disabled="disabled"]:hover,

Loading…
Cancel
Save