@capgo/capacitor-patch 8.3.3 → 8.3.5
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 +2 -1
- package/patches/catalog.json +278 -0
- package/patches/upstream-pr-7540-ios.patch +84 -0
- package/patches/upstream-pr-8272-core.patch +62 -0
- package/patches/upstream-pr-8274-cli.patch +39 -0
- package/patches/upstream-pr-8284-cli.patch +46 -0
- package/patches/upstream-pr-8364-android.patch +62 -0
- package/patches/upstream-pr-8383-android.patch +26 -0
- package/patches/upstream-pr-8400-android.patch +82 -0
- package/patches/upstream-pr-8403-android.patch +30 -0
- package/patches/upstream-pr-8403-ios.patch +30 -0
- package/patches/upstream-pr-8478-android.patch +212 -0
- package/patches/upstream-pr-8478-ios.patch +159 -0
- package/patches/upstream-pr-8520-ios.patch +46 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capgo/capacitor-patch",
|
|
3
|
-
"version": "8.3.
|
|
3
|
+
"version": "8.3.5",
|
|
4
4
|
"description": "Capacitor plugin for applying vetted Capgo patches during cap sync and cap update.",
|
|
5
5
|
"main": "dist/plugin.cjs.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"watch": "tsc --watch",
|
|
54
54
|
"prepublishOnly": "bun run build",
|
|
55
55
|
"check:wiring": "node scripts/check-capacitor-plugin-wiring.mjs",
|
|
56
|
+
"check:cap9-deprecated": "node scripts/check-cap9-deprecated.mjs",
|
|
56
57
|
"changelog:ai": "node scripts/generate-ai-changelog.mjs"
|
|
57
58
|
},
|
|
58
59
|
"dependencies": {
|
package/patches/catalog.json
CHANGED
|
@@ -206,6 +206,29 @@
|
|
|
206
206
|
},
|
|
207
207
|
"patchFile": "patches/upstream-pr-7535-android.patch"
|
|
208
208
|
},
|
|
209
|
+
{
|
|
210
|
+
"id": "upstream-pr-7540-ios",
|
|
211
|
+
"title": "fix(iOS): change hardcoded config path when using custom config file for auto register plugins (ios)",
|
|
212
|
+
"recommended": false,
|
|
213
|
+
"phase": "package",
|
|
214
|
+
"target": {
|
|
215
|
+
"type": "package",
|
|
216
|
+
"packageName": "@capacitor/ios",
|
|
217
|
+
"versionRange": ">=8.0.0 <9.0.0"
|
|
218
|
+
},
|
|
219
|
+
"source": {
|
|
220
|
+
"upstreamPullRequest": "https://github.com/ionic-team/capacitor/pull/7540",
|
|
221
|
+
"capacitorPlusBranch": "https://github.com/Cap-go/capacitor-plus/tree/sync/upstream-pr-7540",
|
|
222
|
+
"author": "tossaro",
|
|
223
|
+
"authorAssociation": "external"
|
|
224
|
+
},
|
|
225
|
+
"upstream": {
|
|
226
|
+
"state": "open",
|
|
227
|
+
"mergedAt": null,
|
|
228
|
+
"status": "not-merged"
|
|
229
|
+
},
|
|
230
|
+
"patchFile": "patches/upstream-pr-7540-ios.patch"
|
|
231
|
+
},
|
|
209
232
|
{
|
|
210
233
|
"id": "upstream-pr-7599-ios",
|
|
211
234
|
"title": "fix(ios): allow enabling gesture navigation via config (#3808) (ios)",
|
|
@@ -505,6 +528,52 @@
|
|
|
505
528
|
},
|
|
506
529
|
"patchFile": "patches/upstream-pr-8271-core.patch"
|
|
507
530
|
},
|
|
531
|
+
{
|
|
532
|
+
"id": "upstream-pr-8272-core",
|
|
533
|
+
"title": "fix(core): fix buildUrlParams array handling and replace deprecated substr (core)",
|
|
534
|
+
"recommended": false,
|
|
535
|
+
"phase": "package",
|
|
536
|
+
"target": {
|
|
537
|
+
"type": "package",
|
|
538
|
+
"packageName": "@capacitor/core",
|
|
539
|
+
"versionRange": ">=8.0.0 <9.0.0"
|
|
540
|
+
},
|
|
541
|
+
"source": {
|
|
542
|
+
"upstreamPullRequest": "https://github.com/ionic-team/capacitor/pull/8272",
|
|
543
|
+
"capacitorPlusBranch": "https://github.com/Cap-go/capacitor-plus/tree/sync/upstream-pr-8272",
|
|
544
|
+
"author": "maniktyagi04",
|
|
545
|
+
"authorAssociation": "external"
|
|
546
|
+
},
|
|
547
|
+
"upstream": {
|
|
548
|
+
"state": "open",
|
|
549
|
+
"mergedAt": null,
|
|
550
|
+
"status": "not-merged"
|
|
551
|
+
},
|
|
552
|
+
"patchFile": "patches/upstream-pr-8272-core.patch"
|
|
553
|
+
},
|
|
554
|
+
{
|
|
555
|
+
"id": "upstream-pr-8274-cli",
|
|
556
|
+
"title": "feat: Enable copying native resource files from Capacitor plugins to … (cli)",
|
|
557
|
+
"recommended": false,
|
|
558
|
+
"phase": "package",
|
|
559
|
+
"target": {
|
|
560
|
+
"type": "package",
|
|
561
|
+
"packageName": "@capacitor/cli",
|
|
562
|
+
"versionRange": ">=8.0.0 <9.0.0"
|
|
563
|
+
},
|
|
564
|
+
"source": {
|
|
565
|
+
"upstreamPullRequest": "https://github.com/ionic-team/capacitor/pull/8274",
|
|
566
|
+
"capacitorPlusBranch": "https://github.com/Cap-go/capacitor-plus/tree/sync/upstream-pr-8274",
|
|
567
|
+
"author": "White-D-coder",
|
|
568
|
+
"authorAssociation": "external"
|
|
569
|
+
},
|
|
570
|
+
"upstream": {
|
|
571
|
+
"state": "open",
|
|
572
|
+
"mergedAt": null,
|
|
573
|
+
"status": "not-merged"
|
|
574
|
+
},
|
|
575
|
+
"patchFile": "patches/upstream-pr-8274-cli.patch"
|
|
576
|
+
},
|
|
508
577
|
{
|
|
509
578
|
"id": "upstream-pr-8275-android",
|
|
510
579
|
"title": "fix(android): preserve file chooser callback across activity recreation (android)",
|
|
@@ -528,6 +597,29 @@
|
|
|
528
597
|
},
|
|
529
598
|
"patchFile": "patches/upstream-pr-8275-android.patch"
|
|
530
599
|
},
|
|
600
|
+
{
|
|
601
|
+
"id": "upstream-pr-8284-cli",
|
|
602
|
+
"title": "feat: allow spm platforms to select os without being overwritten (cli)",
|
|
603
|
+
"recommended": false,
|
|
604
|
+
"phase": "package",
|
|
605
|
+
"target": {
|
|
606
|
+
"type": "package",
|
|
607
|
+
"packageName": "@capacitor/cli",
|
|
608
|
+
"versionRange": ">=8.0.0 <9.0.0"
|
|
609
|
+
},
|
|
610
|
+
"source": {
|
|
611
|
+
"upstreamPullRequest": "https://github.com/ionic-team/capacitor/pull/8284",
|
|
612
|
+
"capacitorPlusBranch": "https://github.com/Cap-go/capacitor-plus/tree/sync/upstream-pr-8284",
|
|
613
|
+
"author": "WcaleNieWolny",
|
|
614
|
+
"authorAssociation": "external"
|
|
615
|
+
},
|
|
616
|
+
"upstream": {
|
|
617
|
+
"state": "open",
|
|
618
|
+
"mergedAt": null,
|
|
619
|
+
"status": "not-merged"
|
|
620
|
+
},
|
|
621
|
+
"patchFile": "patches/upstream-pr-8284-cli.patch"
|
|
622
|
+
},
|
|
531
623
|
{
|
|
532
624
|
"id": "upstream-pr-8304-ios",
|
|
533
625
|
"title": "fix(http): Fix throwing data URI requests on iOS (ios)",
|
|
@@ -551,6 +643,121 @@
|
|
|
551
643
|
},
|
|
552
644
|
"patchFile": "patches/upstream-pr-8304-ios.patch"
|
|
553
645
|
},
|
|
646
|
+
{
|
|
647
|
+
"id": "upstream-pr-8364-android",
|
|
648
|
+
"title": "Add method to disable autosuggestion (android)",
|
|
649
|
+
"recommended": false,
|
|
650
|
+
"phase": "package",
|
|
651
|
+
"target": {
|
|
652
|
+
"type": "package",
|
|
653
|
+
"packageName": "@capacitor/android",
|
|
654
|
+
"versionRange": ">=8.0.0 <9.0.0"
|
|
655
|
+
},
|
|
656
|
+
"source": {
|
|
657
|
+
"upstreamPullRequest": "https://github.com/ionic-team/capacitor/pull/8364",
|
|
658
|
+
"capacitorPlusBranch": "https://github.com/Cap-go/capacitor-plus/tree/sync/upstream-pr-8364",
|
|
659
|
+
"author": "tyilo",
|
|
660
|
+
"authorAssociation": "external"
|
|
661
|
+
},
|
|
662
|
+
"upstream": {
|
|
663
|
+
"state": "open",
|
|
664
|
+
"mergedAt": null,
|
|
665
|
+
"status": "not-merged"
|
|
666
|
+
},
|
|
667
|
+
"patchFile": "patches/upstream-pr-8364-android.patch"
|
|
668
|
+
},
|
|
669
|
+
{
|
|
670
|
+
"id": "upstream-pr-8383-android",
|
|
671
|
+
"title": "fix(android): allow synchronous replies on the modern bridge (android)",
|
|
672
|
+
"recommended": false,
|
|
673
|
+
"phase": "package",
|
|
674
|
+
"target": {
|
|
675
|
+
"type": "package",
|
|
676
|
+
"packageName": "@capacitor/android",
|
|
677
|
+
"versionRange": ">=8.0.0 <9.0.0"
|
|
678
|
+
},
|
|
679
|
+
"source": {
|
|
680
|
+
"upstreamPullRequest": "https://github.com/ionic-team/capacitor/pull/8383",
|
|
681
|
+
"capacitorPlusBranch": "https://github.com/Cap-go/capacitor-plus/tree/sync/upstream-pr-8383",
|
|
682
|
+
"author": "richavos",
|
|
683
|
+
"authorAssociation": "external"
|
|
684
|
+
},
|
|
685
|
+
"upstream": {
|
|
686
|
+
"state": "open",
|
|
687
|
+
"mergedAt": null,
|
|
688
|
+
"status": "not-merged"
|
|
689
|
+
},
|
|
690
|
+
"patchFile": "patches/upstream-pr-8383-android.patch"
|
|
691
|
+
},
|
|
692
|
+
{
|
|
693
|
+
"id": "upstream-pr-8400-android",
|
|
694
|
+
"title": "fix(android): add null check for plugin annotation in getPermissionStates (android)",
|
|
695
|
+
"recommended": false,
|
|
696
|
+
"phase": "package",
|
|
697
|
+
"target": {
|
|
698
|
+
"type": "package",
|
|
699
|
+
"packageName": "@capacitor/android",
|
|
700
|
+
"versionRange": ">=8.0.0 <9.0.0"
|
|
701
|
+
},
|
|
702
|
+
"source": {
|
|
703
|
+
"upstreamPullRequest": "https://github.com/ionic-team/capacitor/pull/8400",
|
|
704
|
+
"capacitorPlusBranch": "https://github.com/Cap-go/capacitor-plus/tree/sync/upstream-pr-8400",
|
|
705
|
+
"author": "robingenz",
|
|
706
|
+
"authorAssociation": "external"
|
|
707
|
+
},
|
|
708
|
+
"upstream": {
|
|
709
|
+
"state": "open",
|
|
710
|
+
"mergedAt": null,
|
|
711
|
+
"status": "not-merged"
|
|
712
|
+
},
|
|
713
|
+
"patchFile": "patches/upstream-pr-8400-android.patch"
|
|
714
|
+
},
|
|
715
|
+
{
|
|
716
|
+
"id": "upstream-pr-8403-android",
|
|
717
|
+
"title": "fix(http): correctly serialize Blob objects in request bodies and FormData (android)",
|
|
718
|
+
"recommended": false,
|
|
719
|
+
"phase": "package",
|
|
720
|
+
"target": {
|
|
721
|
+
"type": "package",
|
|
722
|
+
"packageName": "@capacitor/android",
|
|
723
|
+
"versionRange": ">=8.0.0 <9.0.0"
|
|
724
|
+
},
|
|
725
|
+
"source": {
|
|
726
|
+
"upstreamPullRequest": "https://github.com/ionic-team/capacitor/pull/8403",
|
|
727
|
+
"capacitorPlusBranch": "https://github.com/Cap-go/capacitor-plus/tree/sync/upstream-pr-8403",
|
|
728
|
+
"author": "vamsi2246",
|
|
729
|
+
"authorAssociation": "external"
|
|
730
|
+
},
|
|
731
|
+
"upstream": {
|
|
732
|
+
"state": "open",
|
|
733
|
+
"mergedAt": null,
|
|
734
|
+
"status": "not-merged"
|
|
735
|
+
},
|
|
736
|
+
"patchFile": "patches/upstream-pr-8403-android.patch"
|
|
737
|
+
},
|
|
738
|
+
{
|
|
739
|
+
"id": "upstream-pr-8403-ios",
|
|
740
|
+
"title": "fix(http): correctly serialize Blob objects in request bodies and FormData (ios)",
|
|
741
|
+
"recommended": false,
|
|
742
|
+
"phase": "package",
|
|
743
|
+
"target": {
|
|
744
|
+
"type": "package",
|
|
745
|
+
"packageName": "@capacitor/ios",
|
|
746
|
+
"versionRange": ">=8.0.0 <9.0.0"
|
|
747
|
+
},
|
|
748
|
+
"source": {
|
|
749
|
+
"upstreamPullRequest": "https://github.com/ionic-team/capacitor/pull/8403",
|
|
750
|
+
"capacitorPlusBranch": "https://github.com/Cap-go/capacitor-plus/tree/sync/upstream-pr-8403",
|
|
751
|
+
"author": "vamsi2246",
|
|
752
|
+
"authorAssociation": "external"
|
|
753
|
+
},
|
|
754
|
+
"upstream": {
|
|
755
|
+
"state": "open",
|
|
756
|
+
"mergedAt": null,
|
|
757
|
+
"status": "not-merged"
|
|
758
|
+
},
|
|
759
|
+
"patchFile": "patches/upstream-pr-8403-ios.patch"
|
|
760
|
+
},
|
|
554
761
|
{
|
|
555
762
|
"id": "upstream-pr-8418-android",
|
|
556
763
|
"title": "fix(android): range request truncation (android)",
|
|
@@ -667,5 +874,76 @@
|
|
|
667
874
|
"status": "not-merged-as-of-2026-05-12"
|
|
668
875
|
},
|
|
669
876
|
"patchFile": "patches/upstream-pr-8458-cli.patch"
|
|
877
|
+
},
|
|
878
|
+
{
|
|
879
|
+
"id": "upstream-pr-8478-android",
|
|
880
|
+
"title": "fix(http): support binary request bodies (android)",
|
|
881
|
+
"recommended": false,
|
|
882
|
+
"supersedes": ["upstream-pr-8403-android"],
|
|
883
|
+
"phase": "package",
|
|
884
|
+
"target": {
|
|
885
|
+
"type": "package",
|
|
886
|
+
"packageName": "@capacitor/android",
|
|
887
|
+
"versionRange": ">=8.0.0 <9.0.0"
|
|
888
|
+
},
|
|
889
|
+
"source": {
|
|
890
|
+
"upstreamPullRequest": "https://github.com/ionic-team/capacitor/pull/8478",
|
|
891
|
+
"capacitorPlusBranch": "https://github.com/Cap-go/capacitor-plus/tree/sync/upstream-pr-8478",
|
|
892
|
+
"author": "iamanaws",
|
|
893
|
+
"authorAssociation": "external"
|
|
894
|
+
},
|
|
895
|
+
"upstream": {
|
|
896
|
+
"state": "open",
|
|
897
|
+
"mergedAt": null,
|
|
898
|
+
"status": "not-merged"
|
|
899
|
+
},
|
|
900
|
+
"patchFile": "patches/upstream-pr-8478-android.patch"
|
|
901
|
+
},
|
|
902
|
+
{
|
|
903
|
+
"id": "upstream-pr-8478-ios",
|
|
904
|
+
"title": "fix(http): support binary request bodies (ios)",
|
|
905
|
+
"recommended": false,
|
|
906
|
+
"supersedes": ["upstream-pr-8403-ios"],
|
|
907
|
+
"phase": "package",
|
|
908
|
+
"target": {
|
|
909
|
+
"type": "package",
|
|
910
|
+
"packageName": "@capacitor/ios",
|
|
911
|
+
"versionRange": ">=8.0.0 <9.0.0"
|
|
912
|
+
},
|
|
913
|
+
"source": {
|
|
914
|
+
"upstreamPullRequest": "https://github.com/ionic-team/capacitor/pull/8478",
|
|
915
|
+
"capacitorPlusBranch": "https://github.com/Cap-go/capacitor-plus/tree/sync/upstream-pr-8478",
|
|
916
|
+
"author": "iamanaws",
|
|
917
|
+
"authorAssociation": "external"
|
|
918
|
+
},
|
|
919
|
+
"upstream": {
|
|
920
|
+
"state": "open",
|
|
921
|
+
"mergedAt": null,
|
|
922
|
+
"status": "not-merged"
|
|
923
|
+
},
|
|
924
|
+
"patchFile": "patches/upstream-pr-8478-ios.patch"
|
|
925
|
+
},
|
|
926
|
+
{
|
|
927
|
+
"id": "upstream-pr-8520-ios",
|
|
928
|
+
"title": "fix(ios): retain WKHTTPCookieStore observer so cookie sync works (ios)",
|
|
929
|
+
"recommended": false,
|
|
930
|
+
"phase": "package",
|
|
931
|
+
"target": {
|
|
932
|
+
"type": "package",
|
|
933
|
+
"packageName": "@capacitor/ios",
|
|
934
|
+
"versionRange": ">=8.0.0 <9.0.0"
|
|
935
|
+
},
|
|
936
|
+
"source": {
|
|
937
|
+
"upstreamPullRequest": "https://github.com/ionic-team/capacitor/pull/8520",
|
|
938
|
+
"capacitorPlusBranch": "https://github.com/Cap-go/capacitor-plus/tree/sync/upstream-pr-8520",
|
|
939
|
+
"author": "Cybertron01Z",
|
|
940
|
+
"authorAssociation": "external"
|
|
941
|
+
},
|
|
942
|
+
"upstream": {
|
|
943
|
+
"state": "open",
|
|
944
|
+
"mergedAt": null,
|
|
945
|
+
"status": "not-merged"
|
|
946
|
+
},
|
|
947
|
+
"patchFile": "patches/upstream-pr-8520-ios.patch"
|
|
670
948
|
}
|
|
671
949
|
]
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
diff --git a/Capacitor/Capacitor/CAPInstanceConfiguration.h b/Capacitor/Capacitor/CAPInstanceConfiguration.h
|
|
2
|
+
index 171dbb46..ac52df02 100644
|
|
3
|
+
--- a/Capacitor/Capacitor/CAPInstanceConfiguration.h
|
|
4
|
+
+++ b/Capacitor/Capacitor/CAPInstanceConfiguration.h
|
|
5
|
+
@@ -13,6 +13,7 @@ NS_SWIFT_NAME(InstanceConfiguration)
|
|
6
|
+
@property (nonatomic, readonly, nonnull) NSArray<NSString*> *allowedNavigationHostnames;
|
|
7
|
+
@property (nonatomic, readonly, nonnull) NSURL *localURL;
|
|
8
|
+
@property (nonatomic, readonly, nonnull) NSURL *serverURL;
|
|
9
|
+
+@property (nonatomic, readonly, nullable) NSURL *configURL;
|
|
10
|
+
@property (nonatomic, readonly, nullable) NSString *errorPath;
|
|
11
|
+
@property (nonatomic, readonly, nonnull) NSDictionary *pluginConfigurations;
|
|
12
|
+
@property (nonatomic, readonly) BOOL loggingEnabled;
|
|
13
|
+
diff --git a/Capacitor/Capacitor/CAPInstanceConfiguration.m b/Capacitor/Capacitor/CAPInstanceConfiguration.m
|
|
14
|
+
index d6b7785e..a8e2c0f1 100644
|
|
15
|
+
--- a/Capacitor/Capacitor/CAPInstanceConfiguration.m
|
|
16
|
+
+++ b/Capacitor/Capacitor/CAPInstanceConfiguration.m
|
|
17
|
+
@@ -49,6 +49,13 @@
|
|
18
|
+
else {
|
|
19
|
+
_serverURL = _localURL;
|
|
20
|
+
}
|
|
21
|
+
+
|
|
22
|
+
+ if (descriptor.configUrl != nil) {
|
|
23
|
+
+ _configURL = descriptor.configUrl;
|
|
24
|
+
+ }
|
|
25
|
+
+ else {
|
|
26
|
+
+ _configURL = [[NSBundle mainBundle] URLForResource:@"capacitor.config" withExtension:@"json"];
|
|
27
|
+
+ }
|
|
28
|
+
_errorPath = descriptor.errorPath;
|
|
29
|
+
// extract the one value we care about from the cordova configuration
|
|
30
|
+
_cordovaDeployDisabled = [descriptor cordovaDeployDisabled];
|
|
31
|
+
@@ -63,6 +70,7 @@
|
|
32
|
+
_allowedNavigationHostnames = [[configuration allowedNavigationHostnames] copy];
|
|
33
|
+
_localURL = [[configuration localURL] copy];
|
|
34
|
+
_serverURL = [[configuration serverURL] copy];
|
|
35
|
+
+ _configURL = [[configuration configURL] copy];
|
|
36
|
+
_errorPath = [[configuration errorPath] copy];
|
|
37
|
+
_pluginConfigurations = [[configuration pluginConfigurations] copy];
|
|
38
|
+
_loggingEnabled = configuration.loggingEnabled;
|
|
39
|
+
diff --git a/Capacitor/Capacitor/CAPInstanceDescriptor.h b/Capacitor/Capacitor/CAPInstanceDescriptor.h
|
|
40
|
+
index f477ef55..d4d02203 100644
|
|
41
|
+
--- a/Capacitor/Capacitor/CAPInstanceDescriptor.h
|
|
42
|
+
+++ b/Capacitor/Capacitor/CAPInstanceDescriptor.h
|
|
43
|
+
@@ -68,6 +68,11 @@ NS_SWIFT_NAME(InstanceDescriptor)
|
|
44
|
+
@discussion Defaults to nil, in which case the server URL will be constructed from @c urlScheme and @c urlHostname. If set, it will override the other properties. Set by @c server.url in the configuration file.
|
|
45
|
+
*/
|
|
46
|
+
@property (nonatomic, copy, nullable) NSString *serverURL;
|
|
47
|
+
+/**
|
|
48
|
+
+ @brief The file URL from which Capacitor will load configuration
|
|
49
|
+
+ @discussion Defaults to @c capacitor.config.json located at the root of the application bundle.
|
|
50
|
+
+ */
|
|
51
|
+
+@property (nonatomic, copy, nullable) NSURL *configUrl;
|
|
52
|
+
/**
|
|
53
|
+
@brief The JSON dictionary that contains the plugin-specific configuration information.
|
|
54
|
+
@discussion Set by @c plugins in the configuration file.
|
|
55
|
+
diff --git a/Capacitor/Capacitor/CAPInstanceDescriptor.swift b/Capacitor/Capacitor/CAPInstanceDescriptor.swift
|
|
56
|
+
index a7eff5f6..db8c8f7d 100644
|
|
57
|
+
--- a/Capacitor/Capacitor/CAPInstanceDescriptor.swift
|
|
58
|
+
+++ b/Capacitor/Capacitor/CAPInstanceDescriptor.swift
|
|
59
|
+
@@ -30,6 +30,8 @@ internal extension InstanceDescriptor {
|
|
60
|
+
// swiftlint:disable function_body_length
|
|
61
|
+
// swiftlint:disable:next identifier_name
|
|
62
|
+
@objc func _parseConfiguration(at capacitorURL: URL?, cordovaConfiguration cordovaURL: URL?) {
|
|
63
|
+
+ configUrl = capacitorURL
|
|
64
|
+
+
|
|
65
|
+
// sanity check that the app directory is valid
|
|
66
|
+
var isDirectory: ObjCBool = ObjCBool(false)
|
|
67
|
+
if warnings.contains(.missingAppDir) == false,
|
|
68
|
+
diff --git a/Capacitor/Capacitor/CapacitorBridge.swift b/Capacitor/Capacitor/CapacitorBridge.swift
|
|
69
|
+
index 7b8b9b99..c4a91e2a 100644
|
|
70
|
+
--- a/Capacitor/Capacitor/CapacitorBridge.swift
|
|
71
|
+
+++ b/Capacitor/Capacitor/CapacitorBridge.swift
|
|
72
|
+
@@ -306,8 +306,10 @@
|
|
73
|
+
|
|
74
|
+
if autoRegisterPlugins {
|
|
75
|
+
do {
|
|
76
|
+
- if let pluginJSON = Bundle.main.url(forResource: "capacitor.config", withExtension: "json") {
|
|
77
|
+
- let pluginData = try Data(contentsOf: pluginJSON)
|
|
78
|
+
+ let configFileURL = (config.configURL?.isFileURL == true ? config.configURL : nil)
|
|
79
|
+
+ ?? Bundle.main.url(forResource: "capacitor.config", withExtension: "json")
|
|
80
|
+
+ if let configFileURL = configFileURL {
|
|
81
|
+
+ let pluginData = try Data(contentsOf: configFileURL)
|
|
82
|
+
let registrationList = try JSONDecoder().decode(RegistrationList.self, from: pluginData)
|
|
83
|
+
|
|
84
|
+
for plugin in registrationList.packageClassList {
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
diff --git a/dist/index.cjs.js b/dist/index.cjs.js
|
|
2
|
+
index 34d371f..e1f2a3b 100644
|
|
3
|
+
--- a/dist/index.cjs.js
|
|
4
|
+
+++ b/dist/index.cjs.js
|
|
5
|
+
@@ -435,13 +435,16 @@
|
|
6
|
+
let encodedValue;
|
|
7
|
+
let item;
|
|
8
|
+
if (Array.isArray(value)) {
|
|
9
|
+
+ if (value.length === 0) {
|
|
10
|
+
+ return accumulator;
|
|
11
|
+
+ }
|
|
12
|
+
item = '';
|
|
13
|
+
value.forEach((str) => {
|
|
14
|
+
encodedValue = shouldEncode ? encodeURIComponent(str) : str;
|
|
15
|
+
item += `${key}=${encodedValue}&`;
|
|
16
|
+
});
|
|
17
|
+
// last character will always be "&" so slice it off
|
|
18
|
+
- item.slice(0, -1);
|
|
19
|
+
+ item = item.slice(0, -1);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
encodedValue = shouldEncode ? encodeURIComponent(value) : value;
|
|
23
|
+
@@ -450,7 +453,7 @@
|
|
24
|
+
return `${accumulator}&${item}`;
|
|
25
|
+
}, '');
|
|
26
|
+
// Remove initial "&" from the reduce
|
|
27
|
+
- return output.substr(1);
|
|
28
|
+
+ return output.substring(1);
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Build the RequestInit object based on the options passed into the initial request
|
|
32
|
+
diff --git a/dist/index.js b/dist/index.js
|
|
33
|
+
index fb980f2..f4e5d6c 100644
|
|
34
|
+
--- a/dist/index.js
|
|
35
|
+
+++ b/dist/index.js
|
|
36
|
+
@@ -431,13 +431,16 @@
|
|
37
|
+
let encodedValue;
|
|
38
|
+
let item;
|
|
39
|
+
if (Array.isArray(value)) {
|
|
40
|
+
+ if (value.length === 0) {
|
|
41
|
+
+ return accumulator;
|
|
42
|
+
+ }
|
|
43
|
+
item = '';
|
|
44
|
+
value.forEach((str) => {
|
|
45
|
+
encodedValue = shouldEncode ? encodeURIComponent(str) : str;
|
|
46
|
+
item += `${key}=${encodedValue}&`;
|
|
47
|
+
});
|
|
48
|
+
// last character will always be "&" so slice it off
|
|
49
|
+
- item.slice(0, -1);
|
|
50
|
+
+ item = item.slice(0, -1);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
encodedValue = shouldEncode ? encodeURIComponent(value) : value;
|
|
54
|
+
@@ -446,7 +449,7 @@
|
|
55
|
+
return `${accumulator}&${item}`;
|
|
56
|
+
}, '');
|
|
57
|
+
// Remove initial "&" from the reduce
|
|
58
|
+
- return output.substr(1);
|
|
59
|
+
+ return output.substring(1);
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Build the RequestInit object based on the options passed into the initial request
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
diff --git a/dist/android/update.js b/dist/android/update.js
|
|
2
|
+
index 5e3b058..a3f4b5c 100644
|
|
3
|
+
--- a/dist/android/update.js
|
|
4
|
+
+++ b/dist/android/update.js
|
|
5
|
+
@@ -28,6 +28,7 @@ async function updateAndroid(config) {
|
|
6
|
+
if (cordovaPlugins.length > 0) {
|
|
7
|
+
await copyPluginsNativeFiles(config, cordovaPlugins);
|
|
8
|
+
}
|
|
9
|
+
+ await copyPluginsNativeFiles(config, capacitorPlugins);
|
|
10
|
+
if (!(await (0, fs_extra_1.pathExists)(config.android.webDirAbs))) {
|
|
11
|
+
await (0, copy_1.copy)(config, platform);
|
|
12
|
+
}
|
|
13
|
+
diff --git a/dist/plugin.js b/dist/plugin.js
|
|
14
|
+
index 3be0fa0..db03dd0 100644
|
|
15
|
+
--- a/dist/plugin.js
|
|
16
|
+
+++ b/dist/plugin.js
|
|
17
|
+
@@ -38,6 +38,10 @@ async function resolvePlugin(config, name) {
|
|
18
|
+
if (!meta) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
+ const pluginXMLPath = (0, path_1.join)(rootPath, 'plugin.xml');
|
|
22
|
+
+ const xmlMeta = (await (0, fs_extra_1.pathExists)(pluginXMLPath))
|
|
23
|
+
+ ? await (0, xml_1.readXML)(pluginXMLPath)
|
|
24
|
+
+ : null;
|
|
25
|
+
if (meta.capacitor) {
|
|
26
|
+
return {
|
|
27
|
+
id: name,
|
|
28
|
+
@@ -46,10 +50,9 @@ async function resolvePlugin(config, name) {
|
|
29
|
+
rootPath,
|
|
30
|
+
repository: meta.repository,
|
|
31
|
+
manifest: meta.capacitor,
|
|
32
|
+
+ xml: xmlMeta ? xmlMeta.plugin : undefined,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
- const pluginXMLPath = (0, path_1.join)(rootPath, 'plugin.xml');
|
|
36
|
+
- const xmlMeta = await (0, xml_1.readXML)(pluginXMLPath);
|
|
37
|
+
return {
|
|
38
|
+
id: name,
|
|
39
|
+
name: fixName(name),
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
diff --git a/dist/util/spm.js b/dist/util/spm.js
|
|
2
|
+
index 81877e7..169e9d0 100644
|
|
3
|
+
--- a/dist/util/spm.js
|
|
4
|
+
+++ b/dist/util/spm.js
|
|
5
|
+
@@ -86,7 +86,7 @@
|
|
6
|
+
async function generatePackageText(config, plugins) {
|
|
7
|
+
var _a, _b, _c;
|
|
8
|
+
const iosPlatformVersion = await (0, common_1.getCapacitorPackageVersion)(config, config.ios.name);
|
|
9
|
+
- const iosVersion = (0, common_2.getMajoriOSVersion)(config);
|
|
10
|
+
+ const iosVersion = (0, common_2.getMajorMinoriOSVersion)(config);
|
|
11
|
+
let packageSwiftText = `// swift-tools-version: 5.9
|
|
12
|
+
import PackageDescription
|
|
13
|
+
|
|
14
|
+
diff --git a/dist/ios/common.js b/dist/ios/common.js
|
|
15
|
+
index 8e5a1b2..f3c2d8e 100644
|
|
16
|
+
--- a/dist/ios/common.js
|
|
17
|
+
+++ b/dist/ios/common.js
|
|
18
|
+
@@ -114,3 +114,28 @@
|
|
19
|
+
return iosVersion;
|
|
20
|
+
}
|
|
21
|
+
exports.getMajoriOSVersion = getMajoriOSVersion;
|
|
22
|
+
+
|
|
23
|
+
+function getMajorMinoriOSVersion(config) {
|
|
24
|
+
+ const pbx = (0, fs_extra_1.readFileSync)((0, path_1.join)(config.ios.nativeXcodeProjDirAbs, 'project.pbxproj'), 'utf-8');
|
|
25
|
+
+ const searchString = 'IPHONEOS_DEPLOYMENT_TARGET = ';
|
|
26
|
+
+ const startIndex = pbx.indexOf(searchString);
|
|
27
|
+
+ if (startIndex === -1) {
|
|
28
|
+
+ return '';
|
|
29
|
+
+ }
|
|
30
|
+
+ const valueStart = startIndex + searchString.length;
|
|
31
|
+
+ const endIndex = pbx.indexOf(';', valueStart);
|
|
32
|
+
+ const newlineIndex = pbx.indexOf('\n', valueStart);
|
|
33
|
+
+ const actualEnd = endIndex !== -1 && newlineIndex !== -1
|
|
34
|
+
+ ? Math.min(endIndex, newlineIndex)
|
|
35
|
+
+ : endIndex !== -1
|
|
36
|
+
+ ? endIndex
|
|
37
|
+
+ : newlineIndex !== -1
|
|
38
|
+
+ ? newlineIndex
|
|
39
|
+
+ : pbx.length;
|
|
40
|
+
+ let iosVersion = pbx.substring(valueStart, actualEnd).trim();
|
|
41
|
+
+ if (iosVersion.endsWith('.0')) {
|
|
42
|
+
+ iosVersion = iosVersion.slice(0, -2);
|
|
43
|
+
+ }
|
|
44
|
+
+ return iosVersion;
|
|
45
|
+
+}
|
|
46
|
+
+exports.getMajorMinoriOSVersion = getMajorMinoriOSVersion;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
diff --git a/capacitor/src/main/java/com/getcapacitor/CapacitorWebView.java b/capacitor/src/main/java/com/getcapacitor/CapacitorWebView.java
|
|
2
|
+
index 22f6f972..d30529b7 100644
|
|
3
|
+
--- a/capacitor/src/main/java/com/getcapacitor/CapacitorWebView.java
|
|
4
|
+
+++ b/capacitor/src/main/java/com/getcapacitor/CapacitorWebView.java
|
|
5
|
+
@@ -2,6 +2,7 @@ package com.getcapacitor;
|
|
6
|
+
|
|
7
|
+
import android.content.Context;
|
|
8
|
+
import android.os.Build;
|
|
9
|
+
+import android.text.InputType;
|
|
10
|
+
+import android.view.inputmethod.InputMethodManager;
|
|
11
|
+
import android.util.AttributeSet;
|
|
12
|
+
import android.util.TypedValue;
|
|
13
|
+
import android.view.KeyEvent;
|
|
14
|
+
@@ -17,6 +18,7 @@ public class CapacitorWebView extends WebView {
|
|
15
|
+
|
|
16
|
+
private BaseInputConnection capInputConnection;
|
|
17
|
+
private Bridge bridge;
|
|
18
|
+
+ private boolean autosuggestionEnabled = true;
|
|
19
|
+
|
|
20
|
+
public CapacitorWebView(Context context, AttributeSet attrs) {
|
|
21
|
+
super(context, attrs);
|
|
22
|
+
@@ -26,6 +28,10 @@ public class CapacitorWebView extends WebView {
|
|
23
|
+
this.bridge = bridge;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
+ public void setAutosuggestionEnabled(boolean enabled) {
|
|
27
|
+
+ autosuggestionEnabled = enabled;
|
|
28
|
+
+ InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
|
29
|
+
+ if (imm != null) {
|
|
30
|
+
+ imm.restartInput(this);
|
|
31
|
+
+ }
|
|
32
|
+
+ }
|
|
33
|
+
+
|
|
34
|
+
@Override
|
|
35
|
+
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
|
|
36
|
+
CapConfig config;
|
|
37
|
+
@@ -36,13 +42,23 @@ public class CapacitorWebView extends WebView {
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
boolean captureInput = config.isInputCaptured();
|
|
41
|
+
+ InputConnection inputConnection;
|
|
42
|
+
if (captureInput) {
|
|
43
|
+
if (capInputConnection == null) {
|
|
44
|
+
capInputConnection = new BaseInputConnection(this, false);
|
|
45
|
+
}
|
|
46
|
+
- return capInputConnection;
|
|
47
|
+
+ inputConnection = capInputConnection;
|
|
48
|
+
+ } else {
|
|
49
|
+
+ inputConnection = super.onCreateInputConnection(outAttrs);
|
|
50
|
+
}
|
|
51
|
+
- return super.onCreateInputConnection(outAttrs);
|
|
52
|
+
+
|
|
53
|
+
+ if (!autosuggestionEnabled) {
|
|
54
|
+
+ // See https://stackoverflow.com/a/28009054/640584
|
|
55
|
+
+ outAttrs.inputType &= ~EditorInfo.TYPE_MASK_VARIATION;
|
|
56
|
+
+ outAttrs.inputType |= InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD;
|
|
57
|
+
+ }
|
|
58
|
+
+
|
|
59
|
+
+ return inputConnection;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@Override
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
diff --git a/capacitor/src/main/java/com/getcapacitor/MessageHandler.java b/capacitor/src/main/java/com/getcapacitor/MessageHandler.java
|
|
2
|
+
index dc91c9b0..1499deec 100644
|
|
3
|
+
--- a/capacitor/src/main/java/com/getcapacitor/MessageHandler.java
|
|
4
|
+
+++ b/capacitor/src/main/java/com/getcapacitor/MessageHandler.java
|
|
5
|
+
@@ -26,8 +26,7 @@ public class MessageHandler {
|
|
6
|
+
if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER) && !bridge.getConfig().isUsingLegacyBridge()) {
|
|
7
|
+
WebViewCompat.WebMessageListener capListener = (view, message, sourceOrigin, isMainFrame, replyProxy) -> {
|
|
8
|
+
if (isMainFrame) {
|
|
9
|
+
- postMessage(message.getData());
|
|
10
|
+
- javaScriptReplyProxy = replyProxy;
|
|
11
|
+
+ onModernBridgeMessage(message.getData(), replyProxy);
|
|
12
|
+
} else {
|
|
13
|
+
Logger.warn("Plugin execution is allowed in Main Frame only");
|
|
14
|
+
}
|
|
15
|
+
@@ -42,6 +41,11 @@ public class MessageHandler {
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
+ void onModernBridgeMessage(String data, JavaScriptReplyProxy replyProxy) {
|
|
20
|
+
+ javaScriptReplyProxy = replyProxy;
|
|
21
|
+
+ postMessage(data);
|
|
22
|
+
+ }
|
|
23
|
+
+
|
|
24
|
+
/**
|
|
25
|
+
* The main message handler that will be called from JavaScript
|
|
26
|
+
* to send a message to the native bridge.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
diff --git a/capacitor/src/main/java/com/getcapacitor/Bridge.java b/capacitor/src/main/java/com/getcapacitor/Bridge.java
|
|
2
|
+
index d4995fbb..32eebd73 100644
|
|
3
|
+
--- a/capacitor/src/main/java/com/getcapacitor/Bridge.java
|
|
4
|
+
+++ b/capacitor/src/main/java/com/getcapacitor/Bridge.java
|
|
5
|
+
@@ -1214,42 +1214,44 @@ public class Bridge {
|
|
6
|
+
protected Map<String, PermissionState> getPermissionStates(Plugin plugin) {
|
|
7
|
+
Map<String, PermissionState> permissionsResults = new HashMap<>();
|
|
8
|
+
CapacitorPlugin annotation = plugin.getPluginHandle().getPluginAnnotation();
|
|
9
|
+
- for (Permission perm : annotation.permissions()) {
|
|
10
|
+
- // If a permission is defined with no permission constants, return GRANTED for it.
|
|
11
|
+
- // Otherwise, get its true state.
|
|
12
|
+
- if (perm.strings().length == 0 || (perm.strings().length == 1 && perm.strings()[0].isEmpty())) {
|
|
13
|
+
- String key = perm.alias();
|
|
14
|
+
- if (!key.isEmpty()) {
|
|
15
|
+
- PermissionState existingResult = permissionsResults.get(key);
|
|
16
|
+
-
|
|
17
|
+
- // auto set permission state to GRANTED if the alias is empty.
|
|
18
|
+
- if (existingResult == null) {
|
|
19
|
+
- permissionsResults.put(key, PermissionState.GRANTED);
|
|
20
|
+
- }
|
|
21
|
+
- }
|
|
22
|
+
- } else {
|
|
23
|
+
- for (String permString : perm.strings()) {
|
|
24
|
+
- String key = perm.alias().isEmpty() ? permString : perm.alias();
|
|
25
|
+
- PermissionState permissionStatus;
|
|
26
|
+
- if (ActivityCompat.checkSelfPermission(this.getContext(), permString) == PackageManager.PERMISSION_GRANTED) {
|
|
27
|
+
- permissionStatus = PermissionState.GRANTED;
|
|
28
|
+
- } else {
|
|
29
|
+
- permissionStatus = PermissionState.PROMPT;
|
|
30
|
+
-
|
|
31
|
+
- // Check if there is a cached permission state for the "Never ask again" state
|
|
32
|
+
- SharedPreferences prefs = getContext().getSharedPreferences(PERMISSION_PREFS_NAME, Activity.MODE_PRIVATE);
|
|
33
|
+
- String state = prefs.getString(permString, null);
|
|
34
|
+
-
|
|
35
|
+
- if (state != null) {
|
|
36
|
+
- permissionStatus = PermissionState.byState(state);
|
|
37
|
+
+ if (annotation != null) {
|
|
38
|
+
+ for (Permission perm : annotation.permissions()) {
|
|
39
|
+
+ // If a permission is defined with no permission constants, return GRANTED for it.
|
|
40
|
+
+ // Otherwise, get its true state.
|
|
41
|
+
+ if (perm.strings().length == 0 || (perm.strings().length == 1 && perm.strings()[0].isEmpty())) {
|
|
42
|
+
+ String key = perm.alias();
|
|
43
|
+
+ if (!key.isEmpty()) {
|
|
44
|
+
+ PermissionState existingResult = permissionsResults.get(key);
|
|
45
|
+
+
|
|
46
|
+
+ // auto set permission state to GRANTED if the alias is empty.
|
|
47
|
+
+ if (existingResult == null) {
|
|
48
|
+
+ permissionsResults.put(key, PermissionState.GRANTED);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
+ } else {
|
|
52
|
+
+ for (String permString : perm.strings()) {
|
|
53
|
+
+ String key = perm.alias().isEmpty() ? permString : perm.alias();
|
|
54
|
+
+ PermissionState permissionStatus;
|
|
55
|
+
+ if (ActivityCompat.checkSelfPermission(this.getContext(), permString) == PackageManager.PERMISSION_GRANTED) {
|
|
56
|
+
+ permissionStatus = PermissionState.GRANTED;
|
|
57
|
+
+ } else {
|
|
58
|
+
+ permissionStatus = PermissionState.PROMPT;
|
|
59
|
+
+
|
|
60
|
+
+ // Check if there is a cached permission state for the "Never ask again" state
|
|
61
|
+
+ SharedPreferences prefs = getContext().getSharedPreferences(PERMISSION_PREFS_NAME, Activity.MODE_PRIVATE);
|
|
62
|
+
+ String state = prefs.getString(permString, null);
|
|
63
|
+
+
|
|
64
|
+
+ if (state != null) {
|
|
65
|
+
+ permissionStatus = PermissionState.byState(state);
|
|
66
|
+
+ }
|
|
67
|
+
+ }
|
|
68
|
+
|
|
69
|
+
- PermissionState existingResult = permissionsResults.get(key);
|
|
70
|
+
+ PermissionState existingResult = permissionsResults.get(key);
|
|
71
|
+
|
|
72
|
+
- // multiple permissions with the same alias must all be true, otherwise all false.
|
|
73
|
+
- if (existingResult == null || existingResult == PermissionState.GRANTED) {
|
|
74
|
+
- permissionsResults.put(key, permissionStatus);
|
|
75
|
+
+ // multiple permissions with the same alias must all be true, otherwise all false.
|
|
76
|
+
+ if (existingResult == null || existingResult == PermissionState.GRANTED) {
|
|
77
|
+
+ permissionsResults.put(key, permissionStatus);
|
|
78
|
+
+ }
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
+ }
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
diff --git a/capacitor/src/main/assets/native-bridge.js b/capacitor/src/main/assets/native-bridge.js
|
|
2
|
+
index f5e7cc44..000b49a9 100644
|
|
3
|
+
--- a/capacitor/src/main/assets/native-bridge.js
|
|
4
|
+
+++ b/capacitor/src/main/assets/native-bridge.js
|
|
5
|
+
@@ -48,14 +48,14 @@ var nativeBridge = (function (exports) {
|
|
6
|
+
const newFormData = [];
|
|
7
|
+
for (const pair of formData.entries()) {
|
|
8
|
+
const [key, value] = pair;
|
|
9
|
+
- if (value instanceof File) {
|
|
10
|
+
+ if (typeof Blob !== 'undefined' && value instanceof Blob) {
|
|
11
|
+
const base64File = await readFileAsBase64(value);
|
|
12
|
+
newFormData.push({
|
|
13
|
+
key,
|
|
14
|
+
value: base64File,
|
|
15
|
+
type: 'base64File',
|
|
16
|
+
contentType: value.type,
|
|
17
|
+
- fileName: value.name,
|
|
18
|
+
+ fileName: value.name || 'blob',
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
@@ -128,7 +128,7 @@ var nativeBridge = (function (exports) {
|
|
23
|
+
type: 'formData',
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
- else if (body instanceof File) {
|
|
27
|
+
+ else if (typeof Blob !== 'undefined' && body instanceof Blob) {
|
|
28
|
+
const fileData = await readFileAsBase64(body);
|
|
29
|
+
return {
|
|
30
|
+
data: fileData,
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
diff --git a/Capacitor/Capacitor/assets/native-bridge.js b/Capacitor/Capacitor/assets/native-bridge.js
|
|
2
|
+
index f5e7cc44..000b49a9 100644
|
|
3
|
+
--- a/Capacitor/Capacitor/assets/native-bridge.js
|
|
4
|
+
+++ b/Capacitor/Capacitor/assets/native-bridge.js
|
|
5
|
+
@@ -48,14 +48,14 @@ var nativeBridge = (function (exports) {
|
|
6
|
+
const newFormData = [];
|
|
7
|
+
for (const pair of formData.entries()) {
|
|
8
|
+
const [key, value] = pair;
|
|
9
|
+
- if (value instanceof File) {
|
|
10
|
+
+ if (typeof Blob !== 'undefined' && value instanceof Blob) {
|
|
11
|
+
const base64File = await readFileAsBase64(value);
|
|
12
|
+
newFormData.push({
|
|
13
|
+
key,
|
|
14
|
+
value: base64File,
|
|
15
|
+
type: 'base64File',
|
|
16
|
+
contentType: value.type,
|
|
17
|
+
- fileName: value.name,
|
|
18
|
+
+ fileName: value.name || 'blob',
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
@@ -128,7 +128,7 @@ var nativeBridge = (function (exports) {
|
|
23
|
+
type: 'formData',
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
- else if (body instanceof File) {
|
|
27
|
+
+ else if (typeof Blob !== 'undefined' && body instanceof Blob) {
|
|
28
|
+
const fileData = await readFileAsBase64(body);
|
|
29
|
+
return {
|
|
30
|
+
data: fileData,
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
diff --git a/capacitor/src/main/assets/native-bridge.js b/capacitor/src/main/assets/native-bridge.js
|
|
2
|
+
index f5e7cc44..742cf3f 100644
|
|
3
|
+
--- a/capacitor/src/main/assets/native-bridge.js
|
|
4
|
+
+++ b/capacitor/src/main/assets/native-bridge.js
|
|
5
|
+
@@ -44,18 +44,45 @@
|
|
6
|
+
reader.onerror = reject;
|
|
7
|
+
reader.readAsBinaryString(file);
|
|
8
|
+
});
|
|
9
|
+
+ const readArrayBufferAsBase64 = (arrayBuffer) => {
|
|
10
|
+
+ const bytes = new Uint8Array(arrayBuffer);
|
|
11
|
+
+ const chunkSize = 0x8000;
|
|
12
|
+
+ let binary = '';
|
|
13
|
+
+ for (let i = 0; i < bytes.length; i += chunkSize) {
|
|
14
|
+
+ binary += String.fromCharCode(...bytes.subarray(i, i + chunkSize));
|
|
15
|
+
+ }
|
|
16
|
+
+ return btoa(binary);
|
|
17
|
+
+ };
|
|
18
|
+
+ const readBlobAsBase64 = (blob) => new Promise((resolve, reject) => {
|
|
19
|
+
+ const reader = new FileReader();
|
|
20
|
+
+ reader.onload = () => {
|
|
21
|
+
+ const result = reader.result;
|
|
22
|
+
+ resolve(result.indexOf(',') >= 0 ? result.split(',')[1] : result);
|
|
23
|
+
+ };
|
|
24
|
+
+ reader.onerror = reject;
|
|
25
|
+
+ reader.readAsDataURL(blob);
|
|
26
|
+
+ });
|
|
27
|
+
+ const readDataViewAsBase64 = (dataView) => readArrayBufferAsBase64(dataView.buffer.slice(dataView.byteOffset, dataView.byteOffset + dataView.byteLength));
|
|
28
|
+
+ const base64StringToArrayBuffer = (base64) => {
|
|
29
|
+
+ const binary = atob(base64);
|
|
30
|
+
+ const bytes = new Uint8Array(binary.length);
|
|
31
|
+
+ for (let i = 0; i < binary.length; i++) {
|
|
32
|
+
+ bytes[i] = binary.charCodeAt(i);
|
|
33
|
+
+ }
|
|
34
|
+
+ return bytes.buffer;
|
|
35
|
+
+ };
|
|
36
|
+
const convertFormData = async (formData) => {
|
|
37
|
+
const newFormData = [];
|
|
38
|
+
for (const pair of formData.entries()) {
|
|
39
|
+
const [key, value] = pair;
|
|
40
|
+
- if (value instanceof File) {
|
|
41
|
+
+ if (typeof Blob !== 'undefined' && value instanceof Blob) {
|
|
42
|
+
const base64File = await readFileAsBase64(value);
|
|
43
|
+
newFormData.push({
|
|
44
|
+
key,
|
|
45
|
+
value: base64File,
|
|
46
|
+
type: 'base64File',
|
|
47
|
+
contentType: value.type,
|
|
48
|
+
- fileName: value.name,
|
|
49
|
+
+ fileName: value.name || 'blob',
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
@@ -65,9 +92,31 @@
|
|
54
|
+
return newFormData;
|
|
55
|
+
};
|
|
56
|
+
const convertBody = async (body, contentType) => {
|
|
57
|
+
- if (body instanceof ReadableStream || body instanceof Uint8Array) {
|
|
58
|
+
+ if (body instanceof File) {
|
|
59
|
+
+ const fileData = await readFileAsBase64(body);
|
|
60
|
+
+ return {
|
|
61
|
+
+ data: fileData,
|
|
62
|
+
+ type: 'file',
|
|
63
|
+
+ headers: { 'Content-Type': body.type },
|
|
64
|
+
+ };
|
|
65
|
+
+ }
|
|
66
|
+
+ else if (typeof Blob !== 'undefined' && body instanceof Blob) {
|
|
67
|
+
+ return {
|
|
68
|
+
+ data: await readBlobAsBase64(body),
|
|
69
|
+
+ type: 'binary',
|
|
70
|
+
+ headers: { 'Content-Type': contentType || body.type || 'application/octet-stream' },
|
|
71
|
+
+ };
|
|
72
|
+
+ }
|
|
73
|
+
+ else if (body instanceof ArrayBuffer) {
|
|
74
|
+
+ return {
|
|
75
|
+
+ data: readArrayBufferAsBase64(body),
|
|
76
|
+
+ type: 'binary',
|
|
77
|
+
+ headers: { 'Content-Type': contentType || 'application/octet-stream' },
|
|
78
|
+
+ };
|
|
79
|
+
+ }
|
|
80
|
+
+ if ((typeof ReadableStream !== 'undefined' && body instanceof ReadableStream) || body instanceof Uint8Array) {
|
|
81
|
+
let encodedData;
|
|
82
|
+
- if (body instanceof ReadableStream) {
|
|
83
|
+
+ if (typeof ReadableStream !== 'undefined' && body instanceof ReadableStream) {
|
|
84
|
+
const reader = body.getReader();
|
|
85
|
+
const chunks = [];
|
|
86
|
+
while (true) {
|
|
87
|
+
@@ -87,7 +136,9 @@
|
|
88
|
+
else {
|
|
89
|
+
encodedData = body;
|
|
90
|
+
}
|
|
91
|
+
- let data = new TextDecoder().decode(encodedData);
|
|
92
|
+
+ let data = (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('image')) || contentType === 'application/octet-stream'
|
|
93
|
+
+ ? readDataViewAsBase64(encodedData)
|
|
94
|
+
+ : new TextDecoder().decode(encodedData);
|
|
95
|
+
let type;
|
|
96
|
+
if (contentType === 'application/json') {
|
|
97
|
+
try {
|
|
98
|
+
@@ -102,7 +153,7 @@
|
|
99
|
+
type = 'formData';
|
|
100
|
+
}
|
|
101
|
+
else if (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('image')) {
|
|
102
|
+
- type = 'image';
|
|
103
|
+
+ type = 'binary';
|
|
104
|
+
}
|
|
105
|
+
else if (contentType === 'application/octet-stream') {
|
|
106
|
+
type = 'binary';
|
|
107
|
+
@@ -128,14 +179,6 @@
|
|
108
|
+
type: 'formData',
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
- else if (body instanceof File) {
|
|
112
|
+
- const fileData = await readFileAsBase64(body);
|
|
113
|
+
- return {
|
|
114
|
+
- data: fileData,
|
|
115
|
+
- type: 'file',
|
|
116
|
+
- headers: { 'Content-Type': body.type },
|
|
117
|
+
- };
|
|
118
|
+
- }
|
|
119
|
+
return { data: body, type: 'json' };
|
|
120
|
+
};
|
|
121
|
+
const CAPACITOR_HTTP_INTERCEPTOR = '/_capacitor_http_interceptor_';
|
|
122
|
+
@@ -531,15 +574,18 @@
|
|
123
|
+
data: requestData,
|
|
124
|
+
dataType: type,
|
|
125
|
+
headers: nativeHeaders,
|
|
126
|
+
+ responseType: 'arraybuffer',
|
|
127
|
+
});
|
|
128
|
+
const contentType = nativeResponse.headers['Content-Type'] || nativeResponse.headers['content-type'];
|
|
129
|
+
- let data = (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('application/json'))
|
|
130
|
+
- ? JSON.stringify(nativeResponse.data)
|
|
131
|
+
- : nativeResponse.data;
|
|
132
|
+
// use null data for 204 No Content HTTP response
|
|
133
|
+
- if (nativeResponse.status === 204) {
|
|
134
|
+
- data = null;
|
|
135
|
+
- }
|
|
136
|
+
+ const normalizedContentType = contentType === null || contentType === void 0 ? void 0 : contentType.toLowerCase();
|
|
137
|
+
+ const data = nativeResponse.status === 204
|
|
138
|
+
+ ? null
|
|
139
|
+
+ : (normalizedContentType === null || normalizedContentType === void 0 ? void 0 : normalizedContentType.startsWith('application/json'))
|
|
140
|
+
+ ? JSON.stringify(nativeResponse.data)
|
|
141
|
+
+ : typeof nativeResponse.data === 'string'
|
|
142
|
+
+ ? base64StringToArrayBuffer(nativeResponse.data)
|
|
143
|
+
+ : base64StringToArrayBuffer(String(nativeResponse.data));
|
|
144
|
+
// intercept & parse response before returning
|
|
145
|
+
const response = new Response(data, {
|
|
146
|
+
headers: nativeResponse.headers,
|
|
147
|
+
diff --git a/capacitor/src/main/java/com/getcapacitor/plugin/util/CapacitorHttpUrlConnection.java b/capacitor/src/main/java/com/getcapacitor/plugin/util/CapacitorHttpUrlConnection.java
|
|
148
|
+
index 6180d642..c2f966ae 100644
|
|
149
|
+
--- a/capacitor/src/main/java/com/getcapacitor/plugin/util/CapacitorHttpUrlConnection.java
|
|
150
|
+
+++ b/capacitor/src/main/java/com/getcapacitor/plugin/util/CapacitorHttpUrlConnection.java
|
|
151
|
+
@@ -1,6 +1,5 @@
|
|
152
|
+
package com.getcapacitor.plugin.util;
|
|
153
|
+
|
|
154
|
+
-import android.os.Build;
|
|
155
|
+
import android.os.LocaleList;
|
|
156
|
+
import android.text.TextUtils;
|
|
157
|
+
import com.getcapacitor.Bridge;
|
|
158
|
+
@@ -19,7 +18,6 @@ import java.net.URL;
|
|
159
|
+
import java.net.URLEncoder;
|
|
160
|
+
import java.net.UnknownServiceException;
|
|
161
|
+
import java.nio.charset.StandardCharsets;
|
|
162
|
+
-import java.util.Base64;
|
|
163
|
+
import java.util.Iterator;
|
|
164
|
+
import java.util.List;
|
|
165
|
+
import java.util.Locale;
|
|
166
|
+
@@ -209,13 +207,8 @@ public class CapacitorHttpUrlConnection implements ICapacitorHttpUrlConnection {
|
|
167
|
+
dataString = call.getString("data");
|
|
168
|
+
}
|
|
169
|
+
this.writeRequestBody(dataString != null ? dataString : "");
|
|
170
|
+
- } else if (bodyType != null && bodyType.equals("file")) {
|
|
171
|
+
- try (DataOutputStream os = new DataOutputStream(connection.getOutputStream())) {
|
|
172
|
+
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
173
|
+
- os.write(Base64.getDecoder().decode(body.toString()));
|
|
174
|
+
- }
|
|
175
|
+
- os.flush();
|
|
176
|
+
- }
|
|
177
|
+
+ } else if (bodyType != null && (bodyType.equals("file") || bodyType.equals("binary"))) {
|
|
178
|
+
+ this.writeRequestBody(decodeBase64RequestBody(body.toString()));
|
|
179
|
+
} else if (contentType.contains("application/x-www-form-urlencoded")) {
|
|
180
|
+
try {
|
|
181
|
+
JSObject obj = body.toJSObject();
|
|
182
|
+
@@ -252,6 +245,17 @@ public class CapacitorHttpUrlConnection implements ICapacitorHttpUrlConnection {
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
+ private void writeRequestBody(byte[] body) throws IOException {
|
|
187
|
+
+ try (DataOutputStream os = new DataOutputStream(connection.getOutputStream())) {
|
|
188
|
+
+ os.write(body);
|
|
189
|
+
+ os.flush();
|
|
190
|
+
+ }
|
|
191
|
+
+ }
|
|
192
|
+
+
|
|
193
|
+
+ private static byte[] decodeBase64RequestBody(String body) {
|
|
194
|
+
+ return android.util.Base64.decode(body, android.util.Base64.DEFAULT);
|
|
195
|
+
+ }
|
|
196
|
+
+
|
|
197
|
+
private void writeObjectRequestBody(JSObject object) throws IOException, JSONException {
|
|
198
|
+
try (DataOutputStream os = new DataOutputStream(connection.getOutputStream())) {
|
|
199
|
+
Iterator<String> keys = object.keys();
|
|
200
|
+
@@ -296,11 +300,7 @@ public class CapacitorHttpUrlConnection implements ICapacitorHttpUrlConnection {
|
|
201
|
+
os.writeBytes("Content-Transfer-Encoding: binary" + lineEnd);
|
|
202
|
+
os.writeBytes(lineEnd);
|
|
203
|
+
|
|
204
|
+
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
205
|
+
- os.write(Base64.getDecoder().decode(value));
|
|
206
|
+
- } else {
|
|
207
|
+
- os.write(android.util.Base64.decode(value, android.util.Base64.DEFAULT));
|
|
208
|
+
- }
|
|
209
|
+
+ os.write(decodeBase64RequestBody(value));
|
|
210
|
+
|
|
211
|
+
os.writeBytes(lineEnd);
|
|
212
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
diff --git a/Capacitor/Capacitor/Plugins/CapacitorUrlRequest.swift b/Capacitor/Capacitor/Plugins/CapacitorUrlRequest.swift
|
|
2
|
+
index 34433368..8308c3d7 100644
|
|
3
|
+
--- a/Capacitor/Capacitor/Plugins/CapacitorUrlRequest.swift
|
|
4
|
+
+++ b/Capacitor/Capacitor/Plugins/CapacitorUrlRequest.swift
|
|
5
|
+
@@ -172,7 +172,7 @@ open class CapacitorUrlRequest: NSObject, URLSessionTaskDelegate {
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
public func getRequestData(_ body: JSValue, _ contentType: String, _ dataType: String? = nil) throws -> Data? {
|
|
9
|
+
- if dataType == "file" {
|
|
10
|
+
+ if dataType == "file" || dataType == "binary" {
|
|
11
|
+
guard let stringData = body as? String else {
|
|
12
|
+
throw CapacitorUrlRequestError.serializationError("[ data ] argument could not be parsed as string")
|
|
13
|
+
}
|
|
14
|
+
diff --git a/Capacitor/Capacitor/assets/native-bridge.js b/Capacitor/Capacitor/assets/native-bridge.js
|
|
15
|
+
index f5e7cc44..742cf3f 100644
|
|
16
|
+
--- a/Capacitor/Capacitor/assets/native-bridge.js
|
|
17
|
+
+++ b/Capacitor/Capacitor/assets/native-bridge.js
|
|
18
|
+
@@ -44,18 +44,45 @@
|
|
19
|
+
reader.onerror = reject;
|
|
20
|
+
reader.readAsBinaryString(file);
|
|
21
|
+
});
|
|
22
|
+
+ const readArrayBufferAsBase64 = (arrayBuffer) => {
|
|
23
|
+
+ const bytes = new Uint8Array(arrayBuffer);
|
|
24
|
+
+ const chunkSize = 0x8000;
|
|
25
|
+
+ let binary = '';
|
|
26
|
+
+ for (let i = 0; i < bytes.length; i += chunkSize) {
|
|
27
|
+
+ binary += String.fromCharCode(...bytes.subarray(i, i + chunkSize));
|
|
28
|
+
+ }
|
|
29
|
+
+ return btoa(binary);
|
|
30
|
+
+ };
|
|
31
|
+
+ const readBlobAsBase64 = (blob) => new Promise((resolve, reject) => {
|
|
32
|
+
+ const reader = new FileReader();
|
|
33
|
+
+ reader.onload = () => {
|
|
34
|
+
+ const result = reader.result;
|
|
35
|
+
+ resolve(result.indexOf(',') >= 0 ? result.split(',')[1] : result);
|
|
36
|
+
+ };
|
|
37
|
+
+ reader.onerror = reject;
|
|
38
|
+
+ reader.readAsDataURL(blob);
|
|
39
|
+
+ });
|
|
40
|
+
+ const readDataViewAsBase64 = (dataView) => readArrayBufferAsBase64(dataView.buffer.slice(dataView.byteOffset, dataView.byteOffset + dataView.byteLength));
|
|
41
|
+
+ const base64StringToArrayBuffer = (base64) => {
|
|
42
|
+
+ const binary = atob(base64);
|
|
43
|
+
+ const bytes = new Uint8Array(binary.length);
|
|
44
|
+
+ for (let i = 0; i < binary.length; i++) {
|
|
45
|
+
+ bytes[i] = binary.charCodeAt(i);
|
|
46
|
+
+ }
|
|
47
|
+
+ return bytes.buffer;
|
|
48
|
+
+ };
|
|
49
|
+
const convertFormData = async (formData) => {
|
|
50
|
+
const newFormData = [];
|
|
51
|
+
for (const pair of formData.entries()) {
|
|
52
|
+
const [key, value] = pair;
|
|
53
|
+
- if (value instanceof File) {
|
|
54
|
+
+ if (typeof Blob !== 'undefined' && value instanceof Blob) {
|
|
55
|
+
const base64File = await readFileAsBase64(value);
|
|
56
|
+
newFormData.push({
|
|
57
|
+
key,
|
|
58
|
+
value: base64File,
|
|
59
|
+
type: 'base64File',
|
|
60
|
+
contentType: value.type,
|
|
61
|
+
- fileName: value.name,
|
|
62
|
+
+ fileName: value.name || 'blob',
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
@@ -65,9 +92,31 @@
|
|
67
|
+
return newFormData;
|
|
68
|
+
};
|
|
69
|
+
const convertBody = async (body, contentType) => {
|
|
70
|
+
- if (body instanceof ReadableStream || body instanceof Uint8Array) {
|
|
71
|
+
+ if (body instanceof File) {
|
|
72
|
+
+ const fileData = await readFileAsBase64(body);
|
|
73
|
+
+ return {
|
|
74
|
+
+ data: fileData,
|
|
75
|
+
+ type: 'file',
|
|
76
|
+
+ headers: { 'Content-Type': body.type },
|
|
77
|
+
+ };
|
|
78
|
+
+ }
|
|
79
|
+
+ else if (typeof Blob !== 'undefined' && body instanceof Blob) {
|
|
80
|
+
+ return {
|
|
81
|
+
+ data: await readBlobAsBase64(body),
|
|
82
|
+
+ type: 'binary',
|
|
83
|
+
+ headers: { 'Content-Type': contentType || body.type || 'application/octet-stream' },
|
|
84
|
+
+ };
|
|
85
|
+
+ }
|
|
86
|
+
+ else if (body instanceof ArrayBuffer) {
|
|
87
|
+
+ return {
|
|
88
|
+
+ data: readArrayBufferAsBase64(body),
|
|
89
|
+
+ type: 'binary',
|
|
90
|
+
+ headers: { 'Content-Type': contentType || 'application/octet-stream' },
|
|
91
|
+
+ };
|
|
92
|
+
+ }
|
|
93
|
+
+ if ((typeof ReadableStream !== 'undefined' && body instanceof ReadableStream) || body instanceof Uint8Array) {
|
|
94
|
+
let encodedData;
|
|
95
|
+
- if (body instanceof ReadableStream) {
|
|
96
|
+
+ if (typeof ReadableStream !== 'undefined' && body instanceof ReadableStream) {
|
|
97
|
+
const reader = body.getReader();
|
|
98
|
+
const chunks = [];
|
|
99
|
+
while (true) {
|
|
100
|
+
@@ -87,7 +136,9 @@
|
|
101
|
+
else {
|
|
102
|
+
encodedData = body;
|
|
103
|
+
}
|
|
104
|
+
- let data = new TextDecoder().decode(encodedData);
|
|
105
|
+
+ let data = (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('image')) || contentType === 'application/octet-stream'
|
|
106
|
+
+ ? readDataViewAsBase64(encodedData)
|
|
107
|
+
+ : new TextDecoder().decode(encodedData);
|
|
108
|
+
let type;
|
|
109
|
+
if (contentType === 'application/json') {
|
|
110
|
+
try {
|
|
111
|
+
@@ -102,7 +153,7 @@
|
|
112
|
+
type = 'formData';
|
|
113
|
+
}
|
|
114
|
+
else if (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('image')) {
|
|
115
|
+
- type = 'image';
|
|
116
|
+
+ type = 'binary';
|
|
117
|
+
}
|
|
118
|
+
else if (contentType === 'application/octet-stream') {
|
|
119
|
+
type = 'binary';
|
|
120
|
+
@@ -128,14 +179,6 @@
|
|
121
|
+
type: 'formData',
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
- else if (body instanceof File) {
|
|
125
|
+
- const fileData = await readFileAsBase64(body);
|
|
126
|
+
- return {
|
|
127
|
+
- data: fileData,
|
|
128
|
+
- type: 'file',
|
|
129
|
+
- headers: { 'Content-Type': body.type },
|
|
130
|
+
- };
|
|
131
|
+
- }
|
|
132
|
+
return { data: body, type: 'json' };
|
|
133
|
+
};
|
|
134
|
+
const CAPACITOR_HTTP_INTERCEPTOR = '/_capacitor_http_interceptor_';
|
|
135
|
+
@@ -531,15 +574,18 @@
|
|
136
|
+
data: requestData,
|
|
137
|
+
dataType: type,
|
|
138
|
+
headers: nativeHeaders,
|
|
139
|
+
+ responseType: 'arraybuffer',
|
|
140
|
+
});
|
|
141
|
+
const contentType = nativeResponse.headers['Content-Type'] || nativeResponse.headers['content-type'];
|
|
142
|
+
- let data = (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('application/json'))
|
|
143
|
+
- ? JSON.stringify(nativeResponse.data)
|
|
144
|
+
- : nativeResponse.data;
|
|
145
|
+
// use null data for 204 No Content HTTP response
|
|
146
|
+
- if (nativeResponse.status === 204) {
|
|
147
|
+
- data = null;
|
|
148
|
+
- }
|
|
149
|
+
+ const normalizedContentType = contentType === null || contentType === void 0 ? void 0 : contentType.toLowerCase();
|
|
150
|
+
+ const data = nativeResponse.status === 204
|
|
151
|
+
+ ? null
|
|
152
|
+
+ : (normalizedContentType === null || normalizedContentType === void 0 ? void 0 : normalizedContentType.startsWith('application/json'))
|
|
153
|
+
+ ? JSON.stringify(nativeResponse.data)
|
|
154
|
+
+ : typeof nativeResponse.data === 'string'
|
|
155
|
+
+ ? base64StringToArrayBuffer(nativeResponse.data)
|
|
156
|
+
+ : base64StringToArrayBuffer(String(nativeResponse.data));
|
|
157
|
+
// intercept & parse response before returning
|
|
158
|
+
const response = new Response(data, {
|
|
159
|
+
headers: nativeResponse.headers,
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
diff --git a/Capacitor/Capacitor/CAPBridgeViewController.swift b/Capacitor/Capacitor/CAPBridgeViewController.swift
|
|
2
|
+
index a7285213..8d8cf088 100644
|
|
3
|
+
--- a/Capacitor/Capacitor/CAPBridgeViewController.swift
|
|
4
|
+
+++ b/Capacitor/Capacitor/CAPBridgeViewController.swift
|
|
5
|
+
@@ -10,6 +10,12 @@ import Cordova
|
|
6
|
+
|
|
7
|
+
public fileprivate(set) var webView: WKWebView?
|
|
8
|
+
|
|
9
|
+
+ // WKHTTPCookieStore does not retain observers, so we hold a strong reference here
|
|
10
|
+
+ // (else it deallocs immediately and `cookiesDidChange` never fires) plus the store
|
|
11
|
+
+ // it was added to, so the observer can be removed in `deinit` as the docs require.
|
|
12
|
+
+ private var cookieObserver: CapacitorWKCookieObserver?
|
|
13
|
+
+ private var cookieObserverStore: WKHTTPCookieStore?
|
|
14
|
+
+
|
|
15
|
+
public var isStatusBarVisible = true
|
|
16
|
+
public var statusBarStyle: UIStatusBarStyle = .default
|
|
17
|
+
public var statusBarAnimation: UIStatusBarAnimation = .fade
|
|
18
|
+
@@ -27,6 +33,12 @@ import Cordova
|
|
19
|
+
return false
|
|
20
|
+
}()
|
|
21
|
+
|
|
22
|
+
+ deinit {
|
|
23
|
+
+ if let cookieObserver = cookieObserver {
|
|
24
|
+
+ cookieObserverStore?.remove(cookieObserver)
|
|
25
|
+
+ }
|
|
26
|
+
+ }
|
|
27
|
+
+
|
|
28
|
+
override public final func loadView() {
|
|
29
|
+
// load the configuration and set the logging flag
|
|
30
|
+
let configDescriptor = instanceDescriptor()
|
|
31
|
+
@@ -118,7 +130,11 @@ import Cordova
|
|
32
|
+
*/
|
|
33
|
+
open func webViewConfiguration(for instanceConfiguration: InstanceConfiguration) -> WKWebViewConfiguration {
|
|
34
|
+
let webViewConfiguration = WKWebViewConfiguration()
|
|
35
|
+
- webViewConfiguration.websiteDataStore.httpCookieStore.add(CapacitorWKCookieObserver())
|
|
36
|
+
+ let cookieObserver = CapacitorWKCookieObserver()
|
|
37
|
+
+ let cookieStore = webViewConfiguration.websiteDataStore.httpCookieStore
|
|
38
|
+
+ if let existingObserver = self.cookieObserver {
|
|
39
|
+
+ cookieObserverStore?.remove(existingObserver)
|
|
40
|
+
+ }
|
|
41
|
+
+ cookieStore.add(cookieObserver)
|
|
42
|
+
+ self.cookieObserver = cookieObserver
|
|
43
|
+
+ self.cookieObserverStore = cookieStore
|
|
44
|
+
webViewConfiguration.allowsInlineMediaPlayback = true
|
|
45
|
+
webViewConfiguration.suppressesIncrementalRendering = false
|
|
46
|
+
webViewConfiguration.allowsAirPlayForMediaPlayback = true
|