@quicktvui/web-renderer 1.0.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/package.json +24 -0
- package/src/adapters/es3-video-player.js +828 -0
- package/src/components/Modal.js +119 -0
- package/src/components/QtAnimationView.js +678 -0
- package/src/components/QtBaseComponent.js +165 -0
- package/src/components/QtFastListView.js +1920 -0
- package/src/components/QtFlexView.js +799 -0
- package/src/components/QtImage.js +203 -0
- package/src/components/QtItemFrame.js +239 -0
- package/src/components/QtItemStoreView.js +93 -0
- package/src/components/QtItemView.js +125 -0
- package/src/components/QtListView.js +331 -0
- package/src/components/QtLoadingView.js +55 -0
- package/src/components/QtPageRootView.js +19 -0
- package/src/components/QtPlayMark.js +168 -0
- package/src/components/QtProgressBar.js +199 -0
- package/src/components/QtQRCode.js +78 -0
- package/src/components/QtReplaceChild.js +149 -0
- package/src/components/QtRippleView.js +166 -0
- package/src/components/QtSeekBar.js +409 -0
- package/src/components/QtText.js +679 -0
- package/src/components/QtTransitionImage.js +170 -0
- package/src/components/QtView.js +706 -0
- package/src/components/QtWebView.js +613 -0
- package/src/components/TabsView.js +420 -0
- package/src/components/ViewPager.js +206 -0
- package/src/components/index.js +24 -0
- package/src/components/plugins/TextV2Component.js +70 -0
- package/src/components/plugins/index.js +7 -0
- package/src/core/SceneBuilder.js +58 -0
- package/src/core/TVFocusManager.js +2014 -0
- package/src/core/asyncLocalStorage.js +175 -0
- package/src/core/autoProxy.js +165 -0
- package/src/core/componentRegistry.js +84 -0
- package/src/core/constants.js +6 -0
- package/src/core/index.js +8 -0
- package/src/core/moduleUtils.js +36 -0
- package/src/core/patches.js +958 -0
- package/src/core/templateBinding.js +666 -0
- package/src/index.js +246 -0
- package/src/modules/AndroidDevelopModule.js +101 -0
- package/src/modules/AndroidDeviceModule.js +341 -0
- package/src/modules/AndroidNetworkModule.js +178 -0
- package/src/modules/AndroidSharedPreferencesModule.js +100 -0
- package/src/modules/ESDeviceInfoModule.js +450 -0
- package/src/modules/ESGroupDataModule.js +195 -0
- package/src/modules/ESIJKAudioPlayerModule.js +477 -0
- package/src/modules/ESLocalStorageModule.js +100 -0
- package/src/modules/ESLogModule.js +65 -0
- package/src/modules/ESModule.js +106 -0
- package/src/modules/ESNetworkSpeedModule.js +117 -0
- package/src/modules/ESToastModule.js +172 -0
- package/src/modules/EsNativeModule.js +117 -0
- package/src/modules/FastListModule.js +101 -0
- package/src/modules/FocusModule.js +145 -0
- package/src/modules/RuntimeDeviceModule.js +176 -0
|
@@ -0,0 +1,613 @@
|
|
|
1
|
+
// QtWebView component for web platform
|
|
2
|
+
// Implements WebView using iframe
|
|
3
|
+
import { QtBaseComponent } from './QtBaseComponent'
|
|
4
|
+
|
|
5
|
+
console.log('[QtWebView] Module loaded')
|
|
6
|
+
|
|
7
|
+
export class QtWebView extends QtBaseComponent {
|
|
8
|
+
constructor(context, id, pId) {
|
|
9
|
+
super(context, id, pId)
|
|
10
|
+
this.tagName = 'ESWebViewComponent'
|
|
11
|
+
this.dom = document.createElement('div')
|
|
12
|
+
this._iframe = null
|
|
13
|
+
this._url = null
|
|
14
|
+
this._userAgent = null
|
|
15
|
+
|
|
16
|
+
console.log('[QtWebView] constructor called, id:', id)
|
|
17
|
+
|
|
18
|
+
// Create iframe container
|
|
19
|
+
this.dom.style.position = 'relative'
|
|
20
|
+
this.dom.style.overflow = 'hidden'
|
|
21
|
+
this.dom.setAttribute('data-component-name', 'QtWebView')
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
defaultStyle() {
|
|
25
|
+
return {
|
|
26
|
+
boxSizing: 'border-box',
|
|
27
|
+
zIndex: 0,
|
|
28
|
+
display: 'block',
|
|
29
|
+
position: 'relative',
|
|
30
|
+
overflow: 'hidden',
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Create or get iframe
|
|
35
|
+
_getOrCreateIframe() {
|
|
36
|
+
if (!this._iframe) {
|
|
37
|
+
this._iframe = document.createElement('iframe')
|
|
38
|
+
this._iframe.style.width = '100%'
|
|
39
|
+
this._iframe.style.height = '100%'
|
|
40
|
+
this._iframe.style.border = 'none'
|
|
41
|
+
this._iframe.style.position = 'absolute'
|
|
42
|
+
this._iframe.style.top = '0'
|
|
43
|
+
this._iframe.style.left = '0'
|
|
44
|
+
this._iframe.allow = 'autoplay; fullscreen; clipboard-write'
|
|
45
|
+
this._iframe.setAttribute(
|
|
46
|
+
'sandbox',
|
|
47
|
+
'allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox'
|
|
48
|
+
)
|
|
49
|
+
this.dom.appendChild(this._iframe)
|
|
50
|
+
|
|
51
|
+
// Handle iframe load error
|
|
52
|
+
this._iframe.addEventListener('error', (e) => {
|
|
53
|
+
console.error('[QtWebView] iframe error:', e)
|
|
54
|
+
this._handleLoadError()
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
// Handle iframe load
|
|
58
|
+
this._iframe.addEventListener('load', () => {
|
|
59
|
+
console.log('[QtWebView] iframe loaded')
|
|
60
|
+
// Try to detect if blocked
|
|
61
|
+
this._detectBlockedContent()
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
// Prevent iframe from stealing keyboard focus
|
|
65
|
+
// This ensures Escape key still works for back navigation
|
|
66
|
+
this._iframe.setAttribute('tabindex', '-1')
|
|
67
|
+
this._iframe.addEventListener('focus', (e) => {
|
|
68
|
+
// Blur the iframe to return focus to parent
|
|
69
|
+
setTimeout(() => {
|
|
70
|
+
if (this._iframe) {
|
|
71
|
+
this._iframe.blur()
|
|
72
|
+
document.body.focus()
|
|
73
|
+
}
|
|
74
|
+
}, 0)
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
return this._iframe
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Detect if content is blocked by X-Frame-Options or connection failed
|
|
81
|
+
_detectBlockedContent() {
|
|
82
|
+
if (!this._iframe) return
|
|
83
|
+
|
|
84
|
+
// Give a small delay for the browser to render error pages
|
|
85
|
+
setTimeout(() => {
|
|
86
|
+
if (!this._iframe) return
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
// This will throw if cross-origin
|
|
90
|
+
const doc = this._iframe.contentDocument || this._iframe.contentWindow.document
|
|
91
|
+
|
|
92
|
+
// Check if it's a blank or error page
|
|
93
|
+
const bodyContent = doc?.body?.innerHTML || ''
|
|
94
|
+
|
|
95
|
+
console.log('[QtWebView] _detectBlockedContent - bodyContent length:', bodyContent.length)
|
|
96
|
+
|
|
97
|
+
// Chrome shows error pages with specific content
|
|
98
|
+
const isConnectionError =
|
|
99
|
+
bodyContent.includes('ERR_CONNECTION') ||
|
|
100
|
+
bodyContent.includes('ERR_NAME_NOT_RESOLVED') ||
|
|
101
|
+
bodyContent.includes('拒绝了我们的连接请求') ||
|
|
102
|
+
bodyContent.includes('无法访问此网站')
|
|
103
|
+
|
|
104
|
+
const isBlockedError =
|
|
105
|
+
bodyContent.includes('X-Frame-Options') ||
|
|
106
|
+
bodyContent.includes('refused to connect') ||
|
|
107
|
+
bodyContent.includes('blocked by') ||
|
|
108
|
+
bodyContent.includes('拒绝连接')
|
|
109
|
+
|
|
110
|
+
// Check for empty or minimal content
|
|
111
|
+
const isEmpty =
|
|
112
|
+
!doc ||
|
|
113
|
+
!doc.body ||
|
|
114
|
+
bodyContent === '' ||
|
|
115
|
+
bodyContent === '<br>' ||
|
|
116
|
+
bodyContent.length < 50
|
|
117
|
+
|
|
118
|
+
console.log(
|
|
119
|
+
'[QtWebView] _detectBlockedContent - isConnectionError:',
|
|
120
|
+
isConnectionError,
|
|
121
|
+
'isBlockedError:',
|
|
122
|
+
isBlockedError,
|
|
123
|
+
'isEmpty:',
|
|
124
|
+
isEmpty
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
if (isConnectionError) {
|
|
128
|
+
console.log('[QtWebView] Detected connection error')
|
|
129
|
+
this._handleLoadError('无法连接到服务器,请检查网络或地址是否正确')
|
|
130
|
+
} else if (isBlockedError) {
|
|
131
|
+
console.log('[QtWebView] Detected blocked content')
|
|
132
|
+
this._handleLoadError('该网站设置了安全策略,禁止在页面内嵌入显示')
|
|
133
|
+
} else if (isEmpty) {
|
|
134
|
+
console.log('[QtWebView] Detected empty content')
|
|
135
|
+
this._handleLoadError('页面内容为空')
|
|
136
|
+
}
|
|
137
|
+
} catch (e) {
|
|
138
|
+
// Cross-origin - the page may have loaded successfully
|
|
139
|
+
console.log('[QtWebView] Cross-origin page loaded successfully')
|
|
140
|
+
}
|
|
141
|
+
}, 500)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Handle load error - show friendly error message
|
|
145
|
+
_handleLoadError(errorMessage = '该网站设置了安全策略,禁止在页面内嵌入显示') {
|
|
146
|
+
// Show error message in the container
|
|
147
|
+
this.dom.innerHTML = `
|
|
148
|
+
<div style="display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%; height: 100%; background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); color: #fff; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;">
|
|
149
|
+
<div style="width: 120px; height: 120px; border-radius: 50%; background: rgba(255,255,255,0.1); display: flex; align-items: center; justify-content: center; margin-bottom: 30px;">
|
|
150
|
+
<svg width="60" height="60" viewBox="0 0 24 24" fill="none" stroke="#ff6b6b" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
151
|
+
<circle cx="12" cy="12" r="10"></circle>
|
|
152
|
+
<line x1="15" y1="9" x2="9" y2="15"></line>
|
|
153
|
+
<line x1="9" y1="9" x2="15" y2="15"></line>
|
|
154
|
+
</svg>
|
|
155
|
+
</div>
|
|
156
|
+
<div style="font-size: 28px; font-weight: 600; margin-bottom: 12px; color: #fff;">无法加载页面</div>
|
|
157
|
+
<div style="font-size: 16px; color: #888; margin-bottom: 8px; text-align: center; max-width: 400px; line-height: 1.6;">
|
|
158
|
+
${errorMessage}
|
|
159
|
+
</div>
|
|
160
|
+
<div style="font-size: 14px; color: #666; margin-bottom: 30px; word-break: break-all; max-width: 500px; text-align: center;">
|
|
161
|
+
${this._url || ''}
|
|
162
|
+
</div>
|
|
163
|
+
<div style="display: flex; gap: 16px;">
|
|
164
|
+
<button id="webview-open-external" style="padding: 14px 28px; font-size: 16px; cursor: pointer; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; border-radius: 8px; transition: transform 0.2s, box-shadow 0.2s; box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);">
|
|
165
|
+
在新窗口打开
|
|
166
|
+
</button>
|
|
167
|
+
<button id="webview-go-back" style="padding: 14px 28px; font-size: 16px; cursor: pointer; background: rgba(255,255,255,0.1); color: #fff; border: 1px solid rgba(255,255,255,0.2); border-radius: 8px; transition: transform 0.2s, background 0.2s;">
|
|
168
|
+
返回上一页
|
|
169
|
+
</button>
|
|
170
|
+
</div>
|
|
171
|
+
</div>
|
|
172
|
+
`
|
|
173
|
+
|
|
174
|
+
// Open in new window button
|
|
175
|
+
const openBtn = this.dom.querySelector('#webview-open-external')
|
|
176
|
+
if (openBtn && this._url) {
|
|
177
|
+
openBtn.addEventListener('mouseenter', () => {
|
|
178
|
+
openBtn.style.transform = 'translateY(-2px)'
|
|
179
|
+
openBtn.style.boxShadow = '0 6px 20px rgba(102, 126, 234, 0.5)'
|
|
180
|
+
})
|
|
181
|
+
openBtn.addEventListener('mouseleave', () => {
|
|
182
|
+
openBtn.style.transform = 'translateY(0)'
|
|
183
|
+
openBtn.style.boxShadow = '0 4px 15px rgba(102, 126, 234, 0.4)'
|
|
184
|
+
})
|
|
185
|
+
openBtn.addEventListener('click', () => {
|
|
186
|
+
window.open(this._url, '_blank')
|
|
187
|
+
})
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Go back button
|
|
191
|
+
const backBtn = this.dom.querySelector('#webview-go-back')
|
|
192
|
+
if (backBtn) {
|
|
193
|
+
backBtn.addEventListener('mouseenter', () => {
|
|
194
|
+
backBtn.style.background = 'rgba(255,255,255,0.15)'
|
|
195
|
+
})
|
|
196
|
+
backBtn.addEventListener('mouseleave', () => {
|
|
197
|
+
backBtn.style.background = 'rgba(255,255,255,0.1)'
|
|
198
|
+
})
|
|
199
|
+
backBtn.addEventListener('click', () => {
|
|
200
|
+
const router = global.__ES_ROUTER__
|
|
201
|
+
if (router && typeof router.back === 'function') {
|
|
202
|
+
router.back()
|
|
203
|
+
} else {
|
|
204
|
+
window.history.back()
|
|
205
|
+
}
|
|
206
|
+
})
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Handle URL property
|
|
211
|
+
updateProperty(key, value) {
|
|
212
|
+
if (key === 'url' || key === 'source') {
|
|
213
|
+
if (typeof value === 'string') {
|
|
214
|
+
this.loadUrl([value])
|
|
215
|
+
} else if (value && value.uri) {
|
|
216
|
+
this.loadUrl([value.uri])
|
|
217
|
+
}
|
|
218
|
+
return
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (key === 'userAgent') {
|
|
222
|
+
this.setUserAgent([value])
|
|
223
|
+
return
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// For other properties, use parent class handling
|
|
227
|
+
super.updateProperty(key, value)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Check if URL is reachable before loading
|
|
231
|
+
// Note: Due to CORS restrictions, this check is not 100% reliable
|
|
232
|
+
// We use a simple img request to check connectivity
|
|
233
|
+
async _checkUrlReachable(url) {
|
|
234
|
+
return new Promise((resolve) => {
|
|
235
|
+
// For http/https URLs, try to use a simple method
|
|
236
|
+
// We can't reliably check cross-origin URLs due to CORS
|
|
237
|
+
// So we just check if it's a valid URL format
|
|
238
|
+
try {
|
|
239
|
+
const urlObj = new URL(url)
|
|
240
|
+
// If it's a valid URL, assume it's reachable
|
|
241
|
+
// The iframe will handle the actual loading
|
|
242
|
+
resolve(true)
|
|
243
|
+
} catch (e) {
|
|
244
|
+
console.log('[QtWebView] Invalid URL format:', e.message)
|
|
245
|
+
resolve(false)
|
|
246
|
+
}
|
|
247
|
+
})
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Load URL
|
|
251
|
+
loadUrl(params) {
|
|
252
|
+
const url = Array.isArray(params) ? params[0] : params
|
|
253
|
+
console.log('[QtWebView] loadUrl:', url)
|
|
254
|
+
this._url = url
|
|
255
|
+
|
|
256
|
+
// Clear previous content and timeout
|
|
257
|
+
if (this._loadTimeout) {
|
|
258
|
+
clearTimeout(this._loadTimeout)
|
|
259
|
+
this._loadTimeout = null
|
|
260
|
+
}
|
|
261
|
+
this.dom.innerHTML = ''
|
|
262
|
+
|
|
263
|
+
// Validate URL
|
|
264
|
+
try {
|
|
265
|
+
new URL(url)
|
|
266
|
+
} catch (e) {
|
|
267
|
+
this._handleLoadError('URL 格式无效')
|
|
268
|
+
return
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Show loading indicator
|
|
272
|
+
this._showLoading()
|
|
273
|
+
|
|
274
|
+
// Create iframe and load URL
|
|
275
|
+
const iframe = this._getOrCreateIframe()
|
|
276
|
+
iframe.src = url
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Show loading indicator
|
|
280
|
+
_showLoading() {
|
|
281
|
+
this.dom.innerHTML = `
|
|
282
|
+
<div style="display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%; height: 100%; background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); color: #fff; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;">
|
|
283
|
+
<div style="width: 60px; height: 60px; border: 4px solid rgba(255,255,255,0.1); border-top-color: #667eea; border-radius: 50%; animation: spin 1s linear infinite;"></div>
|
|
284
|
+
<div style="margin-top: 20px; font-size: 16px; color: #888;">正在加载...</div>
|
|
285
|
+
<style>
|
|
286
|
+
@keyframes spin {
|
|
287
|
+
to { transform: rotate(360deg); }
|
|
288
|
+
}
|
|
289
|
+
</style>
|
|
290
|
+
</div>
|
|
291
|
+
`
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// Reload the page
|
|
295
|
+
reload(params) {
|
|
296
|
+
if (this._iframe) {
|
|
297
|
+
this._iframe.src = this._iframe.src
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Clear cache
|
|
302
|
+
clearCache(params) {
|
|
303
|
+
// In web, we can't clear browser cache directly
|
|
304
|
+
console.log('[QtWebView] clearCache called (no-op in web)')
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Get current URL
|
|
308
|
+
getUrl() {
|
|
309
|
+
return Promise.resolve(this._iframe?.src || this._url)
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Get original URL
|
|
313
|
+
getOriginalUrl() {
|
|
314
|
+
return Promise.resolve(this._url)
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Set layer type (no-op in web)
|
|
318
|
+
setLayerType(params) {
|
|
319
|
+
console.log('[QtWebView] setLayerType called (no-op in web)')
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Set ignore CA (no-op in web)
|
|
323
|
+
setIgnoreCA(params) {
|
|
324
|
+
console.log('[QtWebView] setIgnoreCA called (no-op in web)')
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Get back forward list
|
|
328
|
+
getBackForwardList() {
|
|
329
|
+
// In web, we can't access iframe history directly
|
|
330
|
+
return Promise.resolve([])
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Get current index with back forward list
|
|
334
|
+
getCurrentIndexWithBackForwardList() {
|
|
335
|
+
return Promise.resolve(0)
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Get screen status
|
|
339
|
+
getScreenStatus() {
|
|
340
|
+
return Promise.resolve(0)
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Auto click position
|
|
344
|
+
autoClickPosition(params) {
|
|
345
|
+
const [x, y] = Array.isArray(params) ? params : [params, 0]
|
|
346
|
+
console.log('[QtWebView] autoClickPosition:', x, y)
|
|
347
|
+
// Not supported in web
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Disable image display
|
|
351
|
+
disableImageDisplay() {
|
|
352
|
+
console.log('[QtWebView] disableImageDisplay (no-op in web)')
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Enable image display
|
|
356
|
+
enableImageDisplay() {
|
|
357
|
+
console.log('[QtWebView] enableImageDisplay (no-op in web)')
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// Stop loading
|
|
361
|
+
stopLoading() {
|
|
362
|
+
if (this._iframe) {
|
|
363
|
+
// Stop iframe loading by removing and re-adding
|
|
364
|
+
const src = this._iframe.src
|
|
365
|
+
this._iframe.removeAttribute('src')
|
|
366
|
+
this._iframe.src = src
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Clear view
|
|
371
|
+
clearView() {
|
|
372
|
+
if (this._iframe) {
|
|
373
|
+
this._iframe.src = 'about:blank'
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Set listen events
|
|
378
|
+
setListenEvents(params) {
|
|
379
|
+
console.log('[QtWebView] setListenEvents:', params)
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// Set ignore all key event
|
|
383
|
+
setIgnoreAllKeyEvent(params) {
|
|
384
|
+
console.log('[QtWebView] setIgnoreAllKeyEvent:', params)
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// Evaluate JavaScript
|
|
388
|
+
evaluateJavascript(params) {
|
|
389
|
+
const script = Array.isArray(params) ? params[0] : params
|
|
390
|
+
if (this._iframe && this._iframe.contentWindow) {
|
|
391
|
+
try {
|
|
392
|
+
const result = this._iframe.contentWindow.eval(script)
|
|
393
|
+
return Promise.resolve(result)
|
|
394
|
+
} catch (e) {
|
|
395
|
+
console.error('[QtWebView] evaluateJavascript error:', e)
|
|
396
|
+
return Promise.resolve(null)
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
return Promise.resolve(null)
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Set sniffing enabled
|
|
403
|
+
setSniffingEnabled(params) {
|
|
404
|
+
console.log('[QtWebView] setSniffingEnabled (no-op in web)')
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// Set sniffing rule
|
|
408
|
+
setSniffingRule(params) {
|
|
409
|
+
console.log('[QtWebView] setSniffingRule (no-op in web)')
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// Reset sniffing rule
|
|
413
|
+
resetSniffingRule() {
|
|
414
|
+
console.log('[QtWebView] resetSniffingRule (no-op in web)')
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// Set intercept enabled
|
|
418
|
+
setInterceptEnabled(params) {
|
|
419
|
+
console.log('[QtWebView] setInterceptEnabled (no-op in web)')
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// Set intercept rule
|
|
423
|
+
setInterceptRule(params) {
|
|
424
|
+
console.log('[QtWebView] setInterceptRule (no-op in web)')
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// Reset intercept rule
|
|
428
|
+
resetInterceptRule() {
|
|
429
|
+
console.log('[QtWebView] resetInterceptRule (no-op in web)')
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// Should override URL loading
|
|
433
|
+
shouldOverrideUrlLoading(params) {
|
|
434
|
+
console.log('[QtWebView] shouldOverrideUrlLoading:', params)
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// Set user agent
|
|
438
|
+
setUserAgent(params) {
|
|
439
|
+
const userAgent = Array.isArray(params) ? params[0] : params
|
|
440
|
+
this._userAgent = userAgent
|
|
441
|
+
// In web, we can't set iframe user agent directly
|
|
442
|
+
console.log('[QtWebView] setUserAgent (limited support in web):', userAgent)
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Can go back
|
|
446
|
+
canGoBack() {
|
|
447
|
+
// Can't access iframe history in web
|
|
448
|
+
return Promise.resolve(false)
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// Go back
|
|
452
|
+
goBack() {
|
|
453
|
+
// Can't access iframe history in web
|
|
454
|
+
if (this._iframe) {
|
|
455
|
+
try {
|
|
456
|
+
this._iframe.contentWindow.history.back()
|
|
457
|
+
} catch (e) {
|
|
458
|
+
console.error('[QtWebView] goBack error:', e)
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// Can go forward
|
|
464
|
+
canGoForward() {
|
|
465
|
+
return Promise.resolve(false)
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// Go forward
|
|
469
|
+
goForward() {
|
|
470
|
+
if (this._iframe) {
|
|
471
|
+
try {
|
|
472
|
+
this._iframe.contentWindow.history.forward()
|
|
473
|
+
} catch (e) {
|
|
474
|
+
console.error('[QtWebView] goForward error:', e)
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// Can go back or forward
|
|
480
|
+
canGoBackOrForward(params) {
|
|
481
|
+
return Promise.resolve(false)
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// Go back or forward
|
|
485
|
+
goBackOrForward(params) {
|
|
486
|
+
const steps = Array.isArray(params) ? params[0] : params
|
|
487
|
+
if (this._iframe) {
|
|
488
|
+
try {
|
|
489
|
+
this._iframe.contentWindow.history.go(steps)
|
|
490
|
+
} catch (e) {
|
|
491
|
+
console.error('[QtWebView] goBackOrForward error:', e)
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// On resume
|
|
497
|
+
onResume() {
|
|
498
|
+
console.log('[QtWebView] onResume')
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// On pause
|
|
502
|
+
onPause() {
|
|
503
|
+
console.log('[QtWebView] onPause')
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// Pause timers
|
|
507
|
+
pauseTimers() {
|
|
508
|
+
console.log('[QtWebView] pauseTimers (no-op in web)')
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// Resume timers
|
|
512
|
+
resumeTimers() {
|
|
513
|
+
console.log('[QtWebView] resumeTimers (no-op in web)')
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// Destroy
|
|
517
|
+
destroy() {
|
|
518
|
+
if (this._loadTimeout) {
|
|
519
|
+
clearTimeout(this._loadTimeout)
|
|
520
|
+
this._loadTimeout = null
|
|
521
|
+
}
|
|
522
|
+
if (this._iframe) {
|
|
523
|
+
this._iframe.src = 'about:blank'
|
|
524
|
+
this._iframe.remove()
|
|
525
|
+
this._iframe = null
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// Set JavaScript enabled (no-op in web)
|
|
530
|
+
setJavaScriptEnabled(params) {
|
|
531
|
+
console.log('[QtWebView] setJavaScriptEnabled (always enabled in web)')
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// Set plugin state (no-op in web)
|
|
535
|
+
setPluginState(params) {
|
|
536
|
+
console.log('[QtWebView] setPluginState (no-op in web)')
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// Set JavaScript can open windows automatically (no-op in web)
|
|
540
|
+
setJavaScriptCanOpenWindowsAutomatically(params) {
|
|
541
|
+
console.log('[QtWebView] setJavaScriptCanOpenWindowsAutomatically (no-op in web)')
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// Set use wide view port (no-op in web)
|
|
545
|
+
setUseWideViewPort(params) {
|
|
546
|
+
console.log('[QtWebView] setUseWideViewPort (no-op in web)')
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// Set load with overview mode (no-op in web)
|
|
550
|
+
setLoadWithOverviewMode(params) {
|
|
551
|
+
console.log('[QtWebView] setLoadWithOverviewMode (no-op in web)')
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
// Set support zoom (no-op in web)
|
|
555
|
+
setSupportZoom(params) {
|
|
556
|
+
console.log('[QtWebView] setSupportZoom (no-op in web)')
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// Set built in zoom controls (no-op in web)
|
|
560
|
+
setBuiltInZoomControls(params) {
|
|
561
|
+
console.log('[QtWebView] setBuiltInZoomControls (no-op in web)')
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// Set display zoom controls (no-op in web)
|
|
565
|
+
setDisplayZoomControls(params) {
|
|
566
|
+
console.log('[QtWebView] setDisplayZoomControls (no-op in web)')
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// Set allow file access (no-op in web)
|
|
570
|
+
setAllowFileAccess(params) {
|
|
571
|
+
console.log('[QtWebView] setAllowFileAccess (no-op in web)')
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// Set DOM storage enabled (no-op in web)
|
|
575
|
+
setDomStorageEnabled(params) {
|
|
576
|
+
console.log('[QtWebView] setDomStorageEnabled (always enabled in web)')
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// Set database enabled (no-op in web)
|
|
580
|
+
setDatabaseEnabled(params) {
|
|
581
|
+
console.log('[QtWebView] setDatabaseEnabled (no-op in web)')
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// Set app cache enabled (no-op in web)
|
|
585
|
+
setAppCacheEnabled(params) {
|
|
586
|
+
console.log('[QtWebView] setAppCacheEnabled (no-op in web)')
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
// Set app cache path (no-op in web)
|
|
590
|
+
setAppCachePath(params) {
|
|
591
|
+
console.log('[QtWebView] setAppCachePath (no-op in web)')
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// Set media playback requires user gesture (no-op in web)
|
|
595
|
+
setMediaPlaybackRequiresUserGesture(params) {
|
|
596
|
+
console.log('[QtWebView] setMediaPlaybackRequiresUserGesture (no-op in web)')
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
// Init JavaScript interface
|
|
600
|
+
initJavaScriptInterface() {
|
|
601
|
+
console.log('[QtWebView] initJavaScriptInterface (no-op in web)')
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// Remove JavaScript interface
|
|
605
|
+
removeJavaScriptInterface() {
|
|
606
|
+
console.log('[QtWebView] removeJavaScriptInterface (no-op in web)')
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// Init WebView focus
|
|
610
|
+
initWebViewFocus(params) {
|
|
611
|
+
console.log('[QtWebView] initWebViewFocus (no-op in web)')
|
|
612
|
+
}
|
|
613
|
+
}
|