@react-native-ohos/react-native-webview 13.10.5-rc.1 → 13.10.5-rc.3
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.
|
@@ -28,6 +28,7 @@ import { url as OSUrl } from '@kit.ArkTS';
|
|
|
28
28
|
import { RNC, TM } from './generated';
|
|
29
29
|
import Logger from './Logger';
|
|
30
30
|
import { BaseOperate } from './WebViewBaseOperate';
|
|
31
|
+
import { deviceInfo } from '@kit.BasicServicesKit';
|
|
31
32
|
import {
|
|
32
33
|
AlertEvent,
|
|
33
34
|
CACHE_MODE,
|
|
@@ -309,6 +310,10 @@ export struct RNCWebView {
|
|
|
309
310
|
})
|
|
310
311
|
}
|
|
311
312
|
|
|
313
|
+
if (!this.hasRegisterJavaScriptProxy && this.descriptorWrapper.rawProps.messagingEnabled) {
|
|
314
|
+
this.registerJavaScriptProxyOnly()
|
|
315
|
+
}
|
|
316
|
+
|
|
312
317
|
let baseUrl = this.source.baseUrl
|
|
313
318
|
let uri = this.source.uri
|
|
314
319
|
if (this.source.html != undefined && this.source.html != "") {
|
|
@@ -398,7 +403,7 @@ export struct RNCWebView {
|
|
|
398
403
|
const params = new ShouldStartParams();
|
|
399
404
|
params.lockIdentifier = this.webViewBaseOperate?.getLockIdentifier() || -1
|
|
400
405
|
this.ctx.runOnWorkerThread(new WorkerRunnable(), params);
|
|
401
|
-
this.webViewBaseOperate?.emitShouldStartLoadWithRequest(event)
|
|
406
|
+
this.webViewBaseOperate?.emitShouldStartLoadWithRequest(event, this.source.html, this.source.baseUrl)
|
|
402
407
|
const startTime = Date.now();
|
|
403
408
|
// 当lockState没变化并且小于超时时间,阻塞进程
|
|
404
409
|
while (params.lockState === ShouldOverrideCallbackState.UNDECIDED &&
|
|
@@ -417,78 +422,152 @@ export struct RNCWebView {
|
|
|
417
422
|
|
|
418
423
|
build() {
|
|
419
424
|
Stack() {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
425
|
+
if ( deviceInfo.sdkApiVersion >= 20) {
|
|
426
|
+
Web({ src: "", controller: this.controller, renderMode: this.renderMode })
|
|
427
|
+
.mixedMode(this.mode)
|
|
428
|
+
.onPermissionRequest((event: OnPermissionRequestEvent) => {
|
|
429
|
+
if (event && (this.getPermissionDialogMessage(event) != "TYPE_SENSOR")) {
|
|
430
|
+
AlertDialog.show({
|
|
431
|
+
title: this.resourceToString($r('app.string.on_confirm')) + event.request.getOrigin(),
|
|
432
|
+
message: this.getPermissionDialogMessage(event),
|
|
433
|
+
alignment: DialogAlignment.Center,
|
|
434
|
+
primaryButton: {
|
|
435
|
+
value: $r('app.string.deny'),
|
|
436
|
+
action: () => {
|
|
437
|
+
event.request.deny();
|
|
438
|
+
}
|
|
439
|
+
},
|
|
440
|
+
secondaryButton: {
|
|
441
|
+
value: $r('app.string.on_confirm'),
|
|
442
|
+
action: () => {
|
|
443
|
+
event.request.grant(event.request.getAccessibleResource());
|
|
444
|
+
}
|
|
445
|
+
},
|
|
446
|
+
cancel: () => {
|
|
447
|
+
event.request.deny();
|
|
448
|
+
}
|
|
449
|
+
})
|
|
450
|
+
}
|
|
451
|
+
})
|
|
452
|
+
.width(this.webviewWidth)
|
|
453
|
+
.height(this.webviewHeight)
|
|
454
|
+
.fileAccess(this.allowFileAccess)
|
|
455
|
+
.constraintSize({ minHeight: MINHEIGHT })
|
|
456
|
+
.overScrollMode(this.overScrollMode)
|
|
457
|
+
.javaScriptAccess(this.javaScriptEnable)
|
|
458
|
+
.javaScriptOnDocumentStart(this.injectedJavaScriptBeforeContentLoaded)
|
|
459
|
+
.horizontalScrollBarAccess(this.descriptorWrapper.rawProps.showsHorizontalScrollIndicator)
|
|
460
|
+
.verticalScrollBarAccess(this.descriptorWrapper.rawProps.showsVerticalScrollIndicator)
|
|
461
|
+
.overviewModeAccess(this.descriptorWrapper.rawProps.scalesPageToFit)
|
|
462
|
+
.textZoomRatio(this.descriptorWrapper.rawProps.textZoom)
|
|
463
|
+
.backgroundColor(BaseOperate.getColorMode(this.ctx.uiAbilityContext,
|
|
464
|
+
this.descriptorWrapper.rawProps.forceDarkOn) === WebDarkMode.On ? Color.White : Color.Transparent)
|
|
465
|
+
.darkMode(BaseOperate.getColorMode(this.ctx.uiAbilityContext, this.descriptorWrapper.rawProps.forceDarkOn))
|
|
466
|
+
.forceDarkAccess(this.forceDark)
|
|
467
|
+
.cacheMode(this.cacheMode)
|
|
468
|
+
.minFontSize(this.minFontSize)
|
|
469
|
+
.domStorageAccess(this.descriptorWrapper.rawProps.domStorageEnabled)
|
|
470
|
+
.zoomAccess(this.descriptorWrapper.rawProps.scalesPageToFit)
|
|
471
|
+
.overScrollMode(this.overScrollMode)
|
|
472
|
+
.onProgressChange((event: OnProgressChangeEvent) => this.onProgressChange(event))
|
|
473
|
+
.onScroll((event: OnScrollEvent) => this.webViewBaseOperate?.emitScroll(event))
|
|
474
|
+
.nestedScroll({
|
|
475
|
+
scrollForward: this.nestedScroll,
|
|
476
|
+
scrollBackward: this.nestedScroll,
|
|
477
|
+
})
|
|
478
|
+
.onLoadStarted(() => this.onPageBegin())
|
|
479
|
+
.onLoadFinished(() => this.onPageEnd())
|
|
480
|
+
.onErrorReceive((event: OnErrorReceiveEvent) => this.webViewBaseOperate?.emitLoadingError(event))
|
|
481
|
+
.onHttpErrorReceive((event: OnHttpErrorReceiveEvent) => this.webViewBaseOperate?.emitHttpError(event))
|
|
482
|
+
.onControllerAttached(() => this.controllerAttachedInit())
|
|
483
|
+
.onAlert((event: AlertEvent) => this.onJavascriptAlert(event))
|
|
484
|
+
.onConfirm((event: AlertEvent) => this.onJavascriptConfirm(event))
|
|
485
|
+
.onDownloadStart((event: OnDownloadStartEvent) => this.webViewBaseOperate?.onDownloadStart(event))
|
|
486
|
+
.geolocationAccess(this.descriptorWrapper.rawProps.geolocationEnabled)
|
|
487
|
+
.onGeolocationShow((event) => {
|
|
488
|
+
if (event && (this.descriptorWrapper.rawProps.geolocationEnabled != undefined)) {
|
|
489
|
+
event.geolocation.invoke(event.origin, this.descriptorWrapper.rawProps.geolocationEnabled, true);
|
|
490
|
+
}
|
|
491
|
+
})
|
|
492
|
+
.mediaPlayGestureAccess(this.descriptorWrapper.rawProps.mediaPlaybackRequiresUserAction)
|
|
493
|
+
.onRenderExited((event: OnRenderExitedEvent) => this.webViewBaseOperate?.onRenderExited(event))
|
|
494
|
+
.onLoadIntercept((event: OnLoadInterceptEvent) => this.onLoadIntercept(event))
|
|
495
|
+
.onTitleReceive((event: OnTitleReceiveEvent) => this.webViewBaseOperate?.onTitleReceive(event))
|
|
496
|
+
} else {
|
|
497
|
+
Web({ src: "", controller: this.controller, renderMode: this.renderMode })
|
|
498
|
+
.mixedMode(this.mode)
|
|
499
|
+
.onPermissionRequest((event: OnPermissionRequestEvent) => {
|
|
500
|
+
if (event && (this.getPermissionDialogMessage(event) != "TYPE_SENSOR")) {
|
|
501
|
+
AlertDialog.show({
|
|
502
|
+
title: this.resourceToString($r('app.string.on_confirm')) + event.request.getOrigin(),
|
|
503
|
+
message: this.getPermissionDialogMessage(event),
|
|
504
|
+
alignment: DialogAlignment.Center,
|
|
505
|
+
primaryButton: {
|
|
506
|
+
value: $r('app.string.deny'),
|
|
507
|
+
action: () => {
|
|
508
|
+
event.request.deny();
|
|
509
|
+
}
|
|
510
|
+
},
|
|
511
|
+
secondaryButton: {
|
|
512
|
+
value: $r('app.string.on_confirm'),
|
|
513
|
+
action: () => {
|
|
514
|
+
event.request.grant(event.request.getAccessibleResource());
|
|
515
|
+
}
|
|
516
|
+
},
|
|
517
|
+
cancel: () => {
|
|
518
|
+
event.request.deny();
|
|
519
|
+
}
|
|
520
|
+
})
|
|
442
521
|
}
|
|
443
522
|
})
|
|
444
|
-
}
|
|
445
|
-
})
|
|
446
523
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
524
|
+
.width(this.webviewWidth)
|
|
525
|
+
.height(this.webviewHeight)
|
|
526
|
+
.fileAccess(this.allowFileAccess)
|
|
527
|
+
.constraintSize({ minHeight: MINHEIGHT })
|
|
528
|
+
.overScrollMode(this.overScrollMode)
|
|
529
|
+
.javaScriptAccess(this.javaScriptEnable)
|
|
530
|
+
.javaScriptOnDocumentStart(this.injectedJavaScriptBeforeContentLoaded)
|
|
531
|
+
.horizontalScrollBarAccess(this.descriptorWrapper.rawProps.showsHorizontalScrollIndicator)
|
|
532
|
+
.verticalScrollBarAccess(this.descriptorWrapper.rawProps.showsVerticalScrollIndicator)
|
|
533
|
+
.overviewModeAccess(this.descriptorWrapper.rawProps.scalesPageToFit)
|
|
534
|
+
.textZoomRatio(this.descriptorWrapper.rawProps.textZoom)
|
|
535
|
+
.backgroundColor(BaseOperate.getColorMode(this.ctx.uiAbilityContext,
|
|
536
|
+
this.descriptorWrapper.rawProps.forceDarkOn) === WebDarkMode.On ? Color.White : Color.Transparent)
|
|
537
|
+
.darkMode(BaseOperate.getColorMode(this.ctx.uiAbilityContext, this.descriptorWrapper.rawProps.forceDarkOn))
|
|
538
|
+
.forceDarkAccess(this.forceDark)
|
|
539
|
+
.cacheMode(this.cacheMode)
|
|
540
|
+
.minFontSize(this.minFontSize)
|
|
541
|
+
.domStorageAccess(this.descriptorWrapper.rawProps.domStorageEnabled)
|
|
542
|
+
.zoomAccess(this.descriptorWrapper.rawProps.scalesPageToFit)
|
|
543
|
+
.overScrollMode(this.overScrollMode)
|
|
544
|
+
.onProgressChange((event: OnProgressChangeEvent) => this.onProgressChange(event))
|
|
545
|
+
.onScroll((event: OnScrollEvent) => this.webViewBaseOperate?.emitScroll(event))
|
|
546
|
+
.nestedScroll({
|
|
547
|
+
scrollForward: this.nestedScroll,
|
|
548
|
+
scrollBackward: this.nestedScroll,
|
|
549
|
+
})
|
|
550
|
+
.onPageBegin(() => this.onPageBegin())
|
|
551
|
+
.onPageEnd(() => this.onPageEnd())
|
|
552
|
+
.onErrorReceive((event: OnErrorReceiveEvent) => this.webViewBaseOperate?.emitLoadingError(event))
|
|
553
|
+
.onHttpErrorReceive((event: OnHttpErrorReceiveEvent) => this.webViewBaseOperate?.emitHttpError(event))
|
|
554
|
+
.onControllerAttached(() => this.controllerAttachedInit())
|
|
555
|
+
.onAlert((event: AlertEvent) => this.onJavascriptAlert(event))
|
|
556
|
+
.onConfirm((event: AlertEvent) => this.onJavascriptConfirm(event))
|
|
557
|
+
.onDownloadStart((event: OnDownloadStartEvent) => this.webViewBaseOperate?.onDownloadStart(event))
|
|
558
|
+
.geolocationAccess(this.descriptorWrapper.rawProps.geolocationEnabled)
|
|
559
|
+
.onGeolocationShow((event) => {
|
|
560
|
+
if (event && (this.descriptorWrapper.rawProps.geolocationEnabled != undefined)) {
|
|
561
|
+
event.geolocation.invoke(event.origin, this.descriptorWrapper.rawProps.geolocationEnabled, true);
|
|
562
|
+
}
|
|
563
|
+
})
|
|
564
|
+
.mediaPlayGestureAccess(this.descriptorWrapper.rawProps.mediaPlaybackRequiresUserAction)
|
|
565
|
+
.onRenderExited((event: OnRenderExitedEvent) => this.webViewBaseOperate?.onRenderExited(event))
|
|
566
|
+
.onLoadIntercept((event: OnLoadInterceptEvent) => this.onLoadIntercept(event))
|
|
567
|
+
.onTitleReceive((event: OnTitleReceiveEvent) => this.webViewBaseOperate?.onTitleReceive(event))
|
|
568
|
+
|
|
485
569
|
}
|
|
486
|
-
|
|
487
|
-
.mediaPlayGestureAccess(this.descriptorWrapper.rawProps.mediaPlaybackRequiresUserAction)
|
|
488
|
-
.onRenderExited((event: OnRenderExitedEvent) => this.webViewBaseOperate?.onRenderExited(event))
|
|
489
|
-
.onLoadIntercept((event: OnLoadInterceptEvent) => this.onLoadIntercept(event))
|
|
490
|
-
.onTitleReceive((event: OnTitleReceiveEvent) => this.webViewBaseOperate?.onTitleReceive(event))
|
|
491
|
-
}
|
|
570
|
+
}
|
|
492
571
|
.width(this.webviewWidth)
|
|
493
572
|
.height(this.webviewHeight)
|
|
494
573
|
.position({
|
|
@@ -579,12 +658,41 @@ export struct RNCWebView {
|
|
|
579
658
|
}
|
|
580
659
|
}
|
|
581
660
|
|
|
661
|
+
private registerJavaScriptProxyOnly() {
|
|
662
|
+
if (this.messagingEnabled == this.descriptorWrapper.rawProps.messagingEnabled && this.hasRegisterJavaScriptProxy) {
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
this.messagingEnabled = this.descriptorWrapper.rawProps.messagingEnabled;
|
|
666
|
+
if (this.messagingEnabled) {
|
|
667
|
+
let bridge: RNCWebViewBridge = {
|
|
668
|
+
postMessage: (data: string) => {
|
|
669
|
+
Logger.debug(TAG, `[RNOH] bridge postMessage, ${JSON.stringify(data)}`);
|
|
670
|
+
if (this.controller != null) {
|
|
671
|
+
let result: WebViewEventParams = this.createWebViewEvent("onMessage")
|
|
672
|
+
if (result) {
|
|
673
|
+
result.data = data.toString()
|
|
674
|
+
result.lockIdentifier = this.webViewBaseOperate?.getLockIdentifier()
|
|
675
|
+
this.eventEmitter!.emit("message", result as ResultType);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
};
|
|
680
|
+
this.controller.registerJavaScriptProxy(bridge, JAVASCRIPT_INTERFACE, ["postMessage"])
|
|
681
|
+
this.hasRegisterJavaScriptProxy = true
|
|
682
|
+
Logger.debug(TAG, "[RNOH] JavaScript Proxy registered without reloading page")
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
|
|
582
686
|
private registerPostMessage() {
|
|
583
687
|
if (this.messagingEnabled == this.descriptorWrapper.rawProps.messagingEnabled) {
|
|
584
688
|
return;
|
|
585
689
|
}
|
|
586
690
|
this.messagingEnabled = this.descriptorWrapper.rawProps.messagingEnabled;
|
|
587
691
|
if (this.messagingEnabled) {
|
|
692
|
+
if (this.hasRegisterJavaScriptProxy) {
|
|
693
|
+
Logger.debug(TAG, "[RNOH] JavaScript Proxy already registered")
|
|
694
|
+
return
|
|
695
|
+
}
|
|
588
696
|
let bridge: RNCWebViewBridge = {
|
|
589
697
|
postMessage: (data: string) => {
|
|
590
698
|
Logger.debug(TAG, `[RNOH] bridge postMessage, ${JSON.stringify(data)}`);
|
|
@@ -599,8 +707,13 @@ export struct RNCWebView {
|
|
|
599
707
|
}
|
|
600
708
|
};
|
|
601
709
|
this.controller.registerJavaScriptProxy(bridge, JAVASCRIPT_INTERFACE, ["postMessage"])
|
|
602
|
-
this.source.uri
|
|
603
|
-
|
|
710
|
+
if (this.source.uri && !this.source.html) {
|
|
711
|
+
this.controller.loadUrl(this.source.uri, this.headers)
|
|
712
|
+
} else if (this.source.html) {
|
|
713
|
+
Logger.debug(TAG, "[RNOH] JavaScript Proxy registered, HTML content will use it on next load")
|
|
714
|
+
} else {
|
|
715
|
+
this.controller.refresh()
|
|
716
|
+
}
|
|
604
717
|
this.hasRegisterJavaScriptProxy = true
|
|
605
718
|
}
|
|
606
719
|
}
|
|
@@ -190,10 +190,24 @@ export class BaseOperate {
|
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
-
|
|
193
|
+
verifyURLFormat(url: string, html: string | undefined, baseUrl: string | undefined) {
|
|
194
|
+
const dataUrlPattern = /^data:text\/html;/;
|
|
195
|
+
if (dataUrlPattern.test(url)){
|
|
196
|
+
if (html != undefined && html != "") {
|
|
197
|
+
if (baseUrl != undefined && baseUrl != "") {
|
|
198
|
+
url = baseUrl.toLowerCase();
|
|
199
|
+
} else {
|
|
200
|
+
url = 'about:blank';
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return url;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
emitShouldStartLoadWithRequest(event: OnLoadInterceptEvent, html: string | undefined, baseUrl: string | undefined) {
|
|
194
208
|
try {
|
|
195
209
|
this.eventEmitter!.emit('shouldStartLoadWithRequest', {
|
|
196
|
-
url: event.data.getRequestUrl(),
|
|
210
|
+
url: this.verifyURLFormat(event.data.getRequestUrl(), html, baseUrl),
|
|
197
211
|
loading: false,
|
|
198
212
|
title: this.controller.getTitle(),
|
|
199
213
|
canGoBack: this.controller.accessBackward(),
|
package/harmony/rn_webview.har
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"Thibault Malbranche <malbranche.thibault@gmail.com>"
|
|
10
10
|
],
|
|
11
11
|
"license": "MIT",
|
|
12
|
-
"version": "13.10.5-rc.
|
|
12
|
+
"version": "13.10.5-rc.3",
|
|
13
13
|
"homepage": "https://github.com/react-native-oh-library/react-native-webview#readme",
|
|
14
14
|
"scripts": {
|
|
15
15
|
"macos": "react-native run-macos --scheme WebviewExample --project-path example/macos",
|
|
@@ -37,8 +37,7 @@
|
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"escape-string-regexp": "2.0.0",
|
|
39
39
|
"invariant": "2.2.4",
|
|
40
|
-
"react-native-webview": "13.10.2"
|
|
41
|
-
"yarn": "^1.22.22"
|
|
40
|
+
"react-native-webview": "13.10.2"
|
|
42
41
|
},
|
|
43
42
|
"devDependencies": {
|
|
44
43
|
"@babel/cli": "^7.20.0",
|
|
@@ -54,14 +53,12 @@
|
|
|
54
53
|
"@semantic-release/git": "7.0.16",
|
|
55
54
|
"@types/invariant": "^2.2.30",
|
|
56
55
|
"@types/jest": "^29.5.12",
|
|
57
|
-
"@types/minimatch": "^6.0.0",
|
|
58
56
|
"@types/react": "18.2.61",
|
|
59
57
|
"@types/selenium-webdriver": "4.0.9",
|
|
60
58
|
"appium": "1.17.0",
|
|
61
59
|
"eslint": "8.57.0",
|
|
62
60
|
"jest": "^29.6.3",
|
|
63
61
|
"metro-react-native-babel-preset": "0.73.7",
|
|
64
|
-
"minimatch": "^10.0.3",
|
|
65
62
|
"prettier": "2.8.8",
|
|
66
63
|
"react": "18.2.0",
|
|
67
64
|
"react-native": "0.73.5",
|
|
@@ -92,14 +89,14 @@
|
|
|
92
89
|
],
|
|
93
90
|
"publishConfig": {
|
|
94
91
|
"registry": "https://registry.npmjs.org/",
|
|
95
|
-
|
|
92
|
+
"access": "public"
|
|
96
93
|
},
|
|
97
94
|
"harmony": {
|
|
98
95
|
"alias": "react-native-webview",
|
|
99
96
|
"autolinking": {
|
|
100
|
-
"etsPackageClassName":
|
|
101
|
-
"cppPackageClassName":
|
|
102
|
-
"cmakeLibraryTargetName": "rnoh_webview",
|
|
97
|
+
"etsPackageClassName":"WebViewPackage",
|
|
98
|
+
"cppPackageClassName":"WebViewPackage",
|
|
99
|
+
"cmakeLibraryTargetName": "rnoh_webview",
|
|
103
100
|
"ohPackageName": "@react-native-ohos/react-native-webview"
|
|
104
101
|
}
|
|
105
102
|
},
|