@capgo/capacitor-webview-version-checker 8.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/CapgoCapacitorWebviewVersionChecker.podspec +17 -0
- package/LICENSE +373 -0
- package/Package.swift +28 -0
- package/README.md +393 -0
- package/android/build.gradle +61 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/java/app/capgo/webviewversionchecker/WebviewVersionChecker.java +75 -0
- package/android/src/main/java/app/capgo/webviewversionchecker/WebviewVersionCheckerPlugin.java +751 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/dist/docs.json +560 -0
- package/dist/esm/definitions.d.ts +294 -0
- package/dist/esm/definitions.js +2 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +18 -0
- package/dist/esm/web.js +159 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +173 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +176 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Sources/WebviewVersionCheckerPlugin/WebviewVersionChecker.swift +142 -0
- package/ios/Sources/WebviewVersionCheckerPlugin/WebviewVersionCheckerPlugin.swift +394 -0
- package/ios/Tests/WebviewVersionCheckerPluginTests/WebviewVersionCheckerPluginTests.swift +22 -0
- package/package.json +89 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var core = require('@capacitor/core');
|
|
4
|
+
|
|
5
|
+
const WebviewVersionChecker = core.registerPlugin('WebviewVersionChecker', {
|
|
6
|
+
web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.WebviewVersionCheckerWeb()),
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
const UNKNOWN_REASON = 'Web implementation is a compatibility shim. Native Android/iOS implementations provide full WebView checks.';
|
|
10
|
+
class WebviewVersionCheckerWeb extends core.WebPlugin {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
13
|
+
this.monitoring = false;
|
|
14
|
+
this.checkOnResume = true;
|
|
15
|
+
this.autoPromptOnOutdated = false;
|
|
16
|
+
this.lastStatus = null;
|
|
17
|
+
}
|
|
18
|
+
async check(options = {}) {
|
|
19
|
+
var _a;
|
|
20
|
+
const currentVersion = this.detectCurrentVersion();
|
|
21
|
+
const currentMajorVersion = this.parseMajorVersion(currentVersion);
|
|
22
|
+
const latestVersion = options.latestVersion;
|
|
23
|
+
const latestMajorVersion = this.parseMajorVersion(latestVersion);
|
|
24
|
+
let state = 'unknown';
|
|
25
|
+
let reason = UNKNOWN_REASON;
|
|
26
|
+
if (latestVersion && currentVersion) {
|
|
27
|
+
const cmp = this.compareVersions(currentVersion, latestVersion);
|
|
28
|
+
state = cmp >= 0 ? 'latest' : 'outdated';
|
|
29
|
+
reason = cmp >= 0 ? 'Current browser engine is at or above the requested latest version.' : 'Current browser engine is below the requested latest version.';
|
|
30
|
+
}
|
|
31
|
+
else if (typeof options.minimumMajorVersion === 'number' && typeof currentMajorVersion === 'number') {
|
|
32
|
+
state = currentMajorVersion >= options.minimumMajorVersion ? 'latest' : 'outdated';
|
|
33
|
+
reason = state === 'latest' ? 'Current browser engine major version meets the minimum requirement.' : 'Current browser engine major version is below the minimum requirement.';
|
|
34
|
+
}
|
|
35
|
+
const status = {
|
|
36
|
+
platform: 'web',
|
|
37
|
+
state,
|
|
38
|
+
isLatest: state === 'latest',
|
|
39
|
+
checkedAt: new Date().toISOString(),
|
|
40
|
+
reason,
|
|
41
|
+
currentVersion,
|
|
42
|
+
currentMajorVersion,
|
|
43
|
+
latestVersion,
|
|
44
|
+
latestMajorVersion,
|
|
45
|
+
updateUrl: options.updateUrl,
|
|
46
|
+
source: (_a = options.source) !== null && _a !== void 0 ? _a : 'web-shim',
|
|
47
|
+
};
|
|
48
|
+
this.lastStatus = status;
|
|
49
|
+
this.notifyListeners('statusChanged', status);
|
|
50
|
+
if (state === 'latest') {
|
|
51
|
+
this.notifyListeners('webViewLatest', status);
|
|
52
|
+
}
|
|
53
|
+
else if (state === 'outdated') {
|
|
54
|
+
this.notifyListeners('webViewOutdated', status);
|
|
55
|
+
if (options.showPromptOnOutdated || this.autoPromptOnOutdated) {
|
|
56
|
+
await this.showUpdatePrompt({ updateUrl: status.updateUrl });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return status;
|
|
60
|
+
}
|
|
61
|
+
async startMonitoring(options = {}) {
|
|
62
|
+
var _a, _b, _c, _d;
|
|
63
|
+
this.monitoring = true;
|
|
64
|
+
this.checkOnResume = (_a = options.checkOnResume) !== null && _a !== void 0 ? _a : true;
|
|
65
|
+
this.autoPromptOnOutdated = (_b = options.autoPromptOnOutdated) !== null && _b !== void 0 ? _b : false;
|
|
66
|
+
if ((_c = options.checkOnStart) !== null && _c !== void 0 ? _c : true) {
|
|
67
|
+
await this.check(Object.assign(Object.assign({}, options), { source: (_d = options.source) !== null && _d !== void 0 ? _d : 'startMonitoring' }));
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
monitoring: this.monitoring,
|
|
71
|
+
checkOnResume: this.checkOnResume,
|
|
72
|
+
autoPromptOnOutdated: this.autoPromptOnOutdated,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
async stopMonitoring() {
|
|
76
|
+
this.monitoring = false;
|
|
77
|
+
return {
|
|
78
|
+
monitoring: this.monitoring,
|
|
79
|
+
checkOnResume: this.checkOnResume,
|
|
80
|
+
autoPromptOnOutdated: this.autoPromptOnOutdated,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
async getLastStatus() {
|
|
84
|
+
return {
|
|
85
|
+
status: this.lastStatus,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
async showUpdatePrompt(options = {}) {
|
|
89
|
+
var _a, _b;
|
|
90
|
+
const url = (_a = options.updateUrl) !== null && _a !== void 0 ? _a : (_b = this.lastStatus) === null || _b === void 0 ? void 0 : _b.updateUrl;
|
|
91
|
+
if (!url) {
|
|
92
|
+
return {
|
|
93
|
+
shown: false,
|
|
94
|
+
openedUpdatePage: false,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
const opened = this.openUrl(url);
|
|
98
|
+
return {
|
|
99
|
+
shown: true,
|
|
100
|
+
openedUpdatePage: opened,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
async openUpdatePage(options = {}) {
|
|
104
|
+
var _a, _b, _c;
|
|
105
|
+
const url = (_c = (_a = options.updateUrl) !== null && _a !== void 0 ? _a : (_b = this.lastStatus) === null || _b === void 0 ? void 0 : _b.updateUrl) !== null && _c !== void 0 ? _c : '';
|
|
106
|
+
if (!url) {
|
|
107
|
+
return {
|
|
108
|
+
opened: false,
|
|
109
|
+
url,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
opened: this.openUrl(url),
|
|
114
|
+
url,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
detectCurrentVersion() {
|
|
118
|
+
const chromiumMatch = navigator.userAgent.match(/Chrome\/([\d.]+)/i);
|
|
119
|
+
if (chromiumMatch && chromiumMatch[1]) {
|
|
120
|
+
return chromiumMatch[1];
|
|
121
|
+
}
|
|
122
|
+
const appleWebKitMatch = navigator.userAgent.match(/AppleWebKit\/([\d.]+)/i);
|
|
123
|
+
if (appleWebKitMatch && appleWebKitMatch[1]) {
|
|
124
|
+
return appleWebKitMatch[1];
|
|
125
|
+
}
|
|
126
|
+
return navigator.userAgent;
|
|
127
|
+
}
|
|
128
|
+
openUrl(url) {
|
|
129
|
+
try {
|
|
130
|
+
window.open(url, '_blank', 'noopener,noreferrer');
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
catch (_a) {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
parseMajorVersion(version) {
|
|
138
|
+
if (!version) {
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
const match = version.match(/(\d+)/);
|
|
142
|
+
if (!match) {
|
|
143
|
+
return undefined;
|
|
144
|
+
}
|
|
145
|
+
const major = Number.parseInt(match[1], 10);
|
|
146
|
+
return Number.isFinite(major) ? major : undefined;
|
|
147
|
+
}
|
|
148
|
+
compareVersions(left, right) {
|
|
149
|
+
var _a, _b;
|
|
150
|
+
const leftParts = left.split(/[^0-9]+/).filter(Boolean).map((part) => Number.parseInt(part, 10));
|
|
151
|
+
const rightParts = right.split(/[^0-9]+/).filter(Boolean).map((part) => Number.parseInt(part, 10));
|
|
152
|
+
const maxLength = Math.max(leftParts.length, rightParts.length);
|
|
153
|
+
for (let i = 0; i < maxLength; i += 1) {
|
|
154
|
+
const a = (_a = leftParts[i]) !== null && _a !== void 0 ? _a : 0;
|
|
155
|
+
const b = (_b = rightParts[i]) !== null && _b !== void 0 ? _b : 0;
|
|
156
|
+
if (a > b) {
|
|
157
|
+
return 1;
|
|
158
|
+
}
|
|
159
|
+
if (a < b) {
|
|
160
|
+
return -1;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return 0;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
var web = /*#__PURE__*/Object.freeze({
|
|
168
|
+
__proto__: null,
|
|
169
|
+
WebviewVersionCheckerWeb: WebviewVersionCheckerWeb
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
exports.WebviewVersionChecker = WebviewVersionChecker;
|
|
173
|
+
//# sourceMappingURL=plugin.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst WebviewVersionChecker = registerPlugin('WebviewVersionChecker', {\n web: () => import('./web').then((m) => new m.WebviewVersionCheckerWeb()),\n});\nexport * from './definitions';\nexport { WebviewVersionChecker };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nconst UNKNOWN_REASON = 'Web implementation is a compatibility shim. Native Android/iOS implementations provide full WebView checks.';\nexport class WebviewVersionCheckerWeb extends WebPlugin {\n constructor() {\n super(...arguments);\n this.monitoring = false;\n this.checkOnResume = true;\n this.autoPromptOnOutdated = false;\n this.lastStatus = null;\n }\n async check(options = {}) {\n var _a;\n const currentVersion = this.detectCurrentVersion();\n const currentMajorVersion = this.parseMajorVersion(currentVersion);\n const latestVersion = options.latestVersion;\n const latestMajorVersion = this.parseMajorVersion(latestVersion);\n let state = 'unknown';\n let reason = UNKNOWN_REASON;\n if (latestVersion && currentVersion) {\n const cmp = this.compareVersions(currentVersion, latestVersion);\n state = cmp >= 0 ? 'latest' : 'outdated';\n reason = cmp >= 0 ? 'Current browser engine is at or above the requested latest version.' : 'Current browser engine is below the requested latest version.';\n }\n else if (typeof options.minimumMajorVersion === 'number' && typeof currentMajorVersion === 'number') {\n state = currentMajorVersion >= options.minimumMajorVersion ? 'latest' : 'outdated';\n reason = state === 'latest' ? 'Current browser engine major version meets the minimum requirement.' : 'Current browser engine major version is below the minimum requirement.';\n }\n const status = {\n platform: 'web',\n state,\n isLatest: state === 'latest',\n checkedAt: new Date().toISOString(),\n reason,\n currentVersion,\n currentMajorVersion,\n latestVersion,\n latestMajorVersion,\n updateUrl: options.updateUrl,\n source: (_a = options.source) !== null && _a !== void 0 ? _a : 'web-shim',\n };\n this.lastStatus = status;\n this.notifyListeners('statusChanged', status);\n if (state === 'latest') {\n this.notifyListeners('webViewLatest', status);\n }\n else if (state === 'outdated') {\n this.notifyListeners('webViewOutdated', status);\n if (options.showPromptOnOutdated || this.autoPromptOnOutdated) {\n await this.showUpdatePrompt({ updateUrl: status.updateUrl });\n }\n }\n return status;\n }\n async startMonitoring(options = {}) {\n var _a, _b, _c, _d;\n this.monitoring = true;\n this.checkOnResume = (_a = options.checkOnResume) !== null && _a !== void 0 ? _a : true;\n this.autoPromptOnOutdated = (_b = options.autoPromptOnOutdated) !== null && _b !== void 0 ? _b : false;\n if ((_c = options.checkOnStart) !== null && _c !== void 0 ? _c : true) {\n await this.check(Object.assign(Object.assign({}, options), { source: (_d = options.source) !== null && _d !== void 0 ? _d : 'startMonitoring' }));\n }\n return {\n monitoring: this.monitoring,\n checkOnResume: this.checkOnResume,\n autoPromptOnOutdated: this.autoPromptOnOutdated,\n };\n }\n async stopMonitoring() {\n this.monitoring = false;\n return {\n monitoring: this.monitoring,\n checkOnResume: this.checkOnResume,\n autoPromptOnOutdated: this.autoPromptOnOutdated,\n };\n }\n async getLastStatus() {\n return {\n status: this.lastStatus,\n };\n }\n async showUpdatePrompt(options = {}) {\n var _a, _b;\n const url = (_a = options.updateUrl) !== null && _a !== void 0 ? _a : (_b = this.lastStatus) === null || _b === void 0 ? void 0 : _b.updateUrl;\n if (!url) {\n return {\n shown: false,\n openedUpdatePage: false,\n };\n }\n const opened = this.openUrl(url);\n return {\n shown: true,\n openedUpdatePage: opened,\n };\n }\n async openUpdatePage(options = {}) {\n var _a, _b, _c;\n const url = (_c = (_a = options.updateUrl) !== null && _a !== void 0 ? _a : (_b = this.lastStatus) === null || _b === void 0 ? void 0 : _b.updateUrl) !== null && _c !== void 0 ? _c : '';\n if (!url) {\n return {\n opened: false,\n url,\n };\n }\n return {\n opened: this.openUrl(url),\n url,\n };\n }\n detectCurrentVersion() {\n const chromiumMatch = navigator.userAgent.match(/Chrome\\/([\\d.]+)/i);\n if (chromiumMatch && chromiumMatch[1]) {\n return chromiumMatch[1];\n }\n const appleWebKitMatch = navigator.userAgent.match(/AppleWebKit\\/([\\d.]+)/i);\n if (appleWebKitMatch && appleWebKitMatch[1]) {\n return appleWebKitMatch[1];\n }\n return navigator.userAgent;\n }\n openUrl(url) {\n try {\n window.open(url, '_blank', 'noopener,noreferrer');\n return true;\n }\n catch (_a) {\n return false;\n }\n }\n parseMajorVersion(version) {\n if (!version) {\n return undefined;\n }\n const match = version.match(/(\\d+)/);\n if (!match) {\n return undefined;\n }\n const major = Number.parseInt(match[1], 10);\n return Number.isFinite(major) ? major : undefined;\n }\n compareVersions(left, right) {\n var _a, _b;\n const leftParts = left.split(/[^0-9]+/).filter(Boolean).map((part) => Number.parseInt(part, 10));\n const rightParts = right.split(/[^0-9]+/).filter(Boolean).map((part) => Number.parseInt(part, 10));\n const maxLength = Math.max(leftParts.length, rightParts.length);\n for (let i = 0; i < maxLength; i += 1) {\n const a = (_a = leftParts[i]) !== null && _a !== void 0 ? _a : 0;\n const b = (_b = rightParts[i]) !== null && _b !== void 0 ? _b : 0;\n if (a > b) {\n return 1;\n }\n if (a < b) {\n return -1;\n }\n }\n return 0;\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":"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"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
var capacitorWebviewVersionChecker = (function (exports, core) {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const WebviewVersionChecker = core.registerPlugin('WebviewVersionChecker', {
|
|
5
|
+
web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.WebviewVersionCheckerWeb()),
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
const UNKNOWN_REASON = 'Web implementation is a compatibility shim. Native Android/iOS implementations provide full WebView checks.';
|
|
9
|
+
class WebviewVersionCheckerWeb extends core.WebPlugin {
|
|
10
|
+
constructor() {
|
|
11
|
+
super(...arguments);
|
|
12
|
+
this.monitoring = false;
|
|
13
|
+
this.checkOnResume = true;
|
|
14
|
+
this.autoPromptOnOutdated = false;
|
|
15
|
+
this.lastStatus = null;
|
|
16
|
+
}
|
|
17
|
+
async check(options = {}) {
|
|
18
|
+
var _a;
|
|
19
|
+
const currentVersion = this.detectCurrentVersion();
|
|
20
|
+
const currentMajorVersion = this.parseMajorVersion(currentVersion);
|
|
21
|
+
const latestVersion = options.latestVersion;
|
|
22
|
+
const latestMajorVersion = this.parseMajorVersion(latestVersion);
|
|
23
|
+
let state = 'unknown';
|
|
24
|
+
let reason = UNKNOWN_REASON;
|
|
25
|
+
if (latestVersion && currentVersion) {
|
|
26
|
+
const cmp = this.compareVersions(currentVersion, latestVersion);
|
|
27
|
+
state = cmp >= 0 ? 'latest' : 'outdated';
|
|
28
|
+
reason = cmp >= 0 ? 'Current browser engine is at or above the requested latest version.' : 'Current browser engine is below the requested latest version.';
|
|
29
|
+
}
|
|
30
|
+
else if (typeof options.minimumMajorVersion === 'number' && typeof currentMajorVersion === 'number') {
|
|
31
|
+
state = currentMajorVersion >= options.minimumMajorVersion ? 'latest' : 'outdated';
|
|
32
|
+
reason = state === 'latest' ? 'Current browser engine major version meets the minimum requirement.' : 'Current browser engine major version is below the minimum requirement.';
|
|
33
|
+
}
|
|
34
|
+
const status = {
|
|
35
|
+
platform: 'web',
|
|
36
|
+
state,
|
|
37
|
+
isLatest: state === 'latest',
|
|
38
|
+
checkedAt: new Date().toISOString(),
|
|
39
|
+
reason,
|
|
40
|
+
currentVersion,
|
|
41
|
+
currentMajorVersion,
|
|
42
|
+
latestVersion,
|
|
43
|
+
latestMajorVersion,
|
|
44
|
+
updateUrl: options.updateUrl,
|
|
45
|
+
source: (_a = options.source) !== null && _a !== void 0 ? _a : 'web-shim',
|
|
46
|
+
};
|
|
47
|
+
this.lastStatus = status;
|
|
48
|
+
this.notifyListeners('statusChanged', status);
|
|
49
|
+
if (state === 'latest') {
|
|
50
|
+
this.notifyListeners('webViewLatest', status);
|
|
51
|
+
}
|
|
52
|
+
else if (state === 'outdated') {
|
|
53
|
+
this.notifyListeners('webViewOutdated', status);
|
|
54
|
+
if (options.showPromptOnOutdated || this.autoPromptOnOutdated) {
|
|
55
|
+
await this.showUpdatePrompt({ updateUrl: status.updateUrl });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return status;
|
|
59
|
+
}
|
|
60
|
+
async startMonitoring(options = {}) {
|
|
61
|
+
var _a, _b, _c, _d;
|
|
62
|
+
this.monitoring = true;
|
|
63
|
+
this.checkOnResume = (_a = options.checkOnResume) !== null && _a !== void 0 ? _a : true;
|
|
64
|
+
this.autoPromptOnOutdated = (_b = options.autoPromptOnOutdated) !== null && _b !== void 0 ? _b : false;
|
|
65
|
+
if ((_c = options.checkOnStart) !== null && _c !== void 0 ? _c : true) {
|
|
66
|
+
await this.check(Object.assign(Object.assign({}, options), { source: (_d = options.source) !== null && _d !== void 0 ? _d : 'startMonitoring' }));
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
monitoring: this.monitoring,
|
|
70
|
+
checkOnResume: this.checkOnResume,
|
|
71
|
+
autoPromptOnOutdated: this.autoPromptOnOutdated,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
async stopMonitoring() {
|
|
75
|
+
this.monitoring = false;
|
|
76
|
+
return {
|
|
77
|
+
monitoring: this.monitoring,
|
|
78
|
+
checkOnResume: this.checkOnResume,
|
|
79
|
+
autoPromptOnOutdated: this.autoPromptOnOutdated,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
async getLastStatus() {
|
|
83
|
+
return {
|
|
84
|
+
status: this.lastStatus,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
async showUpdatePrompt(options = {}) {
|
|
88
|
+
var _a, _b;
|
|
89
|
+
const url = (_a = options.updateUrl) !== null && _a !== void 0 ? _a : (_b = this.lastStatus) === null || _b === void 0 ? void 0 : _b.updateUrl;
|
|
90
|
+
if (!url) {
|
|
91
|
+
return {
|
|
92
|
+
shown: false,
|
|
93
|
+
openedUpdatePage: false,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
const opened = this.openUrl(url);
|
|
97
|
+
return {
|
|
98
|
+
shown: true,
|
|
99
|
+
openedUpdatePage: opened,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
async openUpdatePage(options = {}) {
|
|
103
|
+
var _a, _b, _c;
|
|
104
|
+
const url = (_c = (_a = options.updateUrl) !== null && _a !== void 0 ? _a : (_b = this.lastStatus) === null || _b === void 0 ? void 0 : _b.updateUrl) !== null && _c !== void 0 ? _c : '';
|
|
105
|
+
if (!url) {
|
|
106
|
+
return {
|
|
107
|
+
opened: false,
|
|
108
|
+
url,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
opened: this.openUrl(url),
|
|
113
|
+
url,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
detectCurrentVersion() {
|
|
117
|
+
const chromiumMatch = navigator.userAgent.match(/Chrome\/([\d.]+)/i);
|
|
118
|
+
if (chromiumMatch && chromiumMatch[1]) {
|
|
119
|
+
return chromiumMatch[1];
|
|
120
|
+
}
|
|
121
|
+
const appleWebKitMatch = navigator.userAgent.match(/AppleWebKit\/([\d.]+)/i);
|
|
122
|
+
if (appleWebKitMatch && appleWebKitMatch[1]) {
|
|
123
|
+
return appleWebKitMatch[1];
|
|
124
|
+
}
|
|
125
|
+
return navigator.userAgent;
|
|
126
|
+
}
|
|
127
|
+
openUrl(url) {
|
|
128
|
+
try {
|
|
129
|
+
window.open(url, '_blank', 'noopener,noreferrer');
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
catch (_a) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
parseMajorVersion(version) {
|
|
137
|
+
if (!version) {
|
|
138
|
+
return undefined;
|
|
139
|
+
}
|
|
140
|
+
const match = version.match(/(\d+)/);
|
|
141
|
+
if (!match) {
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
const major = Number.parseInt(match[1], 10);
|
|
145
|
+
return Number.isFinite(major) ? major : undefined;
|
|
146
|
+
}
|
|
147
|
+
compareVersions(left, right) {
|
|
148
|
+
var _a, _b;
|
|
149
|
+
const leftParts = left.split(/[^0-9]+/).filter(Boolean).map((part) => Number.parseInt(part, 10));
|
|
150
|
+
const rightParts = right.split(/[^0-9]+/).filter(Boolean).map((part) => Number.parseInt(part, 10));
|
|
151
|
+
const maxLength = Math.max(leftParts.length, rightParts.length);
|
|
152
|
+
for (let i = 0; i < maxLength; i += 1) {
|
|
153
|
+
const a = (_a = leftParts[i]) !== null && _a !== void 0 ? _a : 0;
|
|
154
|
+
const b = (_b = rightParts[i]) !== null && _b !== void 0 ? _b : 0;
|
|
155
|
+
if (a > b) {
|
|
156
|
+
return 1;
|
|
157
|
+
}
|
|
158
|
+
if (a < b) {
|
|
159
|
+
return -1;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return 0;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
var web = /*#__PURE__*/Object.freeze({
|
|
167
|
+
__proto__: null,
|
|
168
|
+
WebviewVersionCheckerWeb: WebviewVersionCheckerWeb
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
exports.WebviewVersionChecker = WebviewVersionChecker;
|
|
172
|
+
|
|
173
|
+
return exports;
|
|
174
|
+
|
|
175
|
+
})({}, capacitorExports);
|
|
176
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst WebviewVersionChecker = registerPlugin('WebviewVersionChecker', {\n web: () => import('./web').then((m) => new m.WebviewVersionCheckerWeb()),\n});\nexport * from './definitions';\nexport { WebviewVersionChecker };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nconst UNKNOWN_REASON = 'Web implementation is a compatibility shim. Native Android/iOS implementations provide full WebView checks.';\nexport class WebviewVersionCheckerWeb extends WebPlugin {\n constructor() {\n super(...arguments);\n this.monitoring = false;\n this.checkOnResume = true;\n this.autoPromptOnOutdated = false;\n this.lastStatus = null;\n }\n async check(options = {}) {\n var _a;\n const currentVersion = this.detectCurrentVersion();\n const currentMajorVersion = this.parseMajorVersion(currentVersion);\n const latestVersion = options.latestVersion;\n const latestMajorVersion = this.parseMajorVersion(latestVersion);\n let state = 'unknown';\n let reason = UNKNOWN_REASON;\n if (latestVersion && currentVersion) {\n const cmp = this.compareVersions(currentVersion, latestVersion);\n state = cmp >= 0 ? 'latest' : 'outdated';\n reason = cmp >= 0 ? 'Current browser engine is at or above the requested latest version.' : 'Current browser engine is below the requested latest version.';\n }\n else if (typeof options.minimumMajorVersion === 'number' && typeof currentMajorVersion === 'number') {\n state = currentMajorVersion >= options.minimumMajorVersion ? 'latest' : 'outdated';\n reason = state === 'latest' ? 'Current browser engine major version meets the minimum requirement.' : 'Current browser engine major version is below the minimum requirement.';\n }\n const status = {\n platform: 'web',\n state,\n isLatest: state === 'latest',\n checkedAt: new Date().toISOString(),\n reason,\n currentVersion,\n currentMajorVersion,\n latestVersion,\n latestMajorVersion,\n updateUrl: options.updateUrl,\n source: (_a = options.source) !== null && _a !== void 0 ? _a : 'web-shim',\n };\n this.lastStatus = status;\n this.notifyListeners('statusChanged', status);\n if (state === 'latest') {\n this.notifyListeners('webViewLatest', status);\n }\n else if (state === 'outdated') {\n this.notifyListeners('webViewOutdated', status);\n if (options.showPromptOnOutdated || this.autoPromptOnOutdated) {\n await this.showUpdatePrompt({ updateUrl: status.updateUrl });\n }\n }\n return status;\n }\n async startMonitoring(options = {}) {\n var _a, _b, _c, _d;\n this.monitoring = true;\n this.checkOnResume = (_a = options.checkOnResume) !== null && _a !== void 0 ? _a : true;\n this.autoPromptOnOutdated = (_b = options.autoPromptOnOutdated) !== null && _b !== void 0 ? _b : false;\n if ((_c = options.checkOnStart) !== null && _c !== void 0 ? _c : true) {\n await this.check(Object.assign(Object.assign({}, options), { source: (_d = options.source) !== null && _d !== void 0 ? _d : 'startMonitoring' }));\n }\n return {\n monitoring: this.monitoring,\n checkOnResume: this.checkOnResume,\n autoPromptOnOutdated: this.autoPromptOnOutdated,\n };\n }\n async stopMonitoring() {\n this.monitoring = false;\n return {\n monitoring: this.monitoring,\n checkOnResume: this.checkOnResume,\n autoPromptOnOutdated: this.autoPromptOnOutdated,\n };\n }\n async getLastStatus() {\n return {\n status: this.lastStatus,\n };\n }\n async showUpdatePrompt(options = {}) {\n var _a, _b;\n const url = (_a = options.updateUrl) !== null && _a !== void 0 ? _a : (_b = this.lastStatus) === null || _b === void 0 ? void 0 : _b.updateUrl;\n if (!url) {\n return {\n shown: false,\n openedUpdatePage: false,\n };\n }\n const opened = this.openUrl(url);\n return {\n shown: true,\n openedUpdatePage: opened,\n };\n }\n async openUpdatePage(options = {}) {\n var _a, _b, _c;\n const url = (_c = (_a = options.updateUrl) !== null && _a !== void 0 ? _a : (_b = this.lastStatus) === null || _b === void 0 ? void 0 : _b.updateUrl) !== null && _c !== void 0 ? _c : '';\n if (!url) {\n return {\n opened: false,\n url,\n };\n }\n return {\n opened: this.openUrl(url),\n url,\n };\n }\n detectCurrentVersion() {\n const chromiumMatch = navigator.userAgent.match(/Chrome\\/([\\d.]+)/i);\n if (chromiumMatch && chromiumMatch[1]) {\n return chromiumMatch[1];\n }\n const appleWebKitMatch = navigator.userAgent.match(/AppleWebKit\\/([\\d.]+)/i);\n if (appleWebKitMatch && appleWebKitMatch[1]) {\n return appleWebKitMatch[1];\n }\n return navigator.userAgent;\n }\n openUrl(url) {\n try {\n window.open(url, '_blank', 'noopener,noreferrer');\n return true;\n }\n catch (_a) {\n return false;\n }\n }\n parseMajorVersion(version) {\n if (!version) {\n return undefined;\n }\n const match = version.match(/(\\d+)/);\n if (!match) {\n return undefined;\n }\n const major = Number.parseInt(match[1], 10);\n return Number.isFinite(major) ? major : undefined;\n }\n compareVersions(left, right) {\n var _a, _b;\n const leftParts = left.split(/[^0-9]+/).filter(Boolean).map((part) => Number.parseInt(part, 10));\n const rightParts = right.split(/[^0-9]+/).filter(Boolean).map((part) => Number.parseInt(part, 10));\n const maxLength = Math.max(leftParts.length, rightParts.length);\n for (let i = 0; i < maxLength; i += 1) {\n const a = (_a = leftParts[i]) !== null && _a !== void 0 ? _a : 0;\n const b = (_b = rightParts[i]) !== null && _b !== void 0 ? _b : 0;\n if (a > b) {\n return 1;\n }\n if (a < b) {\n return -1;\n }\n }\n return 0;\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":"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"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import UIKit
|
|
3
|
+
|
|
4
|
+
private let defaultIOSUpdateUrl = "https://support.apple.com/guide/iphone/update-ios-iph3e504502/ios"
|
|
5
|
+
|
|
6
|
+
@objc public class WebviewVersionChecker: NSObject {
|
|
7
|
+
private let isoFormatter: ISO8601DateFormatter = {
|
|
8
|
+
let formatter = ISO8601DateFormatter()
|
|
9
|
+
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
|
|
10
|
+
return formatter
|
|
11
|
+
}()
|
|
12
|
+
|
|
13
|
+
func buildStatus(source: String, latestVersion: String?, minimumMajorVersion: Int?, updateUrl: String?) -> [String: Any] {
|
|
14
|
+
let currentVersion = UIDevice.current.systemVersion
|
|
15
|
+
let currentMajorVersion = parseMajorVersion(currentVersion)
|
|
16
|
+
let normalizedLatestVersion = normalizeVersion(latestVersion)
|
|
17
|
+
let latestMajorVersion = parseMajorVersion(normalizedLatestVersion)
|
|
18
|
+
|
|
19
|
+
var status: [String: Any] = [
|
|
20
|
+
"platform": "ios",
|
|
21
|
+
"source": source,
|
|
22
|
+
"checkedAt": isoFormatter.string(from: Date()),
|
|
23
|
+
"currentVersion": currentVersion,
|
|
24
|
+
"updateUrl": normalizedUpdateUrl(updateUrl)
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
if let currentMajorVersion {
|
|
28
|
+
status["currentMajorVersion"] = currentMajorVersion
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if let normalizedLatestVersion {
|
|
32
|
+
status["latestVersion"] = normalizedLatestVersion
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if let latestMajorVersion {
|
|
36
|
+
status["latestMajorVersion"] = latestMajorVersion
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if let normalizedLatestVersion {
|
|
40
|
+
let cmp = compareVersions(currentVersion, normalizedLatestVersion)
|
|
41
|
+
let isLatest = cmp >= 0
|
|
42
|
+
status["state"] = isLatest ? "latest" : "outdated"
|
|
43
|
+
status["isLatest"] = isLatest
|
|
44
|
+
status["reason"] = isLatest
|
|
45
|
+
? "Installed iOS WebKit version is at or above the requested latest version."
|
|
46
|
+
: "Installed iOS WebKit version is behind the requested latest version."
|
|
47
|
+
return status
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if let minimumMajorVersion, let currentMajorVersion {
|
|
51
|
+
let isLatest = currentMajorVersion >= minimumMajorVersion
|
|
52
|
+
status["state"] = isLatest ? "latest" : "outdated"
|
|
53
|
+
status["isLatest"] = isLatest
|
|
54
|
+
status["reason"] = isLatest
|
|
55
|
+
? "Installed iOS major version satisfies the configured minimum major version."
|
|
56
|
+
: "Installed iOS major version is below the configured minimum major version."
|
|
57
|
+
return status
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
status["state"] = "unknown"
|
|
61
|
+
status["isLatest"] = false
|
|
62
|
+
status["reason"] = "iOS WebKit updates are tied to iOS updates. Configure latestVersion or minimumMajorVersion to enforce a policy."
|
|
63
|
+
return status
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
func defaultPromptMessage(status: [String: Any]?) -> String {
|
|
67
|
+
guard let status else {
|
|
68
|
+
return "A newer iOS WebKit version may be available. Please update iOS for best compatibility."
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
let current = (status["currentVersion"] as? String) ?? "current version"
|
|
72
|
+
let latest = (status["latestVersion"] as? String) ?? "the latest available version"
|
|
73
|
+
|
|
74
|
+
return "Your iOS WebKit version (\(current)) may be outdated. Please update toward \(latest)."
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
func normalizedUpdateUrl(_ value: String?) -> String {
|
|
78
|
+
let trimmed = normalizeVersion(value)
|
|
79
|
+
return trimmed ?? defaultIOSUpdateUrl
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
func promptFingerprint(status: [String: Any]?, updateUrl: String) -> String {
|
|
83
|
+
guard let status else {
|
|
84
|
+
return updateUrl
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
let current = (status["currentVersion"] as? String) ?? ""
|
|
88
|
+
let latest = (status["latestVersion"] as? String) ?? ""
|
|
89
|
+
return "\(current)|\(latest)|\(updateUrl)"
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private func parseMajorVersion(_ value: String?) -> Int? {
|
|
93
|
+
guard let value, !value.isEmpty else {
|
|
94
|
+
return nil
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
var digits = ""
|
|
98
|
+
for character in value {
|
|
99
|
+
if character.isNumber {
|
|
100
|
+
digits.append(character)
|
|
101
|
+
} else if !digits.isEmpty {
|
|
102
|
+
break
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return Int(digits)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private func normalizeVersion(_ value: String?) -> String? {
|
|
110
|
+
guard let value else {
|
|
111
|
+
return nil
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
let trimmed = value.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
115
|
+
return trimmed.isEmpty ? nil : trimmed
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private func compareVersions(_ left: String, _ right: String) -> Int {
|
|
119
|
+
let leftParts = tokenize(left)
|
|
120
|
+
let rightParts = tokenize(right)
|
|
121
|
+
let maxCount = max(leftParts.count, rightParts.count)
|
|
122
|
+
|
|
123
|
+
for index in 0..<maxCount {
|
|
124
|
+
let a = index < leftParts.count ? leftParts[index] : 0
|
|
125
|
+
let b = index < rightParts.count ? rightParts[index] : 0
|
|
126
|
+
if a > b {
|
|
127
|
+
return 1
|
|
128
|
+
}
|
|
129
|
+
if a < b {
|
|
130
|
+
return -1
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return 0
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private func tokenize(_ value: String) -> [Int] {
|
|
138
|
+
value
|
|
139
|
+
.split(whereSeparator: { !$0.isNumber })
|
|
140
|
+
.compactMap { Int($0) }
|
|
141
|
+
}
|
|
142
|
+
}
|