├── .eslintrc.js
├── .gitattributes
├── .github
├── FUNDING.yml
├── issue_template.md
└── workflows
│ └── release.yml
├── .gitignore
├── .gitmodules
├── .npmrc
├── .prettierignore
├── .prettierrc
├── .prettierrc.js
├── .yarnrc.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── config.json
├── demo-snippets
├── assets
│ ├── test-data
│ │ ├── css
│ │ │ └── local-stylesheet.css
│ │ ├── html
│ │ │ ├── camera.html
│ │ │ ├── css-not-predefined.html
│ │ │ ├── css-predefined-link-tags.html
│ │ │ ├── empty.html
│ │ │ ├── javascript-calls-x-local.html
│ │ │ └── javascript-calls.html
│ │ └── js
│ │ │ └── local-javascript.js
│ └── www
│ │ └── index.html
├── ng
│ ├── basic-example
│ │ ├── basic-example.component.html
│ │ ├── basic-example.component.scss
│ │ └── basic-example.component.ts
│ └── install.module.ts
├── package.json
├── react
│ ├── BasicExample.tsx
│ └── install.ts
├── svelte
│ ├── BasicExample.svelte
│ └── install.ts
└── vue
│ ├── BasicExample.vue
│ └── install.ts
├── detox.config.js
├── devices.js
├── docs
├── .nojekyll
├── assets
│ ├── hierarchy.js
│ ├── highlight.css
│ ├── icons.js
│ ├── icons.svg
│ ├── main.js
│ ├── navigation.js
│ ├── search.js
│ └── style.css
├── classes
│ ├── webview.AWebView.html
│ ├── webview.UnsupportedSDKError.html
│ └── webview.WebViewExtBase.html
├── enums
│ └── webview.EventNames.html
├── functions
│ └── webview-rtc.default.html
├── hierarchy.html
├── index.html
├── interfaces
│ ├── webview.EnterFullscreenEventData.html
│ ├── webview.ExitFullscreenEventData.html
│ ├── webview.InjectExecuteJavaScript.html
│ ├── webview.LoadEventData.html
│ ├── webview.LoadFinishedEventData.html
│ ├── webview.LoadJavaScriptResource.html
│ ├── webview.LoadProgressEventData.html
│ ├── webview.LoadStartedEventData.html
│ ├── webview.LoadStyleSheetResource.html
│ ├── webview.RequestPermissionsEventData.html
│ ├── webview.ShouldOverideUrlLoadEventData.html
│ ├── webview.ShouldOverrideUrlLoadEventData.html
│ ├── webview.TitleChangedEventData.html
│ ├── webview.ViewPortProperties.html
│ ├── webview.WebAlertEventData.html
│ ├── webview.WebConfirmEventData.html
│ ├── webview.WebConsoleEventData.html
│ ├── webview.WebPromptEventData.html
│ ├── webview.WebViewEventData.html
│ └── webview.WebViewExtEventData.html
├── modules.html
├── modules
│ ├── webview-rtc.html
│ └── webview.html
├── types
│ ├── webview.CacheMode.html
│ ├── webview.NavigationType.html
│ └── webview.ViewPortValue.html
└── variables
│ ├── webview.WebViewTraceCategory.html
│ ├── webview.allowsInlineMediaPlaybackProperty.html
│ ├── webview.autoInjectJSBridgeProperty.html
│ ├── webview.builtInZoomControlsProperty.html
│ ├── webview.cacheModeProperty.html
│ ├── webview.customUserAgentProperty.html
│ ├── webview.databaseStorageProperty.html
│ ├── webview.debugModeProperty.html
│ ├── webview.displayZoomControlsProperty.html
│ ├── webview.domStorageProperty.html
│ ├── webview.isScrollEnabledProperty.html
│ ├── webview.limitsNavigationsToAppBoundDomainsProperty.html
│ ├── webview.mediaPlaybackRequiresUserActionProperty.html
│ ├── webview.scalesPageToFitProperty.html
│ ├── webview.scrollBarIndicatorVisibleProperty.html
│ ├── webview.scrollBounceProperty.html
│ ├── webview.srcProperty.html
│ ├── webview.supportZoomProperty.html
│ ├── webview.useWideViewPortProperty.html
│ ├── webview.viewPortProperty.html
│ └── webview.webConsoleProperty.html
├── e2e
├── config.json
├── environment.js
├── run-tests.js
└── tests.e2e.js
├── images
├── demo-android.gif
└── demo-ios.gif
├── lerna.json
├── make-bridge-loader.ts
├── package.json
├── packages
├── webview-rtc
│ ├── .npmignore
│ ├── CHANGELOG.md
│ ├── README.md
│ ├── package.json
│ ├── platforms
│ │ └── ios
│ │ │ └── Podfile
│ └── tsconfig.json
└── webview
│ ├── .npmignore
│ ├── CHANGELOG.md
│ ├── README.md
│ ├── package.json
│ ├── platforms
│ ├── android
│ │ ├── AndroidManifest.xml
│ │ ├── buildscript.gradle
│ │ ├── include.gradle
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── nativescript
│ │ │ │ └── webviewinterface
│ │ │ │ ├── WebChromeClient.java
│ │ │ │ ├── WebView.java
│ │ │ │ └── WebViewBridgeInterface.java
│ │ └── native-api-usage.json
│ └── ios
│ │ ├── native-api-usage.json
│ │ └── src
│ │ ├── Constants.swift
│ │ ├── Info.plist
│ │ ├── WKWebviewCustomSchemeHandler.swift
│ │ └── module.modulemap
│ └── tsconfig.json
├── pnpm-workspace.yaml
├── references.d.ts
├── src-native
└── webview
│ └── android
│ ├── .gitignore
│ ├── .project
│ ├── .settings
│ └── org.eclipse.buildship.core.prefs
│ ├── app
│ ├── .classpath
│ ├── .gitignore
│ ├── .project
│ ├── .settings
│ │ └── org.eclipse.buildship.core.prefs
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src
│ │ ├── androidTest
│ │ └── java
│ │ │ └── com
│ │ │ └── github
│ │ │ └── triniwiz
│ │ │ └── imagedemo
│ │ │ └── ExampleInstrumentedTest.kt
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── nativescript
│ │ │ │ └── imagedemo
│ │ │ │ ├── Data.kt
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable-v24
│ │ │ └── ic_launcher_foreground.xml
│ │ │ ├── drawable
│ │ │ ├── bg.xml
│ │ │ ├── error.png
│ │ │ ├── ic_launcher_background.xml
│ │ │ └── law.jpg
│ │ │ ├── layout
│ │ │ ├── activity_main.xml
│ │ │ └── list_item.xml
│ │ │ ├── mipmap-anydpi-v26
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ └── values
│ │ │ ├── attrs.xml
│ │ │ ├── colors.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── github
│ │ └── triniwiz
│ │ └── imagedemo
│ │ └── ExampleUnitTest.kt
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── settings.gradle
│ └── webview
│ ├── .gitignore
│ ├── build.gradle
│ ├── consumer-rules.pro
│ ├── proguard-rules.pro
│ └── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── nativescript
│ │ └── image
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ └── res
│ │ ├── drawable-hdpi
│ │ └── ic_indicator.png
│ │ ├── drawable-mdpi
│ │ └── ic_indicator.png
│ │ ├── drawable-xhdpi
│ │ └── ic_indicator.png
│ │ ├── drawable-xxhdpi
│ │ └── ic_indicator.png
│ │ ├── drawable-xxxhdpi
│ │ └── ic_indicator.png
│ │ ├── drawable
│ │ └── progress_animation.xml
│ │ └── values
│ │ └── attrs.xml
│ └── test
│ └── java
│ └── com
│ └── nativescript
│ └── image
│ └── ExampleUnitTest.java
├── src
├── webview-rtc
│ ├── index.android.ts
│ ├── index.common.ts
│ ├── index.d.ts
│ ├── index.ios.ts
│ └── types
│ │ └── ios
│ │ └── objc!WKWebViewRTC.d.ts
└── webview
│ ├── angular
│ ├── index.ts
│ ├── ng-package.json
│ ├── package.json
│ └── tsconfig.json
│ ├── index.android.ts
│ ├── index.common.ts
│ ├── index.d.ts
│ ├── index.ios.ts
│ ├── nativescript-webview-bridge-loader.android.ts
│ ├── nativescript-webview-bridge-loader.d.ts
│ ├── nativescript-webview-bridge-loader.ios.ts
│ ├── references.d.ts
│ ├── types
│ ├── android
│ │ └── webviewinterface.d.ts
│ ├── ios
│ │ └── ios.d.ts
│ └── url.d.ts
│ └── vue
│ └── index.ts
├── svelte.config.js
├── tsconfig.eslint.json
├── tsconfig.json
├── tsconfig.vue3.json
├── www-src
├── bridge-loader.android.ts.tmpl
├── bridge-loader.ios.ts.tmpl
├── bridge.android.ts
├── bridge.common.ts
├── bridge.ios.ts
├── metadata-view-port.ts
├── package.json
├── rollup.config.mjs
├── tsconfig.json
└── yarn.lock
└── yarn.lock
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: './tools/.eslintrc.js'
3 | };
4 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: [farfromrefug]
2 |
--------------------------------------------------------------------------------
/.github/issue_template.md:
--------------------------------------------------------------------------------
1 | ### Make sure to check the demo app(s) for sample usage
2 |
3 | ### Make sure to check the existing issues in this repository
4 |
5 | ### If the demo apps cannot help and there is no issue for your problem, tell us about it
6 | Please, ensure your title is less than 63 characters long and starts with a capital
7 | letter.
8 |
9 | ### Which platform(s) does your issue occur on?
10 | - iOS/Android/Both
11 | - iOS/Android versions
12 | - emulator or device. What type of device?
13 |
14 | ### Please, provide the following version numbers that your issue occurs with:
15 |
16 | - CLI: (run `tns --version` to fetch it)
17 | - Cross-platform modules: (check the 'version' attribute in the
18 | `node_modules/@nativescript/core/package.json` file in your project)
19 | - Runtime(s): (look for the `"tns-android"` and `"tns-ios"` properties in the `package.json` file of your project)
20 | - Plugin(s): (look for the version numbers in the `package.json` file of your
21 | project and paste your dependencies and devDependencies here)
22 |
23 | ### Please, tell us how to recreate the issue in as much detail as possible.
24 | Describe the steps to reproduce it.
25 |
26 | ### Is there any code involved?
27 | - provide a code example to recreate the problem
28 | - (EVEN BETTER) provide a .zip with application or refer to a repository with application where the problem is reproducible.
29 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: 'release'
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | release_type:
7 | type: choice
8 | default: auto
9 | description: What kind of version upgrade
10 | options:
11 | - auto
12 | - patch
13 | - minor
14 | - major
15 |
16 | jobs:
17 | release:
18 | runs-on: ubuntu-latest
19 | steps:
20 | - name: Checkout repository
21 | uses: actions/checkout@v4
22 | with:
23 | fetch-depth: "0"
24 | submodules: true
25 |
26 | - name: setup node
27 | uses: actions/setup-node@v4
28 | with:
29 | node-version: lts/*
30 | registry-url: 'https://registry.npmjs.org'
31 |
32 |
33 | - uses: oNaiPs/secrets-to-env-action@v1
34 | with:
35 | secrets: ${{ toJSON(secrets) }}
36 |
37 |
38 | - uses: oleksiyrudenko/gha-git-credentials@v2-latest
39 | with:
40 | token: '${{ secrets.GITHUB_TOKEN }}'
41 | name: Martin Guillon
42 | email: dev@akylas.fr
43 |
44 | - name: install jq
45 | run: sudo apt install jq
46 |
47 | - name: Enable CorePack
48 | run: |
49 | corepack enable
50 | yarn config get globalFolder # the yarn command will ensure the correct yarn version is downloaded and installed
51 |
52 | - name: Get yarn cache directory path
53 | id: yarn-cache-dir-path
54 | run: echo "::set-output name=dir::$(yarn config get globalFolder)"
55 |
56 | - name: Remove package.json resolutions
57 | run: echo "`jq 'delpaths([["resolutions"]])' package.json`" > package.json
58 |
59 | - uses: actions/cache@v4
60 | name: Handle node_modules Cache
61 | id: yarn-node_modules # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
62 | with:
63 | path: node_modules
64 | key: ${{ runner.os }}-yarn-node_modules-${{ hashFiles('**/yarn.lock') }}
65 | restore-keys: |
66 | ${{ runner.os }}-node_modules-
67 |
68 | - uses: actions/cache@v4
69 | if: steps.yarn-node_modules.outputs.cache-hit != 'true'
70 | name: Handle Yarn cache
71 | id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
72 | with:
73 | path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
74 | key: ${{ runner.os }}-yarn-cache-${{ hashFiles('**/yarn.lock') }}
75 | restore-keys: |
76 | ${{ runner.os }}-yarn-
77 |
78 | - name: Install deps
79 | if: steps.yarn-node_modules.outputs.cache-hit != 'true'
80 | uses: bahmutov/npm-install@v1
81 | with:
82 | install-command: yarn install --silent
83 | env:
84 | YARN_ENABLE_IMMUTABLE_INSTALLS: false
85 |
86 | - name: run setup
87 | run: |
88 | npm run setup
89 |
90 | - name: "NPM Identity"
91 | env:
92 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
93 | run: |
94 | echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > .npmrc
95 |
96 | - name: publish auto
97 | if: github.event.inputs.release_type == 'auto'
98 | run: |
99 | npm run publish -- --force-publish --no-verify-access --no-private --no-commit-hooks --yes
100 | env:
101 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
102 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
103 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
104 |
105 | - name: publish
106 | if: github.event.inputs.release_type != 'auto'
107 | run: |
108 | npm run publish -- --force-publish --no-verify-access --no-private --no-commit-hooks --yes --bump ${{ github.event.inputs.release_type }}
109 | env:
110 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
111 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
112 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # NativeScript
2 | hooks/
3 | node_modules/
4 | platforms
5 |
6 | # NativeScript Template
7 | *.js.map
8 | !ngcc.config.js
9 | !webpack.config.js
10 |
11 | # Logs
12 | logs
13 | *.log
14 | npm-debug.log*
15 | yarn-debug.log*
16 | yarn-error.log*
17 |
18 | # General
19 | .DS_Store
20 | .AppleDouble
21 | .LSOverride
22 | .idea
23 | .cloud
24 | .gradle
25 | .project
26 | .yarn
27 | .cxx
28 | tmp/
29 |
30 | !.eslintrc.js
31 | !.prettierrc.js
32 |
33 | !e2e/*.js
34 | !detox.config.js
35 | devices.js
36 |
37 | *.framework
38 | *.xcframework
39 | **/*.js.map
40 | src/**/*.js
41 | packages/**/*.js
42 | packages/**/*.d.ts
43 | bin
44 | build
45 | Pods
46 | !packages/*/platforms
47 | /packages/**/*.aar
48 | /packages/**/*.framework
49 | /packages/**/*.xcframework
50 | /demo-snippets/**/*.aar
51 | *.xcuserdatad
52 | /packages/README.md
53 | packages/**/*js.map
54 | packages/**/*js
55 | packages/angular
56 | packages/typings
57 | packages/**/angular/*.json
58 | packages/**/*.ngsummary.json
59 | packages/**/*.metadata.json
60 |
61 | .vscode/settings.json
62 |
63 | /blueprint.md
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "tools"]
2 | path = tools
3 | url = https://github.com/nativescript-community/plugin-seed-tools.git
4 | [submodule "demo-vue"]
5 | path = demo-vue
6 | url = https://github.com/nativescript-community/plugin-seed-demo-vue.git
7 | [submodule "demo-react"]
8 | path = demo-react
9 | url = https://github.com/nativescript-community/plugin-seed-demo-react.git
10 | [submodule "demo-svelte"]
11 | path = demo-svelte
12 | url = https://github.com/nativescript-community/plugin-seed-demo-svelte.git
13 | [submodule "demo-ng"]
14 | path = demo-ng
15 | url = https://github.com/nativescript-community/plugin-seed-demo-ng.git
16 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | shamefully-hoist=true
2 | public-hoist-pattern[]=*eslint*
3 | public-hoist-pattern[]=source-map-support
4 | public-hoist-pattern[]=ts-patch
5 | public-hoist-pattern[]=typescript
6 | public-hoist-pattern[]=cpy-cli
7 | strict-peer-dependencies=false
8 | shell-emulator=true
9 | auto-install-peers=false
10 | loglevel=error
11 | engine-strict=true
12 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | package-lock.json
2 | node_modules/
3 | plugin/
4 | docs/
5 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 200,
3 | "semi": true,
4 | "tabWidth": 4,
5 | "singleQuote": true,
6 | "trailingComma": "none"
7 | }
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | printWidth: 200,
3 | semi: true,
4 | tabWidth: 4,
5 | trailingComma: 'none',
6 | singleQuote: true
7 | };
8 |
--------------------------------------------------------------------------------
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | compressionLevel: mixed
2 |
3 | nmHoistingLimits: workspaces
4 |
5 | nodeLinker: node-modules
6 |
7 | yarnPath: tools/.yarn/releases/yarn-4.0.1.cjs
8 |
--------------------------------------------------------------------------------
/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "readme": true,
3 | "angular": true,
4 | "demos": [
5 | "ng",
6 | "react",
7 | "svelte",
8 | "vue"
9 | ]
10 | }
--------------------------------------------------------------------------------
/demo-snippets/assets/test-data/css/local-stylesheet.css:
--------------------------------------------------------------------------------
1 | .red {
2 | margin: 0;
3 | padding: 0;
4 | font-weight: bolder;
5 | background-color: blue;
6 | color: green;
7 | font-size: 20pt;
8 | }
9 |
10 | body,
11 | html {
12 | margin: 0;
13 | padding: 0;
14 | background-color: purple;
15 | }
16 |
--------------------------------------------------------------------------------
/demo-snippets/assets/test-data/html/camera.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
20 |
21 | Blank
22 |
23 |
24 |
26 |
27 |
28 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/demo-snippets/assets/test-data/html/css-not-predefined.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Inject stylesheet via x-local
5 |
6 |
7 | RED
8 |
9 |
10 |
--------------------------------------------------------------------------------
/demo-snippets/assets/test-data/html/css-predefined-link-tags.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Load predefined x-local stylesheet
5 |
6 |
7 |
8 | RED
9 |
10 |
11 |
--------------------------------------------------------------------------------
/demo-snippets/assets/test-data/html/empty.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Blank
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/demo-snippets/assets/test-data/html/javascript-calls-x-local.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/demo-snippets/assets/test-data/html/javascript-calls.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
35 |
36 |
37 | RED
38 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/demo-snippets/assets/test-data/js/local-javascript.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | function getNumber() {
4 | return 42;
5 | }
6 |
7 | function getNumberFloat() {
8 | return 3.14;
9 | }
10 |
11 | function getFalse() {
12 | return false;
13 | }
14 |
15 | function getTruth() {
16 | return true;
17 | }
18 |
19 | function getString() {
20 | return 'string result from webview JS function';
21 | }
22 |
23 | function getArray() {
24 | return [1.5, true, 'hello'];
25 | }
26 |
27 | function getObject() {
28 | return {
29 | prop: 'test',
30 | name: 'object-test',
31 | values: [42, 3.14]
32 | };
33 | }
34 |
35 | function setupEventListener() {
36 | window.nsWebViewBridge.on('tns-message', function (args) {
37 | window.nsWebViewBridge.emit('web-message', args);
38 | });
39 | }
40 |
41 | function testPromiseResolve() {
42 | return new Promise(function (resolve) {
43 | setTimeout(function () {
44 | resolve(42);
45 | }, 100);
46 | });
47 | }
48 |
49 | function testPromiseReject() {
50 | return new Promise(function (resolve, reject) {
51 | setTimeout(function () {
52 | reject(new Error('The Cake is a Lie'));
53 | }, 100);
54 | });
55 | }
56 |
--------------------------------------------------------------------------------
/demo-snippets/assets/www/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
47 |
48 |
49 | RED
50 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/demo-snippets/ng/basic-example/basic-example.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/demo-snippets/ng/basic-example/basic-example.component.scss:
--------------------------------------------------------------------------------
1 | .label {
2 | font-size: 35;
3 | text-align: center;
4 | width: 100%;
5 | vertical-alignment: center;
6 | color: #FFFFFF;
7 | text-transform: uppercase;
8 | }
--------------------------------------------------------------------------------
/demo-snippets/ng/basic-example/basic-example.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { RouterExtensions } from '@nativescript/angular';
3 |
4 | @Component({
5 | selector: 'ns-basic-example',
6 | templateUrl: './basic-example.component.html',
7 | styleUrls: ['./basic-example.component.scss']
8 | })
9 | export class BasicExampleComponent implements OnInit {
10 | constructor(private router: RouterExtensions) {}
11 |
12 | ngOnInit(): void {}
13 |
14 | goBack(): void {
15 | this.router.back();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/demo-snippets/ng/install.module.ts:
--------------------------------------------------------------------------------
1 | import { NO_ERRORS_SCHEMA, NgModule } from '@angular/core';
2 |
3 | import { AWebViewModule } from '@nativescript-community/ui-webview/angular';
4 | import { BasicExampleComponent } from './basic-example/basic-example.component';
5 |
6 | export const COMPONENTS = [BasicExampleComponent];
7 | @NgModule({
8 | imports: [AWebViewModule],
9 | exports: [AWebViewModule],
10 | schemas: [NO_ERRORS_SCHEMA]
11 | })
12 | export class InstallModule {}
13 |
14 | export function installPlugin() {}
15 |
16 | export const demos = [{ name: 'Static Example', path: 'static-example', component: BasicExampleComponent }];
17 |
--------------------------------------------------------------------------------
/demo-snippets/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@nativescript-community/template-snippet",
3 | "private": true,
4 | "version": "0.0.1",
5 | "dependencies": {
6 | "@nativescript-community/perms": "2.2.21",
7 | "@nativescript-community/ui-webview": "*",
8 | "@nativescript-community/ui-webview-rtc": "*",
9 | "fast-deep-equal": "3.1.3",
10 | "url": "0.11.0"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/demo-snippets/react/BasicExample.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | export function BasicExample() {
4 | return ;
5 | }
6 |
--------------------------------------------------------------------------------
/demo-snippets/react/install.ts:
--------------------------------------------------------------------------------
1 | import { BasicPager } from './BasicExample';
2 |
3 | export function installPlugin() { }
4 |
5 | export const demos = [
6 | { name: 'Basic Pager', path: 'basic', component: BasicPager }
7 | ];
8 |
--------------------------------------------------------------------------------
/demo-snippets/svelte/BasicExample.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 | goBack()} />
8 |
9 |
10 |
11 |
12 |
22 |
--------------------------------------------------------------------------------
/demo-snippets/svelte/install.ts:
--------------------------------------------------------------------------------
1 | import BasicExample from './BasicExample.svelte';
2 | import installWebRTC from '@nativescript-community/ui-webview-rtc';
3 |
4 | export function installPlugin() {
5 | installWebRTC();
6 | }
7 |
8 | export const demos = [{ name: 'Basic Example', path: 'basic', component: BasicExample }];
9 |
--------------------------------------------------------------------------------
/demo-snippets/vue/install.ts:
--------------------------------------------------------------------------------
1 | import Vue from 'nativescript-vue';
2 | import WebView from '@nativescript-community/ui-webview/vue';
3 | import {WebViewTraceCategory} from '@nativescript-community/ui-webview';
4 | import {Trace} from '@nativescript/core';
5 | import installWebRTC from '@nativescript-community/ui-webview-rtc';
6 |
7 | import BasicExample from './BasicExample.vue';
8 |
9 | export function installPlugin() {
10 | Trace.addCategories(WebViewTraceCategory);
11 | Trace.enable();
12 | installWebRTC();
13 | Vue.use(WebView);
14 | }
15 |
16 | export const demos = [{ name: 'Basic Example', path: 'basic', component: BasicExample }];
17 |
--------------------------------------------------------------------------------
/detox.config.js:
--------------------------------------------------------------------------------
1 | const devices = require('./devices');
2 |
3 | module.exports = {
4 | testRunner: 'jest',
5 | runnerConfig: 'e2e/config.json',
6 | configurations: {
7 | 'ng.ios': {
8 | binaryPath: 'demo-ng/platforms/ios/build/Debug-iphonesimulator/demong.app',
9 | build: 'cd demo-ng && ns build ios',
10 | type: 'ios.simulator',
11 | device: {
12 | type: devices.ios,
13 | },
14 | },
15 | 'ng.android': {
16 | binaryPath: 'demo-ng/platforms/android/app/build/outputs/apk/debug/app-debug.apk',
17 | build: 'cd demo-ng && ns build android --detox',
18 | type: 'android.emulator',
19 | device: {
20 | avdName: devices.android,
21 | },
22 | },
23 | 'vue.ios': {
24 | binaryPath: 'demo-vue/platforms/ios/build/Debug-iphonesimulator/demovue.app',
25 | build: 'cd demo-vue && ns build ios',
26 | type: 'ios.simulator',
27 | device: {
28 | type: devices.ios,
29 | },
30 | },
31 | 'vue.android': {
32 | binaryPath: 'demo-vue/platforms/android/app/build/outputs/apk/debug/app-debug.apk',
33 | build: 'cd demo-vue && ns build android --detox',
34 | type: 'android.emulator',
35 | device: {
36 | avdName: devices.android,
37 | },
38 | },
39 | 'svelte.ios': {
40 | binaryPath: 'demo-svelte/platforms/ios/build/Debug-iphonesimulator/demosvelte.app',
41 | build: 'cd demo-svelte && ns build ios',
42 | type: 'ios.simulator',
43 | device: {
44 | type: devices.ios,
45 | },
46 | },
47 | 'svelte.android': {
48 | binaryPath: 'demo-svelte/platforms/android/app/build/outputs/apk/debug/app-debug.apk',
49 | build: 'cd demo-svelte && ns build android --detox',
50 | type: 'android.emulator',
51 | device: {
52 | avdName: devices.android,
53 | },
54 | },
55 | 'react.ios': {
56 | binaryPath: 'demo-react/platforms/ios/build/Debug-iphonesimulator/demoreact.app',
57 | build: 'cd demo-react && ns build ios',
58 | type: 'ios.simulator',
59 | device: {
60 | type: devices.ios,
61 | },
62 | },
63 | 'react.android': {
64 | binaryPath: 'demo-react/platforms/android/app/build/outputs/apk/debug/app-debug.apk',
65 | build: 'cd demo-react && ns build android --detox',
66 | type: 'android.emulator',
67 | device: {
68 | avdName: devices.android,
69 | },
70 | },
71 | },
72 | };
73 |
--------------------------------------------------------------------------------
/devices.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | ios: 'iPhone 12 Pro Max',
3 | android: 'Pixel_3a_API_30_1'
4 | };
5 |
--------------------------------------------------------------------------------
/docs/.nojekyll:
--------------------------------------------------------------------------------
1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false.
--------------------------------------------------------------------------------
/docs/assets/hierarchy.js:
--------------------------------------------------------------------------------
1 | window.hierarchyData = "eJytlstSgzAUht8l61gLJIDdeakrZ3S8Lpwu0nJaMoagSVqdcfruhmo7QFFDdBEWJB//Nxw4yTtSZWk0Gj1SSjGhwQQjBXMBM8NLae+/I1pdJCsAjdDxA0zvObwijJ64zNAoCFOMlkrYuZlgWoM+fIXpyi4ZbNcOclMIC2zm7Tqjs4MKPvi8scbIxtYyvrDxmxmvQJozZtguLqTxNo5LA2rOZrXEDvLb8B1eTeZcZAqkfQuERpikMSZHgR0xpkOCaWBHGGEahXYkmJKhHfFkYx7VzC9KlvV1bjD9bVNMYoJJMvy0SVs2N4YpA15SbdTBrVKISUvhnEuucz+HPdZRIhnWJG7ycimyyxUoxTO4U8KnTD8/pHfdknRTryTt9PwPTT/LSiqNWxW8UuVCgdY+FdxjHSWO6h3hlhsBpzmTi/6fUSfrKhE329KxAOXTlJqcW7htPM1w+yaLZ5/0FugYH7TiT0s556rwyG+TjgJhtCegSwF+Ag3SUSAKawLX8LIEba5AFVzramvsK/LDE1yFko5d0nOL7BlN6g11XE2dL4XQMwUg+yp8h7uq1H/K8Rs3fzDpph1FKO08tJwwDS7HoybxyyGpsXvQyXq9/gDqJksx"
--------------------------------------------------------------------------------
/docs/assets/highlight.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --light-hl-0: #795E26;
3 | --dark-hl-0: #DCDCAA;
4 | --light-hl-1: #000000;
5 | --dark-hl-1: #D4D4D4;
6 | --light-hl-2: #A31515;
7 | --dark-hl-2: #CE9178;
8 | --light-hl-3: #AF00DB;
9 | --dark-hl-3: #C586C0;
10 | --light-hl-4: #001080;
11 | --dark-hl-4: #9CDCFE;
12 | --light-hl-5: #008000;
13 | --dark-hl-5: #6A9955;
14 | --light-hl-6: #000000;
15 | --dark-hl-6: #C8C8C8;
16 | --light-code-background: #FFFFFF;
17 | --dark-code-background: #1E1E1E;
18 | }
19 |
20 | @media (prefers-color-scheme: light) { :root {
21 | --hl-0: var(--light-hl-0);
22 | --hl-1: var(--light-hl-1);
23 | --hl-2: var(--light-hl-2);
24 | --hl-3: var(--light-hl-3);
25 | --hl-4: var(--light-hl-4);
26 | --hl-5: var(--light-hl-5);
27 | --hl-6: var(--light-hl-6);
28 | --code-background: var(--light-code-background);
29 | } }
30 |
31 | @media (prefers-color-scheme: dark) { :root {
32 | --hl-0: var(--dark-hl-0);
33 | --hl-1: var(--dark-hl-1);
34 | --hl-2: var(--dark-hl-2);
35 | --hl-3: var(--dark-hl-3);
36 | --hl-4: var(--dark-hl-4);
37 | --hl-5: var(--dark-hl-5);
38 | --hl-6: var(--dark-hl-6);
39 | --code-background: var(--dark-code-background);
40 | } }
41 |
42 | :root[data-theme='light'] {
43 | --hl-0: var(--light-hl-0);
44 | --hl-1: var(--light-hl-1);
45 | --hl-2: var(--light-hl-2);
46 | --hl-3: var(--light-hl-3);
47 | --hl-4: var(--light-hl-4);
48 | --hl-5: var(--light-hl-5);
49 | --hl-6: var(--light-hl-6);
50 | --code-background: var(--light-code-background);
51 | }
52 |
53 | :root[data-theme='dark'] {
54 | --hl-0: var(--dark-hl-0);
55 | --hl-1: var(--dark-hl-1);
56 | --hl-2: var(--dark-hl-2);
57 | --hl-3: var(--dark-hl-3);
58 | --hl-4: var(--dark-hl-4);
59 | --hl-5: var(--dark-hl-5);
60 | --hl-6: var(--dark-hl-6);
61 | --code-background: var(--dark-code-background);
62 | }
63 |
64 | .hl-0 { color: var(--hl-0); }
65 | .hl-1 { color: var(--hl-1); }
66 | .hl-2 { color: var(--hl-2); }
67 | .hl-3 { color: var(--hl-3); }
68 | .hl-4 { color: var(--hl-4); }
69 | .hl-5 { color: var(--hl-5); }
70 | .hl-6 { color: var(--hl-6); }
71 | pre, code { background: var(--code-background); }
72 |
--------------------------------------------------------------------------------
/docs/assets/navigation.js:
--------------------------------------------------------------------------------
1 | window.navigationData = "eJylmFtT2zAQhf9LnumNFtryloQwE1pohgSYKcODIm9iFVlydQnJdPrfK4cQ3+L1evqKz/mOLK02ix/+9BysXe+s9wzzlYDn3lEvZS4Of0h05CXYd7sHb2OXyPD0Saiod3Z81OOxkJEB1Tt72ENGK1DumiVgcw4on+SUXFEGfvl7tKf072F+V1oLl8zawlpeFWXGh+Mi5VZZn6baOIim599GxmjTDDwgxti7+NHaDZiFZmxZhxFHyoG58FJabgDUdpvOmWM5W2SKBeMFfJOpclYnp8WgtXCdcw57sJix+gXcjdbAvYNLtmJTbkTq0JgGDxbzXbOI9g4lZRvyQihhY+iArjnaIvL3uwGrveHQmlG3tIVMjF4asJb+HjVHW8TUsezW0BOqhvaAjYRpDEDfqLoFC7mB3x6sm4BJhLVCK+J2IT4sbhprL6MfKzAiglsj6SWMOmmR/5HZNXQmnIRhzNSSWh0HHVhE1lsnoWmHok3BOFH82TnAr8sxeOjdfRlktLXX1C3ooVYLYRIyvKpvx1stoQu+pG/Bhx1MUvrOVOQt8O0vJhVdElPAa/qyq3oMP2Q8hisdFZqT26QF3l5Qobz/+vnDyXGBdM1WYslc6CezAGjClVVtzNfKv2PSNyJLojYik1I/27GSQsEVRIJNJNvMGX/aXa5NnrJiRrB5cZRsNZfTP5aCvdMvg8LldBB60hJIiY0uJGruhXRj9VPrJNwPZ7S0lCzEhoTx1/qgRNTEGNhbp5NbC6a/DIVMwh+2ICFRuB7zMOJOnTaMdiQNFiwE5n5J3aKaGAMLm4YK7HrQiA0L00mXXaqpEbSwYTzUUo5UBoko/AYLEiJFIpzN+4+d6X6aDrRX0blOmFCkvaNTkKUkxd6RjWMijK7bsuUZk7IOIgJZhOUsACfhhGb6QpDuV4MFDckOacDMWEWCs1ARd8KKAKXFtZjbg8O58C5ZJT2GN5xEzWUY7OVf+Ow+kqB1OQL3Fu7DBFyZIdGABgsSsupAr2oR7PN+wKOA62oEvRuTZiYMT0PmYKkNCj+kr+Efy2vPjG+M443fprKHpO9TESyYl4WvEItQp9v2U0LtZGXk6aewrsd/gqDcYQ=="
--------------------------------------------------------------------------------
/docs/types/webview.CacheMode.html:
--------------------------------------------------------------------------------
1 | CacheMode | @nativescript-community/ui-webview-rootCacheMode: "default" | "cache_first" | "no_cache" | "cache_only" | "normal"
2 |
--------------------------------------------------------------------------------
/docs/types/webview.ViewPortValue.html:
--------------------------------------------------------------------------------
1 | ViewPortValue | @nativescript-community/ui-webview-root
2 |
--------------------------------------------------------------------------------
/docs/variables/webview.WebViewTraceCategory.html:
--------------------------------------------------------------------------------
1 | WebViewTraceCategory | @nativescript-community/ui-webview-rootVariable WebViewTraceCategoryConst
WebViewTraceCategory: "AWebView"
2 |
--------------------------------------------------------------------------------
/docs/variables/webview.autoInjectJSBridgeProperty.html:
--------------------------------------------------------------------------------
1 | autoInjectJSBridgeProperty | @nativescript-community/ui-webview-rootVariable autoInjectJSBridgePropertyConst
2 |
--------------------------------------------------------------------------------
/docs/variables/webview.builtInZoomControlsProperty.html:
--------------------------------------------------------------------------------
1 | builtInZoomControlsProperty | @nativescript-community/ui-webview-rootVariable builtInZoomControlsPropertyConst
2 |
--------------------------------------------------------------------------------
/docs/variables/webview.cacheModeProperty.html:
--------------------------------------------------------------------------------
1 | cacheModeProperty | @nativescript-community/ui-webview-rootVariable cacheModePropertyConst
2 |
--------------------------------------------------------------------------------
/docs/variables/webview.customUserAgentProperty.html:
--------------------------------------------------------------------------------
1 | customUserAgentProperty | @nativescript-community/ui-webview-rootVariable customUserAgentPropertyConst
2 |
--------------------------------------------------------------------------------
/docs/variables/webview.databaseStorageProperty.html:
--------------------------------------------------------------------------------
1 | databaseStorageProperty | @nativescript-community/ui-webview-rootVariable databaseStoragePropertyConst
2 |
--------------------------------------------------------------------------------
/docs/variables/webview.debugModeProperty.html:
--------------------------------------------------------------------------------
1 | debugModeProperty | @nativescript-community/ui-webview-rootVariable debugModePropertyConst
2 |
--------------------------------------------------------------------------------
/docs/variables/webview.domStorageProperty.html:
--------------------------------------------------------------------------------
1 | domStorageProperty | @nativescript-community/ui-webview-rootVariable domStoragePropertyConst
2 |
--------------------------------------------------------------------------------
/docs/variables/webview.isScrollEnabledProperty.html:
--------------------------------------------------------------------------------
1 | isScrollEnabledProperty | @nativescript-community/ui-webview-rootVariable isScrollEnabledPropertyConst
2 |
--------------------------------------------------------------------------------
/docs/variables/webview.scalesPageToFitProperty.html:
--------------------------------------------------------------------------------
1 | scalesPageToFitProperty | @nativescript-community/ui-webview-rootVariable scalesPageToFitPropertyConst
2 |
--------------------------------------------------------------------------------
/docs/variables/webview.scrollBounceProperty.html:
--------------------------------------------------------------------------------
1 | scrollBounceProperty | @nativescript-community/ui-webview-rootVariable scrollBouncePropertyConst
2 |
--------------------------------------------------------------------------------
/docs/variables/webview.srcProperty.html:
--------------------------------------------------------------------------------
1 | srcProperty | @nativescript-community/ui-webview-rootVariable srcPropertyConst
2 |
--------------------------------------------------------------------------------
/docs/variables/webview.supportZoomProperty.html:
--------------------------------------------------------------------------------
1 | supportZoomProperty | @nativescript-community/ui-webview-rootVariable supportZoomPropertyConst
2 |
--------------------------------------------------------------------------------
/docs/variables/webview.useWideViewPortProperty.html:
--------------------------------------------------------------------------------
1 | useWideViewPortProperty | @nativescript-community/ui-webview-rootVariable useWideViewPortPropertyConst
2 |
--------------------------------------------------------------------------------
/docs/variables/webview.webConsoleProperty.html:
--------------------------------------------------------------------------------
1 | webConsoleProperty | @nativescript-community/ui-webview-rootVariable webConsolePropertyConst
2 |
--------------------------------------------------------------------------------
/e2e/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "testEnvironment": "./environment",
3 | "testRunner": "jest-circus/runner",
4 | "testTimeout": 120000,
5 | "testRegex": "\\.e2e\\.js$",
6 | "reporters": ["detox/runners/jest/streamlineReporter"],
7 | "verbose": true
8 | }
9 |
--------------------------------------------------------------------------------
/e2e/environment.js:
--------------------------------------------------------------------------------
1 | const { DetoxCircusEnvironment, SpecReporter, WorkerAssignReporter } = require('detox/runners/jest-circus');
2 |
3 | class CustomDetoxEnvironment extends DetoxCircusEnvironment {
4 | constructor(config) {
5 | super(config);
6 |
7 | // Can be safely removed, if you are content with the default value (=300000ms)
8 | this.initTimeout = 300000;
9 |
10 | // This takes care of generating status logs on a per-spec basis. By default, Jest only reports at file-level.
11 | // This is strictly optional.
12 | this.registerListeners({
13 | SpecReporter,
14 | WorkerAssignReporter,
15 | });
16 | }
17 | }
18 |
19 | module.exports = CustomDetoxEnvironment;
20 |
--------------------------------------------------------------------------------
/e2e/run-tests.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | const { spawn } = require('child_process');
3 | const { argv } = require('yargs')
4 | .scriptName('run-tests')
5 | .usage('Usage: $0 -p num -h num')
6 | .example('$0', 'Builds and runs e2e testing on all supported platforms and frameworks.')
7 | .example('$0 -b', 'Build e2e testing for all supported platforms and frameworks.')
8 | .example('$0 -r', 'Run e2e testing for all supported platforms and frameworks.')
9 | .example('$0 -p ios', 'Builds and runs e2e testing for all frameworks only on iOS.')
10 | .example('$0 -f ng vue', 'Builds an d runs e2e testing on Angular and Vue.js.')
11 | .example('$0 -p android -f svelte', 'Builds and runs e2e testing for Svelte on iOS.')
12 | .option('p', {
13 | alias: 'platforms',
14 | default: ['ios', 'android'],
15 | choices: ['ios', 'android'],
16 | describe: 'The platforms to test on.',
17 | type: 'array',
18 | })
19 | .option('f', {
20 | alias: 'frameworks',
21 | default: ['ng', 'vue', 'svelte', 'react'],
22 | choices: ['ng', 'vue', 'svelte', 'react'],
23 | describe: 'The frameworks to test on.',
24 | type: 'array',
25 | })
26 | .option('b', {
27 | alias: 'build',
28 | default: false,
29 | describe: 'Flag to ONLY run building of the projects.',
30 | type: 'boolean',
31 | })
32 | .option('r', {
33 | alias: 'run',
34 | default: false,
35 | describe: 'Flag to ONLY run testing (no building) of the projects.',
36 | type: 'boolean',
37 | });
38 |
39 | const { platforms, frameworks, build, run } = argv;
40 | command = generateDetoxCommand(platforms, frameworks, build, run);
41 |
42 | console.log(command);
43 |
44 | function generateDetoxCommand(platforms, frameworks, build, run) {
45 |
46 | configurations = [];
47 | for (const platform of platforms) {
48 | for (const framework of frameworks) {
49 | configurations.push(`${framework}.${platform}`);
50 | }
51 | }
52 |
53 | configurations.sort();
54 |
55 | commands = [];
56 | if (!build && !run) {
57 | for (const configuration of configurations) {
58 | commands.push(`detox build -c ${configuration} && detox test -c ${configuration}`);
59 | }
60 | }
61 | else if(build) {
62 | for (const configuration of configurations) {
63 | commands.push(`detox build -c ${configuration}`);
64 | }
65 | }
66 | else if(run) {
67 | for (const configuration of configurations) {
68 | commands.push(`detox test -c ${configuration}`);
69 | }
70 | }
71 | else {
72 | for (const configuration of configurations) {
73 | commands.push(`detox build -c ${configuration} && detox test -c ${configuration}`);
74 | }
75 | }
76 |
77 | let combinedCommand = '';
78 | for (let i=0; i {
93 | process.stdout.write(`${data}`);
94 | });
95 |
96 | ls.stderr.on('data', (data) => {
97 | process.stderr.write(`${data}`);
98 | });
99 |
100 | ls.on('error', (error) => {
101 | console.log(`error: ${error.message}`);
102 | });
103 |
104 | ls.on('close', (code) => {
105 | console.log(`child process exited with code ${code}`);
106 | });
107 |
108 |
--------------------------------------------------------------------------------
/e2e/tests.e2e.js:
--------------------------------------------------------------------------------
1 | describe('Scroll Test', () => {
2 | beforeEach(async () => {
3 | await device.reloadReactNative();
4 | });
5 |
6 | const firstElement = 'TURQUOISE';
7 | const lastElement = 'ASBESTOS';
8 |
9 | it(`${firstElement} should be visible`, async () => {
10 | await expect(element(by.text(firstElement))).toBeVisible();
11 | });
12 |
13 | it(`${lastElement} should not be visible`, async () => {
14 | await expect(element(by.text(lastElement))).not.toBeVisible();
15 | });
16 |
17 | it('should scroll to bottom', async () => {
18 | await element(by.label('collectionView')).scrollTo('bottom');
19 | });
20 |
21 | it(`${lastElement} should be visible`, async () => {
22 | await expect(element(by.text(lastElement))).toBeVisible();
23 | });
24 |
25 | it(`${firstElement} should not be visible`, async () => {
26 | await expect(element(by.text(firstElement))).not.toBeVisible();
27 | });
28 |
29 | it('should scroll to top', async () => {
30 | await element(by.label('collectionView')).scrollTo('top');
31 | });
32 | });
33 |
--------------------------------------------------------------------------------
/images/demo-android.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/images/demo-android.gif
--------------------------------------------------------------------------------
/images/demo-ios.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/images/demo-ios.gif
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.5.2",
3 | "$schema": "node_modules/@lerna-lite/cli/schemas/lerna-schema.json",
4 | "packages": [
5 | "packages/*"
6 | ],
7 | "npmClient": "yarn",
8 | "useWorkspaces": true,
9 | "command": {
10 | "publish": {
11 | "cleanupTempFiles": true
12 | }
13 | },
14 | "npmClientArgs": [
15 | "--no-package-lock"
16 | ],
17 | "commitHooks": false,
18 | "createRelease": "github",
19 | "conventionalCommits": true,
20 | "private": false,
21 | "message": "chore(release): publish new version %v",
22 | "changelogPreset": "conventional-changelog-conventionalcommits",
23 | "ignoreChanges": [
24 | "**/__fixtures__/**",
25 | "**/__tests__/**",
26 | "**/*.md"
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------
/make-bridge-loader.ts:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const Terser = require('terser');
3 | const { promisify } = require('util');
4 |
5 | const fsWriteFile = promisify(fs.writeFile);
6 | const fsReadFile = promisify(fs.readFile);
7 |
8 | async function nativescriptWebviewBridgeLoader(platform: 'ios' | 'android') {
9 | let template = await fsReadFile(`./www-src/bridge-loader.${platform}.ts.tmpl`, 'UTF-8');
10 |
11 | const values = {
12 | // fetchPolyfill: await fsReadFile('./node_modules/whatwg-fetch/dist/fetch.umd.js', 'UTF-8'),
13 | // promisePolyfill: await fsReadFile('./www-src/node_modules/promise-polyfill/dist/polyfill.js', 'UTF-8'),
14 | webViewBridge: await fsReadFile(`./build/bridge.${platform}.js`, 'UTF-8'),
15 | metadataViewPort: await fsReadFile('./build/metadata-view-port.js', 'UTF-8'),
16 | };
17 |
18 | for (const [name, value] of Object.entries(values)) {
19 | const terserRes = await Terser.minify(value, {
20 | ecma: 2019,
21 | module: false,
22 | toplevel: false,
23 | keep_classnames: false,
24 | keep_fnames: false,
25 | compress: {
26 | passes: 2,
27 | drop_console: true
28 | },
29 | mangle: {
30 | toplevel: true,
31 | properties: {
32 | regex: /^(m[A-Z])/
33 | }
34 | }
35 | });
36 | template = template.replace(`= ${name} ?>`, JSON.stringify(terserRes.code));
37 | }
38 |
39 | await fsWriteFile(`./src/webview/nativescript-webview-bridge-loader.${platform}.ts`, template);
40 | }
41 |
42 | async function worker() {
43 | await nativescriptWebviewBridgeLoader('ios');
44 | await nativescriptWebviewBridgeLoader('android');
45 | }
46 |
47 | worker();
48 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@nativescript-community/ui-webview-root",
3 | "version": "1.0.0",
4 | "homepage": "https://github.com/nativescript-community/ui-webview#readme",
5 | "bugs": {
6 | "url": "https://github.com/nativescript-community/ui-webview/issues"
7 | },
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/nativescript-community/ui-webview.git"
11 | },
12 | "license": "ISC",
13 | "author": "",
14 | "scripts": {
15 | "build": "lerna run build",
16 | "build.all": "lerna run build.all",
17 | "build.all.win": "lerna run build.all.win",
18 | "build.angular": "lerna run build.angular",
19 | "build.angular.win": "lerna run build.angular.win",
20 | "build.win": "lerna run build.win",
21 | "clean": "rimraf 'packages/**/*.d.ts' 'packages/**/*.js' 'packages/**/*.js.map' 'packages/**/*.metada' 'packages/**/angular/ng-package.json'",
22 | "clean.win": "rimraf packages\\**\\*.d.ts packages\\**\\*.js packages\\**\\*.js.map packages\\**\\*.metadata.json packages\\**\\*.ngsummary.json node_modules package-lock.json",
23 | "commitmsg": "commitlint -e $GIT_PARAMS",
24 | "demo.ng.android": "cd ./demo-ng && ns run android --no-hmr --env.watchNodeModules",
25 | "demo.ng.clean": "cd ./demo-ng && ns clean",
26 | "demo.ng.ios": "cd ./demo-ng && ns run ios --no-hmr --env.watchNodeModules",
27 | "demo.react.android": "cd ./demo-react && ns run android --no-hmr --env.watchNodeModules",
28 | "demo.react.clean": "cd ./demo-react && ns clean",
29 | "demo.react.ios": "cd ./demo-react && ns run ios --no-hmr --env.watchNodeModules",
30 | "demo.svelte.android": "cd ./demo-svelte && ns run android --no-hmr --env.watchNodeModules",
31 | "demo.svelte.clean": "cd ./demo-svelte && ns clean",
32 | "demo.svelte.ios": "cd ./demo-svelte && ns run ios --no-hmr --env.watchNodeModules",
33 | "demo.vue.android": "cd ./demo-vue && ns run android --no-hmr --env.watchNodeModules",
34 | "demo.vue.clean": "cd ./demo-vue && ns clean",
35 | "demo.vue.ios": "cd ./demo-vue && ns run ios --no-hmr --env.watchNodeModules",
36 | "postinstall": "npm run setup",
37 | "publish": "npm run setup && npm run clean && npm run build.all && npm run readme && npm run doc && npm run commit_readme_doc_changes && lerna publish",
38 | "readme": "lerna run readme && node ./tools/readme.js",
39 | "setup": "npm run submodules && ts-patch install",
40 | "start": "./node_modules/.bin/ntl -A -s 15 -o",
41 | "submodules": "git submodule update --init",
42 | "sync": "node ./tools/sync.js",
43 | "sync.test": "node ./tools/sync.js",
44 | "tsc": "cpy '**/*.d.ts' '../plugin' --parents --cwd=src && tsc -skipLibCheck -d",
45 | "update": "node ./tools/update.js",
46 | "watch": "npm run tsc -- -w",
47 | "doc": "node tools/builddoc.mjs",
48 | "fullclean": "npm run clean && rimraf 'packages/**/node_modules' 'demo-*/hooks' 'demo-*/node_modules' 'package-lock.json' 'pnpm-lock.yaml' 'node_modules'",
49 | "commit_readme_doc_changes": "git add docs/** *.md ; git commit -m \"readme/doc\" ; echo \"commit readme doc done\""
50 | },
51 | "commitlint": {
52 | "extends": [
53 | "@commitlint/config-conventional"
54 | ]
55 | },
56 | "dependencies": {
57 | "@nativescript-community/plugin-seed-tools": "file:tools",
58 | "@nativescript-community/template-snippet": "file:demo-snippets"
59 | },
60 | "devDependencies": {
61 | "ts-node": "10.9.1"
62 | },
63 | "ntl": {
64 | "descriptions": {
65 | "build": "Build the plugin",
66 | "build.angular": "Build the plugin for Angular",
67 | "build.all": "Build the plugin for all platforms",
68 | "clean": "Clean the local environment.",
69 | "demo.ng.android": "Runs the Angular demo on Android.",
70 | "demo.ng.ios": "Runs the Angular demo on iOS.",
71 | "demo.react.android": "Runs the React demo on Android.",
72 | "demo.react.ios": "Runs the React demo on iOS.",
73 | "demo.svelte.android": "Runs the Svelte demo on Android.",
74 | "demo.svelte.ios": "Runs the Svelte demo on iOS.",
75 | "demo.vue.android": "Runs the Vue demo on Android.",
76 | "demo.vue.ios": "Runs the Vue demo on iOS.",
77 | "watch": "Watch for changes in the plugin source and re-build."
78 | }
79 | },
80 | "engines": {
81 | "npm": "please use yarn or pnpm",
82 | "yarn": ">=1.19.1",
83 | "pnpm": ">=7.0.0",
84 | "node": "^14.20.0 || ^16.13.0 || >=18.10.0"
85 | },
86 | "workspaces": [
87 | "packages/*",
88 | "demo*"
89 | ]
90 | }
91 |
--------------------------------------------------------------------------------
/packages/webview-rtc/.npmignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | tsconfig.json
3 | node_modules/
4 | pnpm-global/
5 | CHANGELOG.md
6 | blueprint.md
7 | *.aar
8 | *.jar
--------------------------------------------------------------------------------
/packages/webview-rtc/README.md:
--------------------------------------------------------------------------------
1 | # NativeScript WebView RTC
2 | [](https://www.npmjs.com/package/@nativescript-community/ui-webview-rtc)
3 | [](https://www.npmjs.com/package/@nativescript-community/ui-webview-rtc)
4 | [](https://www.npmjs.com/package/@nativescript-community/ui-webview-rtc)
5 |
6 | A NativeScript Plugin to add webRTC support to `@nativescript-community/ui-webview`
7 |
8 | ## Installation
9 | Run the following command from the root of your project:
10 |
11 | `tns plugin add @nativescript-community/ui-webview-rtc`
12 |
13 | This command automatically installs the necessary files, as well as stores @nativescript-community/ui-webview-rtc as a dependency in your project's package.json file.
14 |
15 | ## Configuration
16 |
17 | To install the plugin run
18 | ```typescript
19 | import install from '@nativescript-community/ui-webview-rtc';
20 | install();
21 | ```
22 |
23 | then simply use the `webRTC="true"` as a webview property
24 |
--------------------------------------------------------------------------------
/packages/webview-rtc/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@nativescript-community/ui-webview-rtc",
3 | "version": "1.5.2",
4 | "main": "./index",
5 | "sideEffects": false,
6 | "typings": "./index.d.ts",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/nativescript-community/ui-collectionview.git"
10 | },
11 | "scripts": {
12 | "build": "npm run tsc",
13 | "build.all": "npm run build",
14 | "tsc": "cpy '**/*.d.ts' '../../packages/webview-rtc' --parents --cwd=../../src/webview-rtc && tsc -skipLibCheck -d",
15 | "clean": "rimraf ./*.d.ts ./*.js ./*.js.map"
16 | },
17 | "nativescript": {
18 | "platforms": {
19 | "android": "6.1.0",
20 | "ios": "6.1.0"
21 | }
22 | },
23 | "keywords": [
24 | "NativeScript",
25 | "JavaScript",
26 | "Android",
27 | "iOS"
28 | ],
29 | "author": {
30 | "name": "Martin Guillon",
31 | "email": "martin@akylas.fr"
32 | },
33 | "license": "ISC",
34 | "bugs": {
35 | "url": "https://github.com/nativescript-community/ui-webview/issues"
36 | },
37 | "homepage": "https://github.com/nativescript-community/ui-webview#readme",
38 | "dependencies": {
39 | "@nativescript-community/ui-webview": "^1.5.2"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/packages/webview-rtc/platforms/ios/Podfile:
--------------------------------------------------------------------------------
1 | pod 'WKWebViewRTC', :git => 'https://github.com/farfromrefug/WKWebViewRTC.git', :branch => 'dev'
--------------------------------------------------------------------------------
/packages/webview-rtc/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "rootDir": "../../src/webview-rtc",
5 | "outDir": "./",
6 | "paths": {
7 | "@nativescript-community/ui-webview": ["packages/webview/index"],
8 | "@nativescript-community/ui-webview/*": ["packages/webview/*"]
9 | }
10 | },
11 | "include": ["../../src/webview-rtc/**/*.ts", "../../references.d.ts", "../../tools/references.d.ts", "../../src/references.d.ts"],
12 | "exclude": ["../../src/webview-rtc/angular/**"]
13 | }
14 |
--------------------------------------------------------------------------------
/packages/webview/.npmignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | tsconfig.json
3 | node_modules/
4 | pnpm-global/
5 | CHANGELOG.md
6 | blueprint.md
7 | *.aar
8 | *.jar
--------------------------------------------------------------------------------
/packages/webview/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@nativescript-community/ui-webview",
3 | "version": "1.5.2",
4 | "description": "Advanced WebView plugin for NativeScript",
5 | "main": "./index",
6 | "sideEffects": false,
7 | "typings": "./index.d.ts",
8 | "scripts": {
9 | "build": "npm run build.www && npm run tsc",
10 | "build.www": " cd ../../www-src && rollup -c && cd .. && ts-node make-bridge-loader",
11 | "build.all": "npm run build && npm run build.angular",
12 | "build.angular": "ng-packagr -p ../../src/webview/angular/ng-package.json -c ../../src/webview/angular/tsconfig.json && rm angular/.npmignore",
13 | "tsc": "cpy '**/*.d.ts' '../../packages/webview' --parents --cwd=../../src/webview && tsc -skipLibCheck -d",
14 | "clean": "rimraf ./*.d.ts ./*.js ./*.js.map"
15 | },
16 | "nativescript": {
17 | "platforms": {
18 | "android": "6.0.0",
19 | "ios": "6.0.0"
20 | }
21 | },
22 | "keywords": [
23 | "NativeScript",
24 | "JavaScript",
25 | "Android",
26 | "iOS",
27 | "webview",
28 | "WebView",
29 | "cache",
30 | "NativeScript UI",
31 | "nativescript community",
32 | "Angular",
33 | "Vue.js",
34 | "Vue.js Native",
35 | "Vue Native",
36 | "Svelte",
37 | "Svelte Native",
38 | "React",
39 | "React NativeScript",
40 | "preview|https://raw.githubusercontent.com/nativescript-community/ui-webview/master/images/demo-ios.gif|iOS Demo",
41 | "preview|https://raw.githubusercontent.com/nativescript-community/ui-webview/master/images/demo-android.gif|Android Demo"
42 | ],
43 | "author": {
44 | "name": "Nota",
45 | "email": "app@nota.dk",
46 | "url": "https://nota.dk"
47 | },
48 | "contributors": [
49 | {
50 | "name": "Martin Guillon",
51 | "email": "martin@akylas.fr"
52 | },
53 | {
54 | "name": "Morten Anton Bach Sjøgren",
55 | "url": "http://mabs.dk",
56 | "email": "m_abs@mabs.dk"
57 | },
58 | {
59 | "name": "Daniel Dam Freiling",
60 | "email": "dfg@nota.dk"
61 | }
62 | ],
63 | "bugs": {
64 | "url": "https://github.com/nativescript-community/ui-webview/issues"
65 | },
66 | "repository": {
67 | "type": "git",
68 | "url": "https://github.com/nativescript-community/ui-webview"
69 | },
70 | "license": "Apache-2.0",
71 | "readmeFilename": "README.md",
72 | "dependencies": {
73 | "url": "^0.11.0"
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/packages/webview/platforms/android/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
--------------------------------------------------------------------------------
/packages/webview/platforms/android/buildscript.gradle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/packages/webview/platforms/android/buildscript.gradle
--------------------------------------------------------------------------------
/packages/webview/platforms/android/include.gradle:
--------------------------------------------------------------------------------
1 |
2 | dependencies {
3 | implementation 'androidx.core:core:1.7.0'
4 | }
5 |
--------------------------------------------------------------------------------
/packages/webview/platforms/android/java/com/nativescript/webviewinterface/WebChromeClient.java:
--------------------------------------------------------------------------------
1 | package com.nativescript.webviewinterface;
2 |
3 | public class WebChromeClient extends android.webkit.WebChromeClient {
4 | boolean mConsoleEnabled ;
5 |
6 | public WebChromeClient() {
7 | super();
8 | mConsoleEnabled = true;
9 | }
10 | public void setConsoleEnabled(boolean value) {
11 | mConsoleEnabled = value;
12 | }
13 |
14 | public boolean isConsoleEnabled() {
15 | return mConsoleEnabled;
16 | }
17 | public boolean onConsoleMessage(android.webkit.ConsoleMessage message) {
18 | if(mConsoleEnabled == false) {
19 | return true;
20 | }
21 | return handleConsoleMessage(message);
22 | }
23 |
24 | public boolean handleConsoleMessage(android.webkit.ConsoleMessage message) {
25 | return false;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/packages/webview/platforms/android/java/com/nativescript/webviewinterface/WebViewBridgeInterface.java:
--------------------------------------------------------------------------------
1 | package com.nativescript.webviewinterface;
2 |
3 | import android.webkit.JavascriptInterface;
4 |
5 | public class WebViewBridgeInterface {
6 | public WebViewBridgeInterface() {
7 | }
8 |
9 | @JavascriptInterface
10 | public void emitEvent(String eventName, String data) {
11 | this.emitEventToNativeScript(eventName, data);
12 | }
13 |
14 | public void emitEventToNativeScript(String eventName, String data) {
15 | // Extend this function in nativescript
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/webview/platforms/android/native-api-usage.json:
--------------------------------------------------------------------------------
1 | {
2 | "uses": [
3 | "com.nativescript.webviewinterface:",
4 | "android.webkit:WebView",
5 | "android.webkit:WebViewClient",
6 | "android.webkit:WebChromeClient",
7 | "android.webkit:WebResourceRequest",
8 | "android.webkit:WebResourceResponse",
9 | "android.webkit:WebSettings",
10 | "android.webkit:JsResult",
11 | "android.webkit:ConsoleMessage",
12 | "android.webkit:ValueCallback",
13 | "android.webkit:PermissionRequest",
14 | "android.webkit:ConsoleMessage.MessageLevel"
15 | ]
16 | }
--------------------------------------------------------------------------------
/packages/webview/platforms/ios/native-api-usage.json:
--------------------------------------------------------------------------------
1 | {
2 | "uses": [
3 | "NativescriptWebViewExt*:*",
4 | "WebKit.WKURLSchemeHandler:*"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/packages/webview/platforms/ios/src/Constants.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Constants.swift
3 | // NotaWebViewExt
4 | //
5 | // Created by Morten Anton Bach Sjøgren on 14/01/2020.
6 | // Copyright © 2020 Morten Anton Bach Sjøgren. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct Constants {
12 | static let customURLScheme = "x-local"
13 |
14 | static let mimeType: [String: String] = [
15 | "html": "text/html",
16 | "htm": "text/html",
17 | "xhtml": "text/html",
18 | "xhtm": "text/html",
19 | "css": "text/css",
20 | "gif": "image/gif",
21 | "jpeg": "image/jpeg",
22 | "jpg": "image/jpeg",
23 | "js": "text/javascript",
24 | "otf": "application/vnd.ms-opentype",
25 | "png": "image/png",
26 | "svg": "image/svg+xml",
27 | "ttf": "application/x-font-ttf",
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/packages/webview/platforms/ios/src/Info.plist:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/packages/webview/platforms/ios/src/Info.plist
--------------------------------------------------------------------------------
/packages/webview/platforms/ios/src/WKWebviewCustomSchemeHandler.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WKWebviewCustomSchemeHandler.swift
3 | // NativescripWebViewExt
4 | //
5 | // Created by Morten Anton Bach Sjøgren on 14/01/2020.
6 | // Copyright © 2020 Morten Anton Bach Sjøgren. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import WebKit;
11 |
12 | enum WebErrors: Error {
13 | case RequestFailedError
14 | }
15 |
16 | @available(iOS 11, *)
17 | @objc
18 | public class CustomUrlSchemeHandler: NSObject,WKURLSchemeHandler {
19 | var resourceDict: [String: String] = [:];
20 |
21 | @objc
22 | public func resolveFilePath(_ url: URL) -> String? {
23 | // NSLog("CustomUrlSchemeHandler.resolveFilePath(%@)", url.absoluteString);
24 | guard url.absoluteString.starts(with: Constants.customURLScheme) else {
25 | // NSLog("CustomUrlSchemeHandler.resolveFilePath(%@) - invalid scheme", url.absoluteString);
26 | return nil
27 | }
28 | let urlStr = url.host! + url.path
29 | guard let filepath = self.getRegisteredLocalResource(forKey: urlStr) else {
30 | // NSLog("CustomUrlSchemeHandler.resolveFilePath(%@) - no path", url.absoluteString);
31 | return nil;
32 | }
33 |
34 | // NSLog("CustomUrlSchemeHandler.resolveFilePath(%@) - path(%@) - filepath(%@)", url.absoluteString, urlStr, filepath);
35 | return filepath
36 | }
37 |
38 | @objc
39 | public func resolveMimeTypeFrom(filepath: String) -> String {
40 | let ext = URL(fileURLWithPath: filepath).pathExtension;
41 | // NSLog("CustomUrlSchemeHandler.resolveMimeTypeFrom(%@) - ext(%@)", filepath, ext)
42 | if let mimetype = Constants.mimeType[ext] {
43 | // NSLog("CustomUrlSchemeHandler.resolveMimeTypeFrom(%@) - ext(%@) -> mimetype(%@)", filepath, ext, mimetype)
44 | return mimetype
45 | }
46 |
47 | return "application/octet-stream"
48 | }
49 |
50 | @objc
51 | public func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {
52 | // NSLog("CustomUrlSchemeHandler");
53 | DispatchQueue.global().async {
54 | // NSLog("CustomUrlSchemeHandler -> global async");
55 | guard let url = urlSchemeTask.request.url, url.scheme == Constants.customURLScheme else {
56 | // NSLog("CustomUrlSchemeHandler - NO URL")
57 | urlSchemeTask.didFailWithError(WebErrors.RequestFailedError)
58 | return;
59 | }
60 | // NSLog("CustomUrlSchemeHandler - URL(%@)", url.absoluteString)
61 | guard let filepath = self.resolveFilePath(url) else {
62 | // NSLog("CustomUrlSchemeHandler - URL(%@) no path", url.absoluteString)
63 | urlSchemeTask.didFailWithError(WebErrors.RequestFailedError)
64 | return;
65 | }
66 | let mimeType = self.resolveMimeTypeFrom(filepath: filepath);
67 | // NSLog("CustomUrlSchemeHandler - URL(%@) path(%@)", url.absoluteString, filepath)
68 | guard let data = NSData.init(contentsOfFile: filepath) else {
69 | // NSLog("CustomUrlSchemeHandler - URL(%@) path(%@) no data", url.absoluteString, filepath)
70 | urlSchemeTask.didFailWithError(WebErrors.RequestFailedError)
71 | return;
72 | }
73 |
74 | let urlResponse = HTTPURLResponse.init(url: url, statusCode: 200, httpVersion: "HTTP/1.1", headerFields: ["Content-Type": mimeType, "Access-Control-Allow-Origin": "*"])
75 |
76 | urlSchemeTask.didReceive(urlResponse!)
77 | urlSchemeTask.didReceive(data as Data)
78 | urlSchemeTask.didFinish()
79 | }
80 | }
81 |
82 | @objc
83 | public func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {
84 | urlSchemeTask.didFailWithError(WebErrors.RequestFailedError)
85 | }
86 |
87 | @objc
88 | public func registerLocalResource(forKey: String, filepath: String) {
89 | self.resourceDict[forKey] = filepath;
90 | }
91 |
92 | @objc
93 | public func unregisterLocalResource(forKey: String) {
94 | self.resourceDict.removeValue(forKey: forKey)
95 | }
96 |
97 | @objc
98 | public func getRegisteredLocalResource(forKey: String) -> String? {
99 | return self.resourceDict[forKey]
100 | }
101 |
102 | @objc
103 | public func clearRegisteredLocalResource() {
104 | self.resourceDict = [:]
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/packages/webview/platforms/ios/src/module.modulemap:
--------------------------------------------------------------------------------
1 | framework module NativescriptWebViewExt {
2 | umbrella header "NativescriptWebViewExt.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
8 | module NativescriptWebViewExt.Swift {
9 | header "NativescriptWebViewExt-Swift.h"
10 | requires objc
11 | }
12 |
--------------------------------------------------------------------------------
/packages/webview/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "rootDir": "../../src/webview",
5 | "outDir": "./"
6 | },
7 | "include": ["../../src/webview/**/*.ts", "../../references.d.ts", "../../tools/references.d.ts", "../../src/references.d.ts"],
8 | "exclude": ["../../src/webview/angular/**"]
9 | }
10 |
--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 | - packages/*
3 | - demo-*
--------------------------------------------------------------------------------
/references.d.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/references.d.ts
--------------------------------------------------------------------------------
/src-native/webview/android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 |
--------------------------------------------------------------------------------
/src-native/webview/android/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | android
4 | Project android created by Buildship.
5 |
6 |
7 |
8 |
9 | org.eclipse.buildship.core.gradleprojectbuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.buildship.core.gradleprojectnature
16 |
17 |
18 |
19 | 1627552108089
20 |
21 | 30
22 |
23 | org.eclipse.core.resources.regexFilterMatcher
24 | node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src-native/webview/android/.settings/org.eclipse.buildship.core.prefs:
--------------------------------------------------------------------------------
1 | arguments=
2 | auto.sync=false
3 | build.scans.enabled=false
4 | connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(6.8))
5 | connection.project.dir=
6 | eclipse.preferences.version=1
7 | gradle.user.home=
8 | java.home=/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home
9 | jvm.arguments=
10 | offline.mode=false
11 | override.workspace.settings=true
12 | show.console.view=true
13 | show.executions.view=true
14 |
--------------------------------------------------------------------------------
/src-native/webview/android/app/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src-native/webview/android/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/src-native/webview/android/app/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | app
4 | Project app created by Buildship.
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.buildship.core.gradleprojectbuilder
15 |
16 |
17 |
18 |
19 |
20 | org.eclipse.jdt.core.javanature
21 | org.eclipse.buildship.core.gradleprojectnature
22 |
23 |
24 |
25 | 1627552108093
26 |
27 | 30
28 |
29 | org.eclipse.core.resources.regexFilterMatcher
30 | node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/src-native/webview/android/app/.settings/org.eclipse.buildship.core.prefs:
--------------------------------------------------------------------------------
1 | connection.project.dir=..
2 | eclipse.preferences.version=1
3 |
--------------------------------------------------------------------------------
/src-native/webview/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: "kotlin-kapt"
4 |
5 | android {
6 | compileOptions {
7 | sourceCompatibility JavaVersion.VERSION_1_8
8 | targetCompatibility JavaVersion.VERSION_1_8
9 | }
10 | compileSdkVersion 30
11 | defaultConfig {
12 | applicationId "com.nativescript.imagedemo"
13 | minSdkVersion 19
14 | targetSdkVersion 30
15 | versionCode 1
16 | versionName "1.0"
17 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
18 | }
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 | buildFeatures {
26 | viewBinding {
27 | enabled = true
28 | }
29 | dataBinding {
30 | enabled = true
31 | }
32 | }
33 | }
34 |
35 | dependencies {
36 | implementation fileTree(dir: 'libs', include: ['*.jar'])
37 | implementation 'androidx.appcompat:appcompat:1.0.0'
38 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
39 | testImplementation 'junit:junit:4.12'
40 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
41 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
42 | implementation 'com.squareup.okhttp3:okhttp:3.10.0'
43 | implementation 'com.github.bumptech.glide:okhttp3-integration:4.10.0'
44 | implementation 'jp.wasabeef:glide-transformations:4.1.0'
45 | implementation 'jp.co.cyberagent.android:gpuimage:2.0.3'
46 | implementation 'com.github.bumptech.glide:glide:4.11.0'
47 | kapt 'com.github.bumptech.glide:compiler:4.11.0'
48 | kapt 'androidx.annotation:annotation:1.1.0'
49 | implementation 'androidx.recyclerview:recyclerview:1.0.0'
50 | implementation project(path: ':image')
51 | implementation "androidx.core:core-ktx:+"
52 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
53 | }
54 | repositories {
55 | mavenCentral()
56 | }
57 |
--------------------------------------------------------------------------------
/src-native/webview/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/androidTest/java/com/github/triniwiz/imagedemo/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.nativescript.imagedemo
2 |
3 | import android.content.Context
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 | import androidx.test.platform.app.InstrumentationRegistry
6 | import org.junit.Assert
7 | import org.junit.Test
8 | import org.junit.runner.RunWith
9 |
10 | /**
11 | * Instrumented test, which will execute on an Android device.
12 | *
13 | * @see [Testing documentation](http://d.android.com/tools/testing)
14 | */
15 | @RunWith(AndroidJUnit4::class)
16 | class ExampleInstrumentedTest {
17 | @Test
18 | fun useAppContext() {
19 | // Context of the app under test.
20 | val appContext: Context = InstrumentationRegistry.getTargetContext()
21 | Assert.assertEquals("com.nativescript.imagedemo", appContext.packageName)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/java/com/nativescript/imagedemo/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.nativescript.imagedemo
2 |
3 | import android.app.Activity
4 | import android.graphics.Color
5 | import android.graphics.drawable.ColorDrawable
6 | import android.net.Uri
7 | import android.os.Bundle
8 | import android.os.Handler
9 | import android.util.Log
10 | import android.view.LayoutInflater
11 | import android.view.View
12 | import android.view.ViewGroup
13 | import android.widget.TextView
14 | import androidx.appcompat.app.AppCompatActivity
15 | import androidx.recyclerview.widget.LinearLayoutManager
16 | import androidx.recyclerview.widget.RecyclerView
17 | import androidx.recyclerview.widget.RecyclerView.ViewHolder
18 | import com.bumptech.glide.Glide
19 | import com.nativescript.image.ImageView
20 | import com.nativescript.image.ImageView.Companion.enableAutoMM
21 | import com.nativescript.imagedemo.databinding.ActivityMainBinding
22 | import org.json.JSONArray
23 | import org.json.JSONException
24 |
25 | class MainActivity : AppCompatActivity() {
26 | lateinit var binding: ActivityMainBinding
27 | var list: JSONArray? = null
28 | fun dp(dp: Int): Int {
29 | return dp * resources.displayMetrics.density as Int
30 | }
31 |
32 | override fun onCreate(savedInstanceState: Bundle?) {
33 | list = Data.items
34 | binding = ActivityMainBinding.inflate(layoutInflater)
35 | super.onCreate(savedInstanceState)
36 | setContentView(binding.getRoot())
37 | val recyclerView = binding.listView
38 | val adapter: Adapter = Adapter()
39 | recyclerView.adapter = adapter
40 | recyclerView.layoutManager = LinearLayoutManager(this)
41 | val activity: Activity = this
42 | recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
43 | override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
44 | super.onScrollStateChanged(recyclerView, newState)
45 | when (newState) {
46 | RecyclerView.SCROLL_STATE_SETTLING, RecyclerView.SCROLL_STATE_DRAGGING -> Glide.with(activity).pauseAllRequests()
47 | RecyclerView.SCROLL_STATE_IDLE -> Glide.with(activity).resumeRequests()
48 | }
49 | }
50 |
51 | override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
52 | super.onScrolled(recyclerView, dx, dy)
53 | }
54 | })
55 | enableAutoMM(application)
56 | }
57 |
58 | internal inner class Holder(itemView: View) : ViewHolder(itemView) {
59 | var imageView: ImageView?
60 | var foreground: ImageView? = null
61 | var textView: TextView?
62 | fun setText(text: String?) {
63 | textView?.setText(text)
64 | }
65 |
66 | init {
67 | imageView = itemView.findViewById(R.id.imageView)
68 | textView = itemView.findViewById(R.id.textView)
69 | // foreground = itemView.findViewById(R.id.imageView2)
70 | }
71 | }
72 |
73 | var handler: Handler? = Handler()
74 |
75 | internal inner class Adapter : RecyclerView.Adapter() {
76 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
77 | val inflater = LayoutInflater.from(parent.context)
78 | val view = inflater.inflate(R.layout.list_item, parent, false)
79 | return Holder(view)
80 | }
81 |
82 | override fun onBindViewHolder(holder: Holder, position: Int) {
83 | try {
84 | val json = list?.getJSONObject(position)
85 | val url = json?.optString("url") ?: ""
86 | //holder.imageView.setPlaceHolder("res://law");
87 | // holder.imageView?.setPlaceHolder("res://placeholder_dark_grey_square")
88 |
89 | // holder.imageView.setErrorHolder("res://error");
90 | // holder.imageView.setAdjustViewBounds(false);
91 | // holder.imageView.setScaleType(android.widget.ImageView.ScaleType.FIT_XY);
92 | holder.imageView?.setScaleType(android.widget.ImageView.ScaleType.FIT_CENTER)
93 | holder.imageView?.addBasicAuth("httpwatch", "httpwatch")
94 | if (position % 2 == 0) {
95 | holder.imageView?.priority = ImageView.Priority.Low
96 | } else {
97 | holder.imageView?.priority = ImageView.Priority.High
98 | }
99 |
100 | if (url.isNotEmpty()) {
101 | holder.imageView?.setSource(url)
102 | holder.textView?.text = url
103 | } else {
104 | holder.imageView?.setSource(null)
105 | holder.textView?.text = url
106 | }
107 | } catch (e: JSONException) {
108 | e.printStackTrace()
109 | }
110 | }
111 |
112 | override fun getItemCount(): Int {
113 | return list?.length() ?: 0
114 | }
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/res/drawable/bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/res/drawable/error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/src-native/webview/android/app/src/main/res/drawable/error.png
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/res/drawable/law.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/src-native/webview/android/app/src/main/res/drawable/law.jpg
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
13 |
14 |
23 |
24 |
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/res/layout/list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
10 |
18 |
19 |
36 |
37 |
48 |
49 |
50 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/src-native/webview/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/src-native/webview/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/src-native/webview/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/src-native/webview/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/src-native/webview/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/src-native/webview/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/src-native/webview/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/src-native/webview/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/src-native/webview/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/src-native/webview/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 | #ff0000
7 | #ffffff
8 | #000000
9 | #007E00
10 | #0000ff
11 | #FF00F2
12 |
13 |
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ImageDemo
3 |
4 |
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src-native/webview/android/app/src/test/java/com/github/triniwiz/imagedemo/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.nativescript.imagedemo
2 |
3 | import org.junit.Assert
4 | import org.junit.Test
5 |
6 | /**
7 | * Example local unit test, which will execute on the development machine (host).
8 | *
9 | * @see [Testing documentation](http://d.android.com/tools/testing)
10 | */
11 | class ExampleUnitTest {
12 | @Test
13 | fun addition_isCorrect() {
14 | Assert.assertEquals(4, (2 + 2).toLong())
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src-native/webview/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.kotlin_version = '1.4.21'
5 | repositories {
6 | google()
7 |
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:4.1.1'
11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
12 |
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | google()
21 |
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
--------------------------------------------------------------------------------
/src-native/webview/android/gradle.properties:
--------------------------------------------------------------------------------
1 | ## For more details on how to configure your build environment visit
2 | # http://www.gradle.org/docs/current/userguide/build_environment.html
3 | #
4 | # Specifies the JVM arguments used for the daemon process.
5 | # The setting is particularly useful for tweaking memory settings.
6 | # Default value: -Xmx1024m -XX:MaxPermSize=256m
7 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
8 | #
9 | # When configured, Gradle will run in incubating parallel mode.
10 | # This option should only be used with decoupled projects. More details, visit
11 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
12 | # org.gradle.parallel=true
13 | #Fri Dec 18 13:51:47 AST 2020
14 | android.enableJetifier=true
15 | android.useAndroidX=true
16 | org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M"
17 |
--------------------------------------------------------------------------------
/src-native/webview/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Dec 18 13:45:18 AST 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
7 |
--------------------------------------------------------------------------------
/src-native/webview/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/src-native/webview/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 | include ':webview'
3 |
--------------------------------------------------------------------------------
/src-native/webview/android/webview/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/src-native/webview/android/webview/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: "kotlin-kapt"
4 |
5 | android {
6 | compileSdkVersion 30
7 | buildToolsVersion "29.0.3"
8 |
9 | defaultConfig {
10 | minSdkVersion 17
11 | targetSdkVersion 30
12 | versionCode 1
13 | versionName "1.0"
14 |
15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
16 | consumerProguardFiles 'consumer-rules.pro'
17 | }
18 |
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 |
26 | }
27 |
28 | repositories {
29 | mavenCentral()
30 | google()
31 | }
32 |
33 | dependencies {
34 | implementation fileTree(dir: 'libs', include: ['*.jar'])
35 |
36 | implementation 'androidx.appcompat:appcompat:1.0.0'
37 | testImplementation 'junit:junit:4.12'
38 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
39 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
40 | implementation 'com.squareup.okhttp3:okhttp:3.10.0'
41 | implementation 'com.github.bumptech.glide:okhttp3-integration:4.11.0'
42 | implementation 'jp.wasabeef:glide-transformations:4.1.0'
43 | implementation 'jp.co.cyberagent.android:gpuimage:2.0.3'
44 | implementation 'com.github.bumptech.glide:glide:4.11.0'
45 | kapt 'com.github.bumptech.glide:compiler:4.11.0'
46 | annotationProcessor 'androidx.annotation:annotation:1.1.0'
47 | implementation "androidx.core:core:1.3.2"
48 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
49 | }
50 |
--------------------------------------------------------------------------------
/src-native/webview/android/webview/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/src-native/webview/android/webview/consumer-rules.pro
--------------------------------------------------------------------------------
/src-native/webview/android/webview/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/src-native/webview/android/webview/src/androidTest/java/com/nativescript/image/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.nativescript.image;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.test.platform.app.InstrumentationRegistry;
6 | import androidx.test.ext.junit.runners.AndroidJUnit4;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
24 |
25 | assertEquals("com.nativescript.image.test", appContext.getPackageName());
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src-native/webview/android/webview/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/src-native/webview/android/webview/src/main/java/com:
--------------------------------------------------------------------------------
1 | ../../../../../../../packages/webview/platforms/android/java/com
--------------------------------------------------------------------------------
/src-native/webview/android/webview/src/main/res/drawable-hdpi/ic_indicator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/src-native/webview/android/webview/src/main/res/drawable-hdpi/ic_indicator.png
--------------------------------------------------------------------------------
/src-native/webview/android/webview/src/main/res/drawable-mdpi/ic_indicator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/src-native/webview/android/webview/src/main/res/drawable-mdpi/ic_indicator.png
--------------------------------------------------------------------------------
/src-native/webview/android/webview/src/main/res/drawable-xhdpi/ic_indicator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/src-native/webview/android/webview/src/main/res/drawable-xhdpi/ic_indicator.png
--------------------------------------------------------------------------------
/src-native/webview/android/webview/src/main/res/drawable-xxhdpi/ic_indicator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/src-native/webview/android/webview/src/main/res/drawable-xxhdpi/ic_indicator.png
--------------------------------------------------------------------------------
/src-native/webview/android/webview/src/main/res/drawable-xxxhdpi/ic_indicator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nativescript-community/ui-webview/4bfe01c7f40471450a91cca00cb6a6e4a3dea981/src-native/webview/android/webview/src/main/res/drawable-xxxhdpi/ic_indicator.png
--------------------------------------------------------------------------------
/src-native/webview/android/webview/src/main/res/drawable/progress_animation.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
--------------------------------------------------------------------------------
/src-native/webview/android/webview/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src-native/webview/android/webview/src/test/java/com/nativescript/image/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.nativescript.image;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/src/webview-rtc/index.android.ts:
--------------------------------------------------------------------------------
1 | import { AWebView } from '@nativescript-community/ui-webview';
2 | import { webRTCProperty } from './index.common';
3 | export default function install() {
4 | AWebView.prototype[webRTCProperty.setNative] = function (enabled: boolean) {};
5 | }
6 |
--------------------------------------------------------------------------------
/src/webview-rtc/index.common.ts:
--------------------------------------------------------------------------------
1 | import { AWebView } from '@nativescript-community/ui-webview';
2 | import { Property, booleanConverter } from '@nativescript/core';
3 |
4 | export const webRTCProperty = new Property({
5 | name: 'webRTC',
6 | defaultValue: false,
7 | valueConverter: booleanConverter
8 | });
9 |
10 | webRTCProperty.register(AWebView);
11 |
--------------------------------------------------------------------------------
/src/webview-rtc/index.d.ts:
--------------------------------------------------------------------------------
1 | export default function install();
2 |
3 | declare module '@nativescript-community/ui-webview' {
4 | interface AWebView {
5 | webRTC: boolean;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/webview-rtc/index.ios.ts:
--------------------------------------------------------------------------------
1 | import { AWebView } from '@nativescript-community/ui-webview';
2 | import { webRTCProperty } from './index.common';
3 | export default function install() {
4 | AWebView.prototype[webRTCProperty.setNative] = function (enabled: boolean) {
5 | const nativeView = this.nativeViewProtected;
6 | if (!nativeView || this.webViewRTC) {
7 | return;
8 | }
9 |
10 | this.webViewRTC = WKWebViewRTC.alloc().initWithWkwebviewContentController(nativeView, nativeView.configuration.userContentController);
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/src/webview-rtc/types/ios/objc!WKWebViewRTC.d.ts:
--------------------------------------------------------------------------------
1 |
2 | declare class WKWebViewRTC extends NSObject implements WKScriptMessageHandler {
3 |
4 | static alloc(): WKWebViewRTC; // inherited from NSObject
5 |
6 | static new(): WKWebViewRTC; // inherited from NSObject
7 |
8 | readonly debugDescription: string; // inherited from NSObjectProtocol
9 |
10 | readonly description: string; // inherited from NSObjectProtocol
11 |
12 | readonly hash: number; // inherited from NSObjectProtocol
13 |
14 | readonly isProxy: boolean; // inherited from NSObjectProtocol
15 |
16 | readonly superclass: typeof NSObject; // inherited from NSObjectProtocol
17 |
18 | readonly // inherited from NSObjectProtocol
19 |
20 | constructor(o: { wkwebview: WKWebView; contentController: WKUserContentController; });
21 |
22 | class(): typeof NSObject;
23 |
24 | conformsToProtocol(aProtocol: any /* Protocol */): boolean;
25 |
26 | dispose(): void;
27 |
28 | initWithWkwebviewContentController(wkwebview: WKWebView, contentController: WKUserContentController): this;
29 |
30 | isEqual(object: any): boolean;
31 |
32 | isKindOfClass(aClass: typeof NSObject): boolean;
33 |
34 | isMemberOfClass(aClass: typeof NSObject): boolean;
35 |
36 | performSelector(aSelector: string): any;
37 |
38 | performSelectorWithObject(aSelector: string, object: any): any;
39 |
40 | performSelectorWithObjectWithObject(aSelector: string, object1: any, object2: any): any;
41 |
42 | respondsToSelector(aSelector: string): boolean;
43 |
44 | retainCount(): number;
45 |
46 | self(): this;
47 |
48 | userContentControllerDidReceiveScriptMessage(userContentController: WKUserContentController, message: WKScriptMessage): void;
49 | }
50 |
51 | declare var WKWebViewRTCVersionNumber: number;
52 |
53 | declare var WKWebViewRTCVersionString: interop.Reference;
54 |
--------------------------------------------------------------------------------
/src/webview/angular/index.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { NativeScriptCommonModule, isKnownView, registerElement } from '@nativescript/angular';
3 | import { AWebView } from '@nativescript-community/ui-webview';
4 |
5 | const webviewElementName = 'AWebView';
6 |
7 | if (!isKnownView(webviewElementName)) {
8 | registerElement(webviewElementName, () => AWebView);
9 | }
10 |
11 | @NgModule({
12 | imports: [NativeScriptCommonModule]
13 | })
14 | export class AWebViewModule {}
15 |
--------------------------------------------------------------------------------
/src/webview/angular/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "dest": "../../../packages/webview/angular",
3 | "lib": {
4 | "entryFile": "index.ts"
5 | },
6 | "allowedNonPeerDependencies": [
7 | "."
8 | ]
9 | }
--------------------------------------------------------------------------------
/src/webview/angular/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@nativescript-community/ui-webview-angular",
3 | "main": "index.js"
4 | }
--------------------------------------------------------------------------------
/src/webview/angular/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../../tsconfig.json",
3 | "compilerOptions": {
4 | "rootDir": "./",
5 | "plugins": [],
6 | "paths": {
7 | "@nativescript-community/ui-webview": ["packages/webview"],
8 | "@nativescript-community/ui-webview/*": ["packages/webview/*"]
9 | }
10 | },
11 | "include": ["./**/*.ts", "../../../references.d.ts", "../references.d.ts"],
12 | "exclude": ["../node_modules"]
13 | }
14 |
--------------------------------------------------------------------------------
/src/webview/index.d.ts:
--------------------------------------------------------------------------------
1 | import { WebViewExtBase } from './index.common';
2 | export * from './index.common';
3 | /**
4 | * Represents a standard WebView widget.
5 | */
6 | export class AWebView extends WebViewExtBase {}
7 |
--------------------------------------------------------------------------------
/src/webview/nativescript-webview-bridge-loader.android.ts:
--------------------------------------------------------------------------------
1 |
2 | export const webViewBridge: string = "class e{constructor(){this.t={}}onNativeEvent(e,t){const n=this.t[e];if(null==n?void 0:n.length)for(const e of n)if(!1===(null==e?void 0:e(t)))break}on(e,t){if(!t)return;let n=this.t[e];n||(n=this.t[e]=[]),n.push(t)}addEventListener(e,t){this.on(e,t)}off(e,t){if(!e)return void(this.t={});let n=this.t[e];n&&(t?(n=this.t[e]=n.filter((e=>e!==t)),0===n.length&&delete this.t[e]):delete this.t[e])}removeEventListener(e,t){return this.off(e,t)}emit(e,t){this.emitEvent(e,JSON.stringify(t))}async injectJavaScriptFile(e){const t=this.elementIdFromHref(e);if(!document.getElementById(t))return new Promise(((n,i)=>{const r=document.createElement(\"script\");r.async=!0,r.setAttribute(\"id\",t),r.addEventListener(\"error\",(e=>{i(this.serializeError(e)),r.parentElement&&r.parentElement.removeChild(r)})),r.addEventListener(\"load\",(function(){window.requestAnimationFrame((()=>{n()})),r.parentElement&&r.parentElement.removeChild(r)})),r.src=e,document.body.appendChild(r)}))}async injectJavaScript(e,t){if(!document.getElementById(e))return new Promise(((n,i)=>{const r=document.createElement(\"script\");r.setAttribute(\"id\",e),r.addEventListener(\"error\",(function(e){i(e),r.parentElement&&r.parentElement.removeChild(r)})),r.text=t,document.body.appendChild(r),window.requestAnimationFrame((()=>n()))}))}async injectStyleSheetFile(e,t){const n=this.elementIdFromHref(e);if(!document.getElementById(n))return new Promise(((i,r)=>{const o=document.createElement(\"link\");o.addEventListener(\"error\",(e=>{r(e),o.parentElement&&o.parentElement.removeChild(o)})),o.addEventListener(\"load\",(()=>{window.requestAnimationFrame((()=>{i()}))})),o.setAttribute(\"id\",n),o.setAttribute(\"rel\",\"stylesheet\"),o.setAttribute(\"type\",\"text/css\"),o.setAttribute(\"href\",e),document.head&&(t&&document.head.childElementCount>0?document.head.insertBefore(o,document.head.firstElementChild):document.head.appendChild(o))}))}async injectStyleSheet(e,t,n){if(!document.getElementById(e))return new Promise(((i,r)=>{var o;const s=document.createElement(\"style\");s.addEventListener(\"error\",r),s.textContent=t,s.setAttribute(\"id\",e);const d=null!==(o=document.head)&&void 0!==o?o:document.body;d?(n&&d.childElementCount>0?document.head.insertBefore(s,d.firstElementChild):document.head.appendChild(s),i()):r(new Error(\"Couldn't find parent element\"))}))}async executePromise(e,t){try{const n=await e;this.emit(t,{data:n})}catch(e){this.emitError(e,t)}}emitError(e,t=\"web-error\"){\"object\"==typeof e&&(null==e?void 0:e.message)?this.emit(t,{err:this.serializeError(e)}):this.emit(t,{err:e})}elementIdFromHref(e){return e.replace(/^[:]*:\\/\\//,\"\").replace(/[^a-z0-9]/g,\"\")}serializeError(e){const{name:t,message:n,stack:i,...r}=e;return Object.keys(r).reduce(((e,t)=>{const n=r[t];return n instanceof HTMLElement||(e[t]=n),e}),{name:t,message:n,stack:i})}}class t extends e{get androidWebViewBridge(){if(\"undefined\"!=typeof androidWebViewBridge)return androidWebViewBridge}emitEvent(e,t){this.androidWebViewBridge.emitEvent(e,t)}}const n=\"ns-bridge-ready\",i=window;if(!i.nsWebViewBridge){i.nsWebViewBridge=new t;for(const e of[n,\"ns-brige-ready\"])\"undefined\"!=typeof CustomEvent?window.dispatchEvent(new CustomEvent(e,{detail:i.nsWebViewBridge})):window.dispatchEvent(new Event(e))}";
3 | export const metadataViewPort: string = "!function(e){const i={initialScale:1},a=e.document;let t=a.querySelector('head meta[name=\"viewport\"]');t||(t=a.createElement(\"meta\"),t.setAttribute(\"name\",\"viewport\"),a.head.appendChild(t));let l=\"<%= VIEW_PORT %>\";l&&\"string\"!=typeof l||(l=i);const{initialScale:n=i.initialScale,width:s,height:c,userScalable:m,minimumScale:o,maximumScale:u}=l,r=[`initial-scale=${n}`];if(s&&r.push(`width=${s}`),c&&r.push(`height=${c}`),\"boolean\"==typeof m)r.push(\"user-scalable=\"+(m?\"yes\":\"no\"));else if(\"string\"==typeof m){const e=`${m}`.toLowerCase();\"yes\"===e?r.push(\"user-scalable=yes\"):\"no\"===e&&r.push(\"user-scalable=no\")}o&&r.push(`minimum-scale=${o}`),u&&r.push(`maximum-scale=${u}`),t.setAttribute(\"content\",r.join(\", \"))}(window);";
4 |
--------------------------------------------------------------------------------
/src/webview/nativescript-webview-bridge-loader.d.ts:
--------------------------------------------------------------------------------
1 | export const webViewBridge: string;
2 | export const metadataViewPort: string;
3 | export const promisePolyfill: string;
4 |
--------------------------------------------------------------------------------
/src/webview/nativescript-webview-bridge-loader.ios.ts:
--------------------------------------------------------------------------------
1 |
2 | export const webViewBridge: string = "class e{constructor(){this.t={}}onNativeEvent(e,t){const n=this.t[e];if(null==n?void 0:n.length)for(const e of n)if(!1===(null==e?void 0:e(t)))break}on(e,t){if(!t)return;let n=this.t[e];n||(n=this.t[e]=[]),n.push(t)}addEventListener(e,t){this.on(e,t)}off(e,t){if(!e)return void(this.t={});let n=this.t[e];n&&(t?(n=this.t[e]=n.filter((e=>e!==t)),0===n.length&&delete this.t[e]):delete this.t[e])}removeEventListener(e,t){return this.off(e,t)}emit(e,t){this.emitEvent(e,JSON.stringify(t))}async injectJavaScriptFile(e){const t=this.elementIdFromHref(e);if(!document.getElementById(t))return new Promise(((n,o)=>{const i=document.createElement(\"script\");i.async=!0,i.setAttribute(\"id\",t),i.addEventListener(\"error\",(e=>{o(this.serializeError(e)),i.parentElement&&i.parentElement.removeChild(i)})),i.addEventListener(\"load\",(function(){window.requestAnimationFrame((()=>{n()})),i.parentElement&&i.parentElement.removeChild(i)})),i.src=e,document.body.appendChild(i)}))}async injectJavaScript(e,t){if(!document.getElementById(e))return new Promise(((n,o)=>{const i=document.createElement(\"script\");i.setAttribute(\"id\",e),i.addEventListener(\"error\",(function(e){o(e),i.parentElement&&i.parentElement.removeChild(i)})),i.text=t,document.body.appendChild(i),window.requestAnimationFrame((()=>n()))}))}async injectStyleSheetFile(e,t){const n=this.elementIdFromHref(e);if(!document.getElementById(n))return new Promise(((o,i)=>{const r=document.createElement(\"link\");r.addEventListener(\"error\",(e=>{i(e),r.parentElement&&r.parentElement.removeChild(r)})),r.addEventListener(\"load\",(()=>{window.requestAnimationFrame((()=>{o()}))})),r.setAttribute(\"id\",n),r.setAttribute(\"rel\",\"stylesheet\"),r.setAttribute(\"type\",\"text/css\"),r.setAttribute(\"href\",e),document.head&&(t&&document.head.childElementCount>0?document.head.insertBefore(r,document.head.firstElementChild):document.head.appendChild(r))}))}async injectStyleSheet(e,t,n){if(!document.getElementById(e))return new Promise(((o,i)=>{var r;const s=document.createElement(\"style\");s.addEventListener(\"error\",i),s.textContent=t,s.setAttribute(\"id\",e);const c=null!==(r=document.head)&&void 0!==r?r:document.body;c?(n&&c.childElementCount>0?document.head.insertBefore(s,c.firstElementChild):document.head.appendChild(s),o()):i(new Error(\"Couldn't find parent element\"))}))}async executePromise(e,t){try{const n=await e;this.emit(t,{data:n})}catch(e){this.emitError(e,t)}}emitError(e,t=\"web-error\"){\"object\"==typeof e&&(null==e?void 0:e.message)?this.emit(t,{err:this.serializeError(e)}):this.emit(t,{err:e})}elementIdFromHref(e){return e.replace(/^[:]*:\\/\\//,\"\").replace(/[^a-z0-9]/g,\"\")}serializeError(e){const{name:t,message:n,stack:o,...i}=e;return Object.keys(i).reduce(((e,t)=>{const n=i[t];return n instanceof HTMLElement||(e[t]=n),e}),{name:t,message:n,stack:o})}}function t(){var e,t;const n=window;if(null===(t=null===(e=null==n?void 0:n.webkit)||void 0===e?void 0:e.messageHandlers)||void 0===t?void 0:t.nsBridge)return n.webkit.messageHandlers.nsBridge}class n extends e{emitEvent(e,n){const o=t();o&&o.postMessage(JSON.stringify({eventName:e,data:n}))}}const o=\"ns-bridge-ready\",i=window;if(!i.nsWebViewBridge){i.nsWebViewBridge=new n;for(const e of[o,\"ns-brige-ready\"])\"undefined\"!=typeof CustomEvent?window.dispatchEvent(new CustomEvent(e,{detail:i.nsWebViewBridge})):window.dispatchEvent(new Event(e))}";
3 | export const metadataViewPort: string = "!function(e){const i={initialScale:1},a=e.document;let t=a.querySelector('head meta[name=\"viewport\"]');t||(t=a.createElement(\"meta\"),t.setAttribute(\"name\",\"viewport\"),a.head.appendChild(t));let l=\"<%= VIEW_PORT %>\";l&&\"string\"!=typeof l||(l=i);const{initialScale:n=i.initialScale,width:s,height:c,userScalable:m,minimumScale:o,maximumScale:u}=l,r=[`initial-scale=${n}`];if(s&&r.push(`width=${s}`),c&&r.push(`height=${c}`),\"boolean\"==typeof m)r.push(\"user-scalable=\"+(m?\"yes\":\"no\"));else if(\"string\"==typeof m){const e=`${m}`.toLowerCase();\"yes\"===e?r.push(\"user-scalable=yes\"):\"no\"===e&&r.push(\"user-scalable=no\")}o&&r.push(`minimum-scale=${o}`),u&&r.push(`maximum-scale=${u}`),t.setAttribute(\"content\",r.join(\", \"))}(window);";
4 |
--------------------------------------------------------------------------------
/src/webview/references.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 | ///
4 | ///
5 |
--------------------------------------------------------------------------------
/src/webview/types/android/webviewinterface.d.ts:
--------------------------------------------------------------------------------
1 | declare namespace com {
2 | export namespace nativescript {
3 | export namespace webviewinterface {
4 | export class WebViewBridgeInterface {
5 | public emitEvent(param0: string, param1: string): void;
6 | public emitEventToNativeScript(param0: string, param1: string): void;
7 | public constructor();
8 | }
9 | export class WebChromeClient extends globalAndroid.webkit.WebChromeClient {
10 | public setConsoleEnabled(value: boolean);
11 | public isConsoleEnabled(): boolean;
12 | public handleConsoleMessage(message: android.webkit.ConsoleMessage): boolean;
13 | }
14 | export class WebView extends globalAndroid.webkit.WebView {
15 | public setScrollEnabled(value: boolean);
16 | public getScrollEnabled(): boolean;
17 | }
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/webview/types/ios/ios.d.ts:
--------------------------------------------------------------------------------
1 | declare class CustomUrlSchemeHandler extends NSObject {
2 | static alloc(): CustomUrlSchemeHandler; // inherited from NSObject
3 |
4 | static new(): CustomUrlSchemeHandler; // inherited from NSObject
5 |
6 | checkTcpPortForListenWithPort(port: number): boolean;
7 |
8 | clearRegisteredLocalResource(): void;
9 |
10 | getRegisteredLocalResourceForKey(forKey: string): string;
11 |
12 | registerLocalResourceForKeyFilepath(forKey: string, filepath: string): void;
13 |
14 | resolveFilePath(url: NSURL): string;
15 |
16 | resolveMimeTypeFromFilepath(filepath: string): string;
17 |
18 | unregisterLocalResourceForKey(forKey: string): void;
19 |
20 | webViewStartURLSchemeTask(webView: WKWebView, urlSchemeTask: WKURLSchemeTask): void;
21 |
22 | webViewStopURLSchemeTask(webView: WKWebView, urlSchemeTask: WKURLSchemeTask): void;
23 | }
24 |
--------------------------------------------------------------------------------
/src/webview/types/url.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'url' {
2 | export interface ParsedUrlQuery {
3 | [key: string]: string | string[];
4 | }
5 |
6 | export class Url {
7 | protocol?: string | null;
8 | slashes?: boolean | null;
9 | auth?: string | null;
10 | host?: string | null;
11 | port?: string | null;
12 | hostname?: string | null;
13 | hash?: string | null;
14 | search?: string | null;
15 | query?: string | null | ParsedUrlQuery;
16 | pathname?: string | null;
17 | path?: string | null;
18 | href?: string | null;
19 | public format(): string;
20 | public resolve(relative: Url): string;
21 | public resolveObject(source: string, relative: string): Url;
22 | }
23 |
24 | export function parse(input: string): Url;
25 | export function format(url: Url): string;
26 | export function resolve(source: Url, relative: Url): string;
27 | export function resolveObject(source: string, relative: string): Url;
28 | }
29 |
--------------------------------------------------------------------------------
/src/webview/vue/index.ts:
--------------------------------------------------------------------------------
1 | const Plugin = {
2 | install(Vue) {
3 | Vue.registerElement('AWebView', () => require('../').AWebView);
4 | }
5 | };
6 |
7 | export default Plugin;
8 |
--------------------------------------------------------------------------------
/svelte.config.js:
--------------------------------------------------------------------------------
1 | const sveltePreprocess = require('svelte-preprocess');
2 | // const svelteNativePreprocessor = require('svelte-native-preprocessor');
3 |
4 | module.exports = {
5 | compilerOptions: {
6 | namespace: 'foreign'
7 | },
8 | preprocess: [
9 | sveltePreprocess({
10 | typescript: {
11 | compilerOptions: {
12 | target: 'es2020'
13 | }
14 | }
15 | })
16 | // svelteNativePreprocessor()
17 | ]
18 | };
19 |
--------------------------------------------------------------------------------
/tsconfig.eslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "include": ["**/*", ".eslintrc.js", "app.webpack.config.js"]
4 | }
5 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tools/tsconfig",
3 | "compilerOptions": {
4 | "paths": {
5 | "@nativescript-community/ui-webview": ["src/ui-webview"],
6 | "@nativescript-community/ui-webview/*": ["src/ui-webview/*"],
7 | "@nativescript-community/ui-webview-rtc": ["src/ui-webview-rtc"],
8 | "@nativescript-community/ui-webview-rtc/*": ["src/ui-webview-rtc/*"]
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/tsconfig.vue3.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "composite": true,
5 | "paths": {
6 | "nativescript-vue": ["./node_modules/nativescript-vue3"]
7 | }
8 | },
9 | "include": [
10 | "./demo-snippets/vue3"
11 | ]
12 | }
--------------------------------------------------------------------------------
/www-src/bridge-loader.android.ts.tmpl:
--------------------------------------------------------------------------------
1 |
2 | export const webViewBridge: string = = webViewBridge ?>;
3 | export const metadataViewPort: string = = metadataViewPort ?>;
4 |
--------------------------------------------------------------------------------
/www-src/bridge-loader.ios.ts.tmpl:
--------------------------------------------------------------------------------
1 |
2 | export const webViewBridge: string = = webViewBridge ?>;
3 | export const metadataViewPort: string = = metadataViewPort ?>;
4 |
--------------------------------------------------------------------------------
/www-src/bridge.android.ts:
--------------------------------------------------------------------------------
1 | import { NSWebViewBridgeBase } from './bridge.common';
2 |
3 | declare const androidWebViewBridge: {
4 | emitEvent(eventName: string, data: string): void;
5 | };
6 |
7 | // Forked from nativescript-webview-interface@1.4.2
8 | class NSWebViewBridge extends NSWebViewBridgeBase {
9 | private get androidWebViewBridge() {
10 | if (typeof androidWebViewBridge !== 'undefined') {
11 | return androidWebViewBridge;
12 | }
13 | }
14 | /**
15 | * Calls native android function to emit event and payload to android
16 | */
17 | protected emitEvent(eventName: any, data: any) {
18 | this.androidWebViewBridge.emitEvent(eventName, data);
19 | }
20 | }
21 |
22 | const nsBridgeReadyEventName = 'ns-bridge-ready';
23 |
24 | const w = window as any;
25 | if (!w.nsWebViewBridge) {
26 | // Only create the NSWebViewBridge, if is doesn't already exist.
27 | w.nsWebViewBridge = new NSWebViewBridge();
28 |
29 | for (const eventName of [nsBridgeReadyEventName, 'ns-brige-ready']) {
30 | if (typeof CustomEvent !== 'undefined') {
31 | window.dispatchEvent(
32 | new CustomEvent(eventName, {
33 | detail: w.nsWebViewBridge
34 | })
35 | );
36 | } else {
37 | window.dispatchEvent(new Event(eventName));
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/www-src/bridge.ios.ts:
--------------------------------------------------------------------------------
1 | import { NSWebViewBridgeBase } from './bridge.common';
2 |
3 | interface WKWebViewMessageHandler {
4 | postMessage(message: string): void;
5 | }
6 | // if (!Object.keys) {
7 | // Object.keys = (function () {
8 | // 'use strict';
9 | // const hasOwnProperty = Object.prototype.hasOwnProperty;
10 | // const hasDontEnumBug = !{ toString: null }.propertyIsEnumerable('toString');
11 | // const dontEnums = [
12 | // 'toString',
13 | // 'toLocaleString',
14 | // 'valueOf',
15 | // 'hasOwnProperty',
16 | // 'isPrototypeOf',
17 | // 'propertyIsEnumerable',
18 | // 'constructor',
19 | // ];
20 | // const dontEnumsLength = dontEnums.length;
21 |
22 | // return function (obj: any) {
23 | // if (typeof obj !== 'function' && (typeof obj !== 'object' || obj === null)) {
24 | // throw new TypeError('Object.keys called on non-object');
25 | // }
26 |
27 | // const result = new Array();
28 |
29 | // for (const prop in obj) {
30 | // if (hasOwnProperty.call(obj, prop)) {
31 | // result.push(prop);
32 | // }
33 | // }
34 |
35 | // if (hasDontEnumBug) {
36 | // for (let i = 0; i < dontEnumsLength; i++) {
37 | // if (hasOwnProperty.call(obj, dontEnums[i])) {
38 | // result.push(dontEnums[i]);
39 | // }
40 | // }
41 | // }
42 |
43 | // return result;
44 | // };
45 | // })();
46 | // }
47 |
48 | /**
49 | * With WKWebView it's assumed the there is a WKScriptMessage named nsBridge
50 | */
51 | function getWkWebViewMessageHandler(): WKWebViewMessageHandler | void {
52 | const w = window as any;
53 | if (!w?.webkit?.messageHandlers?.nsBridge) {
54 | console.error("Cannot get the window.webkit.messageHandlers.nsBridge - we can't communicate with native-layer");
55 |
56 | return;
57 | }
58 |
59 | return w.webkit.messageHandlers.nsBridge;
60 | }
61 |
62 | // Forked from nativescript-webview-interface@1.4.2
63 | class NSWebViewBridge extends NSWebViewBridgeBase {
64 | protected emitEvent(eventName: string, data: any) {
65 | const messageHandler = getWkWebViewMessageHandler();
66 | if (messageHandler) {
67 | messageHandler.postMessage(
68 | JSON.stringify({
69 | eventName,
70 | data,
71 | })
72 | );
73 |
74 | return;
75 | }
76 |
77 | console.error('NSWebViewBridge only supports WKWebView');
78 | }
79 | }
80 |
81 | const nsBridgeReadyEventName = 'ns-bridge-ready';
82 |
83 | const w = window as any;
84 | if (!w.nsWebViewBridge) {
85 | // Only create the NSWebViewBridge, if is doesn't already exist.
86 | w.nsWebViewBridge = new NSWebViewBridge();
87 |
88 | for (const eventName of [nsBridgeReadyEventName, 'ns-brige-ready']) {
89 | if (typeof CustomEvent !== 'undefined') {
90 | window.dispatchEvent(
91 | new CustomEvent(eventName, {
92 | detail: w.nsWebViewBridge,
93 | })
94 | );
95 | } else {
96 | window.dispatchEvent(new Event(eventName));
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/www-src/metadata-view-port.ts:
--------------------------------------------------------------------------------
1 | interface ViewPortProperties {
2 | width?: number | 'device-width';
3 | height?: number | 'device-height';
4 | initialScale?: number;
5 | maximumScale?: number;
6 | minimumScale?: number;
7 | userScalable?: boolean | 'yes' | 'no';
8 | }
9 |
10 | (function (window) {
11 | const defaultViewPort: ViewPortProperties = {
12 | initialScale: 1.0,
13 | };
14 |
15 | const document = window.document;
16 | let meta: HTMLMetaElement | null = document.querySelector('head meta[name="viewport"]');
17 | if (!meta) {
18 | meta = document.createElement('meta');
19 | meta.setAttribute('name', 'viewport');
20 |
21 | document.head.appendChild(meta);
22 | }
23 |
24 | let viewPortValues: any = '<%= VIEW_PORT %>';
25 | if (!viewPortValues || typeof viewPortValues === 'string') {
26 | viewPortValues = defaultViewPort;
27 | }
28 |
29 | const {
30 | initialScale = defaultViewPort.initialScale,
31 | width,
32 | height,
33 | userScalable,
34 | minimumScale,
35 | maximumScale,
36 | } = viewPortValues;
37 |
38 | const content = [`initial-scale=${initialScale}`] as string[];
39 |
40 | if (width) {
41 | content.push(`width=${width}`);
42 | }
43 |
44 | if (height) {
45 | content.push(`height=${height}`);
46 | }
47 |
48 | if (typeof userScalable === 'boolean') {
49 | content.push(`user-scalable=${userScalable ? 'yes' : 'no'}`);
50 | } else if (typeof userScalable === 'string') {
51 | const lcUserScalable = `${userScalable}`.toLowerCase();
52 | if (lcUserScalable === 'yes') {
53 | content.push('user-scalable=yes');
54 | } else if (lcUserScalable === 'no') {
55 | content.push('user-scalable=no');
56 | } else {
57 | console.error(`userScalable=${JSON.stringify(userScalable)} is an unknown value`);
58 | }
59 | }
60 |
61 | if (minimumScale) {
62 | content.push(`minimum-scale=${minimumScale}`);
63 | }
64 |
65 | if (maximumScale) {
66 | content.push(`maximum-scale=${maximumScale}`);
67 | }
68 |
69 | meta.setAttribute('content', content.join(', '));
70 | })(window);
71 |
--------------------------------------------------------------------------------
/www-src/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "www-src",
3 | "dependencies": {
4 | "@rollup/plugin-commonjs": "^21.0.1",
5 | "@rollup/plugin-strip": "^2.1.0",
6 | "@rollup/plugin-typescript": "^8.3.0",
7 | "promise-polyfill": "^8.2.1",
8 | "rollup": "^2.62.0",
9 | "rollup-plugin-cleanup": "^3.2.1"
10 | }
11 | }
--------------------------------------------------------------------------------
/www-src/rollup.config.mjs:
--------------------------------------------------------------------------------
1 | import strip from '@rollup/plugin-strip';
2 | import typescript from '@rollup/plugin-typescript';
3 | import commonjs from '@rollup/plugin-commonjs';
4 | import cleanup from 'rollup-plugin-cleanup';
5 |
6 | export default [
7 | {
8 | input: 'bridge.android.ts',
9 | plugins: [typescript(), cleanup({ comments: 'none' }), strip({ functions: ['assert.*', 'debug', 'alert'] })],
10 |
11 | output: [
12 | {
13 | format: 'es',
14 | file: '../build/bridge.android.js',
15 | // plugins: [terser()]
16 | }
17 | ]
18 | },
19 | {
20 | input: 'bridge.ios.ts',
21 | plugins: [commonjs({ transformMixedEsModules: true }), typescript(), cleanup({ comments: 'none' }), strip({ functions: ['assert.*', 'debug', 'alert'] })],
22 |
23 | output: [
24 | {
25 | format: 'cjs',
26 | esModule: false,
27 | strict: false,
28 | file: '../build/bridge.ios.js'
29 | // plugins: [terser()]
30 | }
31 | ]
32 | },
33 | {
34 | input: 'metadata-view-port.ts',
35 | plugins: [commonjs({ transformMixedEsModules: true }), typescript(), strip({ functions: ['assert.*', 'debug', 'alert'] })],
36 |
37 | output: [
38 | {
39 | format: 'cjs',
40 | esModule: false,
41 | strict: false,
42 | file: '../build/metadata-view-port.js'
43 | // plugins: [terser()]
44 | }
45 | ]
46 | }
47 | ];
48 |
--------------------------------------------------------------------------------
/www-src/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "ESNext",
4 | "moduleResolution": "node",
5 | "lib": ["es5", "es6", "dom"], "target": "es2019",
6 | "sourceMap": false,
7 | "removeComments": true,
8 | "noEmitHelpers": false,
9 | "importHelpers": false,
10 | "baseUrl": ".",
11 | "esModuleInterop": true,
12 | "skipLibCheck": true,
13 | "outDir": "../build"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------