mirror of
https://github.com/apache/cordova-android.git
synced 2026-07-25 00:00:05 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6131c41399 |
@@ -39,21 +39,8 @@ github:
|
||||
merge: false
|
||||
rebase: false
|
||||
|
||||
rulesets:
|
||||
- name: "Default Branch Protection"
|
||||
type: branch
|
||||
branches:
|
||||
includes:
|
||||
- "~DEFAULT_BRANCH"
|
||||
- "release/*"
|
||||
- "rel/*"
|
||||
excludes: []
|
||||
bypass_teams:
|
||||
- root
|
||||
restrict_deletion: true
|
||||
restrict_force_push: true
|
||||
notifications:
|
||||
commits: commits@cordova.apache.org
|
||||
issues: issues@cordova.apache.org
|
||||
pullrequests_status: issues@cordova.apache.org
|
||||
commits: commits@cordova.apache.org
|
||||
issues: issues@cordova.apache.org
|
||||
pullrequests_status: issues@cordova.apache.org
|
||||
pullrequests_comment: issues@cordova.apache.org
|
||||
|
||||
@@ -5,11 +5,6 @@ http://cordova.apache.org/contribute/contribute_guidelines.html
|
||||
|
||||
Thanks!
|
||||
-->
|
||||
|
||||
### Platforms affected
|
||||
|
||||
|
||||
|
||||
### Motivation and Context
|
||||
<!-- Why is this change required? What problem does it solve? -->
|
||||
<!-- If it fixes an open issue, please link to the issue here. -->
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
cooldown:
|
||||
default-days: 4
|
||||
schedule:
|
||||
interval: "daily" # Every weekday, Monday to Friday
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/"
|
||||
cooldown:
|
||||
default-days: 4
|
||||
schedule:
|
||||
interval: "weekly" # By default on a Monday
|
||||
@@ -41,15 +41,12 @@ jobs:
|
||||
os: [ubuntu-latest, windows-latest, macos-15]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 1
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
@@ -64,7 +61,7 @@ jobs:
|
||||
# It contains mixed content from the npm package "cordova-js" and "./cordova-js-src".
|
||||
# The report might not be resolvable because of the external package.
|
||||
# If the report is related to this repository, it would be detected when scanning "./cordova-js-src".
|
||||
- uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
|
||||
- uses: github/codeql-action/init@v4
|
||||
with:
|
||||
languages: javascript, java-kotlin
|
||||
queries: security-and-quality
|
||||
@@ -77,11 +74,12 @@ jobs:
|
||||
|
||||
- name: npm install and test
|
||||
run: |
|
||||
npm cit
|
||||
npm i
|
||||
npm t
|
||||
env:
|
||||
CI: true
|
||||
|
||||
- uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
|
||||
- uses: github/codeql-action/analyze@v4
|
||||
|
||||
# v4.6.0
|
||||
- uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238
|
||||
|
||||
@@ -31,15 +31,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 1
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
package-manager-cache: false
|
||||
cache: ''
|
||||
|
||||
- name: Setup environment variables
|
||||
run: |
|
||||
@@ -73,14 +68,14 @@ jobs:
|
||||
- name: Verify Target Release Version
|
||||
run: |
|
||||
PACKAGE_VERSION=$(jq -r '.version' package.json)
|
||||
if [ "$PACKAGE_VERSION" != "$TARGET_RELEASE_VERSION" ]; then
|
||||
if [ $PACKAGE_VERSION != "$TARGET_RELEASE_VERSION" ]; then
|
||||
echo "Mismatch version detected between tag version ($TARGET_RELEASE_VERSION) and package version ($PACKAGE_VERSION)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f "plugin.xml" ]; then
|
||||
PLUGIN_VERSION=$(yq -p=xml -o=json '.plugin.+@version' plugin.xml | jq -r .)
|
||||
if [ "$PLUGIN_VERSION" != "$TARGET_RELEASE_VERSION" ]; then
|
||||
PLUGIN_VERSION=$(yq -p=xml -o=json '.plugin.+@version' plugin.xml)
|
||||
if [ $PLUGIN_VERSION != "$TARGET_RELEASE_VERSION" ]; then
|
||||
echo "Mismatch version detected between tag version ($TARGET_RELEASE_VERSION) and plugin version ($PLUGIN_VERSION)"
|
||||
exit 1
|
||||
fi
|
||||
@@ -88,7 +83,7 @@ jobs:
|
||||
|
||||
- name: Generate "tgz" npm convenience package
|
||||
run: |-
|
||||
npm ci
|
||||
npm install
|
||||
NPM_PKG_NAME=$(npm pack --json | jq -r '.[0].filename')
|
||||
mv ./.asf-release/$NPM_PKG_NAME ./.asf-release/${NPM_PACKAGE_NAME}.tgz
|
||||
env:
|
||||
@@ -147,7 +142,7 @@ jobs:
|
||||
CORDOVA_GPG_SECRET_KEY: ${{ secrets.CORDOVA_GPG_SECRET_KEY }}
|
||||
|
||||
- name: Upload to Apache Trusted Release (ATR)
|
||||
uses: apache/tooling-actions/upload-to-atr@f5f4c0e7ddfbde6b1f8288cef36324c6def68051
|
||||
uses: apache/tooling-actions/upload-to-atr@b7e972c11790ee16eca101900af1b3c7fd1b106e
|
||||
with:
|
||||
project: ${{ env.REPO_NAME }}
|
||||
version: ${{ env.TARGET_RELEASE_VERSION }}
|
||||
|
||||
@@ -34,16 +34,13 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Checkout project
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 1
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
# Check license headers (v3.0.0)
|
||||
- uses: erisu/apache-rat-action@30c94d10ed21e6f6fd5590dc5c158f58cae7a0dd
|
||||
# Check license headers (v2.0.0)
|
||||
- uses: erisu/apache-rat-action@46fb01ce7d8f76bdcd7ab10e7af46e1ea95ca01c
|
||||
|
||||
# Setup environment with node
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
|
||||
@@ -51,8 +48,8 @@ jobs:
|
||||
- name: npm install packages
|
||||
run: npm ci
|
||||
|
||||
# Check node package licenses (v2.1.0)
|
||||
- uses: erisu/license-checker-action@04511f4c052b5773f11e1c65b42cda88235c62ae
|
||||
# Check node package licenses (v2.0.1)
|
||||
- uses: erisu/license-checker-action@99cffa11264fe545fd0baa6c13bca5a00ae608f2
|
||||
with:
|
||||
license-config: 'licence_checker.yml'
|
||||
include-asf-category-a: true
|
||||
|
||||
+16
-17
@@ -60,29 +60,28 @@ Object.defineProperty(statusBar, 'setBackgroundColor', {
|
||||
statusBarScript.style.color = value;
|
||||
var rgbStr = window.getComputedStyle(statusBarScript).getPropertyValue('color');
|
||||
|
||||
if (!rgbStr.match(/^rgb/)) {
|
||||
return;
|
||||
}
|
||||
if (!rgbStr.match(/^rgb/)) { return; }
|
||||
|
||||
var rgbVals = rgbStr.match(/\d+/g).map(function (v) { return parseInt(v, 10); });
|
||||
|
||||
var rgbVals = rgbStr.match(/[\d.]+/g).map(function (v, i) { return (i < 3) ? parseInt(v, 10) : parseFloat(v); });
|
||||
if (rgbVals.length < 3) {
|
||||
return;
|
||||
} else if (rgbVals.length === 3) {
|
||||
rgbVals = [255].concat(rgbVals);
|
||||
}
|
||||
|
||||
// TODO: Use `padStart(2, '0')` once SDK 24 is dropped.
|
||||
const padRgb = (val) => {
|
||||
const hex = val.toString(16);
|
||||
return hex.length === 1 ? '0' + hex : hex;
|
||||
};
|
||||
const a = padRgb(rgbVals[0]);
|
||||
const r = padRgb(rgbVals[1]);
|
||||
const g = padRgb(rgbVals[2]);
|
||||
const b = padRgb(rgbVals[3]);
|
||||
const hexStr = '#' + a + r + g + b;
|
||||
|
||||
if (window.StatusBar) {
|
||||
// try to let the StatusBar plugin handle it
|
||||
// TODO: Use `padStart(2, '0')` once SDK 24 is dropped.
|
||||
const padRgb = (val) => {
|
||||
const hex = val.toString(16);
|
||||
return hex.length === 1 ? '0' + hex : hex;
|
||||
};
|
||||
|
||||
const r = padRgb(rgbVals[0]);
|
||||
const g = padRgb(rgbVals[1]);
|
||||
const b = padRgb(rgbVals[2]);
|
||||
const a = padRgb(255 * (rgbVals[3] !== undefined ? rgbVals[3] : 1.0));
|
||||
|
||||
const hexStr = '#' + a + r + g + b;
|
||||
window.StatusBar.backgroundColorByHexString(hexStr);
|
||||
} else {
|
||||
exec(null, null, 'SystemBarPlugin', 'setStatusBarBackgroundColor', rgbVals);
|
||||
|
||||
@@ -225,22 +225,13 @@ public class CordovaActivity extends AppCompatActivity {
|
||||
|
||||
boolean isStatusBarVisible = statusBarView.getVisibility() != View.GONE;
|
||||
int top = isStatusBarVisible && !canEdgeToEdge && !isFullScreen ? bars.top : 0;
|
||||
int bottom = !canEdgeToEdge && !isFullScreen ? bars.bottom : 0;
|
||||
int left = !canEdgeToEdge && !isFullScreen ? bars.left : 0;
|
||||
int right = !canEdgeToEdge && !isFullScreen ? bars.right : 0;
|
||||
|
||||
Insets imeInsets = insets.getInsets(WindowInsetsCompat.Type.ime());
|
||||
// When in fullscreen mode, we ignore bottom system insets (like the navigation bar)
|
||||
// to allow the WebView to span the entire screen and avoid being pushed up.
|
||||
int bottom = isFullScreen ? 0 : canEdgeToEdge ? imeInsets.bottom : Math.max(bars.bottom, imeInsets.bottom);
|
||||
|
||||
FrameLayout.LayoutParams webViewParams = (FrameLayout.LayoutParams) webView.getLayoutParams();
|
||||
// Only update layout margins if the values have actually changed.
|
||||
// This prevents redundant layout passes and potential infinite layout loops
|
||||
if (webViewParams.leftMargin != left || webViewParams.topMargin != top
|
||||
|| webViewParams.rightMargin != right || webViewParams.bottomMargin != bottom) {
|
||||
webViewParams.setMargins(left, top, right, bottom);
|
||||
webView.setLayoutParams(webViewParams);
|
||||
}
|
||||
webViewParams.setMargins(left, top, right, bottom);
|
||||
webView.setLayoutParams(webViewParams);
|
||||
|
||||
FrameLayout.LayoutParams statusBarParams = new FrameLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
|
||||
@@ -74,10 +74,7 @@ public class CordovaPreferences {
|
||||
name = name.toLowerCase(Locale.ENGLISH);
|
||||
String value = prefs.get(name);
|
||||
if (value != null) {
|
||||
// Some 32-bit hex values (for example, 0x80000000) are valid int bit patterns
|
||||
// but exceed Integer.MAX_VALUE when read as positive numbers. Integer.decode()
|
||||
// rejects such values with NumberFormatException, so decode as long first and
|
||||
// cast to int to preserve the intended 32-bit value.
|
||||
// Use Integer.decode() can't handle it if the highest bit is set.
|
||||
return (int)(long)Long.decode(value);
|
||||
}
|
||||
return defaultValue;
|
||||
|
||||
@@ -39,15 +39,15 @@ import androidx.core.view.WindowInsetsControllerCompat;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class SystemBarPlugin extends CordovaPlugin {
|
||||
static final String PLUGIN_NAME = "SystemBarPlugin";
|
||||
|
||||
static final int INVALID_COLOR = -1;
|
||||
|
||||
// Internal variables
|
||||
private Context context;
|
||||
private Resources resources;
|
||||
private Integer overrideStatusBarBackgroundColor = null;
|
||||
private int overrideStatusBarBackgroundColor = INVALID_COLOR;
|
||||
|
||||
private boolean canEdgeToEdge = false;
|
||||
|
||||
@@ -121,16 +121,20 @@ public class SystemBarPlugin extends CordovaPlugin {
|
||||
* If the supplied ARGB is invalid or fails to parse, it will silently ignore
|
||||
* the change request.
|
||||
*
|
||||
* @param argbVals {R, G, B, A}
|
||||
* @param argbVals {A, R, G, B}
|
||||
*/
|
||||
private void setStatusBarBackgroundColor(JSONArray argbVals) {
|
||||
try {
|
||||
int r = argbVals.getInt(0);
|
||||
int g = argbVals.getInt(1);
|
||||
int b = argbVals.getInt(2);
|
||||
int a = Math.round(255 * (float)argbVals.optDouble(3, 1.0));
|
||||
int a = argbVals.getInt(0);
|
||||
int r = argbVals.getInt(1);
|
||||
int g = argbVals.getInt(2);
|
||||
int b = argbVals.getInt(3);
|
||||
String hexColor = String.format("#%02X%02X%02X%02X", a, r, g, b);
|
||||
|
||||
overrideStatusBarBackgroundColor = Color.argb(a, r, g, b);
|
||||
int parsedColor = parseColorFromString(hexColor);
|
||||
if (parsedColor == INVALID_COLOR) return;
|
||||
|
||||
overrideStatusBarBackgroundColor = parsedColor;
|
||||
updateStatusBar(overrideStatusBarBackgroundColor);
|
||||
} catch (JSONException e) {
|
||||
// Silently skip
|
||||
@@ -141,26 +145,26 @@ public class SystemBarPlugin extends CordovaPlugin {
|
||||
* Attempt to update all system bars (status, navigation and gesture bars) in various points
|
||||
* of the apps life cycle.
|
||||
* For example:
|
||||
* 1. Device configurations between (E.g. between dark and light mode)
|
||||
* 2. User resumes the app
|
||||
* 3. App transitions from SplashScreen Theme to App's Theme
|
||||
* 1. Device configurations between (E.g. between dark and light mode)
|
||||
* 2. User resumes the app
|
||||
* 3. App transitions from SplashScreen Theme to App's Theme
|
||||
*/
|
||||
private void updateSystemBars() {
|
||||
// Update Root View Background Color
|
||||
Integer rootViewBackgroundColor = getPreferenceBackgroundColor();
|
||||
if (rootViewBackgroundColor == null) {
|
||||
int rootViewBackgroundColor = getPreferenceBackgroundColor();
|
||||
if (rootViewBackgroundColor == INVALID_COLOR) {
|
||||
rootViewBackgroundColor = canEdgeToEdge ? Color.TRANSPARENT : getUiModeColor();
|
||||
}
|
||||
updateRootView(rootViewBackgroundColor);
|
||||
|
||||
// Update StatusBar Background Color
|
||||
Integer statusBarBackgroundColor;
|
||||
if (overrideStatusBarBackgroundColor != null) {
|
||||
int statusBarBackgroundColor;
|
||||
if (overrideStatusBarBackgroundColor != INVALID_COLOR) {
|
||||
statusBarBackgroundColor = overrideStatusBarBackgroundColor;
|
||||
} else if (preferences.contains("StatusBarBackgroundColor")) {
|
||||
statusBarBackgroundColor = getPreferenceStatusBarBackgroundColor();
|
||||
} else if (preferences.contains("BackgroundColor")) {
|
||||
statusBarBackgroundColor = rootViewBackgroundColor;
|
||||
} else if(preferences.contains("BackgroundColor")){
|
||||
statusBarBackgroundColor = rootViewBackgroundColor;
|
||||
} else {
|
||||
statusBarBackgroundColor = canEdgeToEdge ? Color.TRANSPARENT : getUiModeColor();
|
||||
}
|
||||
@@ -257,31 +261,34 @@ public class SystemBarPlugin extends CordovaPlugin {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the StatusBarBackgroundColor preference value or {@link #getUiModeColor()} as fallback.
|
||||
* Returns the StatusBarBackgroundColor preference value.
|
||||
* If the value is missing or fails to parse, it will attempt to try to guess the background
|
||||
* color by extracting from the apps R.color.cdv_background_color or determine from the uiModes.
|
||||
* If all fails, the color normally used in light mode is returned.
|
||||
*
|
||||
* @return Integer
|
||||
* @return int
|
||||
*/
|
||||
private Integer getPreferenceStatusBarBackgroundColor() {
|
||||
private int getPreferenceStatusBarBackgroundColor() {
|
||||
String colorString = preferences.getString("StatusBarBackgroundColor", null);
|
||||
return Objects.requireNonNullElse(parseColorFromString(colorString), getUiModeColor());
|
||||
|
||||
int parsedColor = parseColorFromString(colorString);
|
||||
if (parsedColor != INVALID_COLOR) return parsedColor;
|
||||
|
||||
return getUiModeColor(); // fallback
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the BackgroundColor preference value.
|
||||
* If the value is missing or fails to decode, null is returned.
|
||||
* If missing or fails to decode, it will return INVALID_COLOR (-1).
|
||||
*
|
||||
* @return Integer|null
|
||||
* @return int
|
||||
*/
|
||||
private Integer getPreferenceBackgroundColor() {
|
||||
if (!preferences.contains("BackgroundColor")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private int getPreferenceBackgroundColor() {
|
||||
try {
|
||||
return preferences.getInteger("BackgroundColor", 0);
|
||||
return preferences.getInteger("BackgroundColor", INVALID_COLOR);
|
||||
} catch (NumberFormatException e) {
|
||||
LOG.e(PLUGIN_NAME, "Invalid background color argument. Example valid string: '0x00000000'");
|
||||
return null;
|
||||
return INVALID_COLOR;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,20 +354,20 @@ public class SystemBarPlugin extends CordovaPlugin {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a color string provided by app developers.
|
||||
* If the color string is empty or unable to parse, null is returned.
|
||||
* Parse color string that would be provided by app developers.
|
||||
* If the color string is empty or unable to parse, it will return INVALID_COLOR (-1).
|
||||
*
|
||||
* @param colorPref hex string value, #AARRGGBB or #RRGGBB
|
||||
* @return Integer|null
|
||||
* @return int
|
||||
*/
|
||||
private Integer parseColorFromString(final String colorPref) {
|
||||
if (colorPref == null || colorPref.isEmpty()) return null;
|
||||
private int parseColorFromString(final String colorPref) {
|
||||
if (colorPref.isEmpty()) return INVALID_COLOR;
|
||||
|
||||
try {
|
||||
return Color.parseColor(colorPref);
|
||||
} catch (IllegalArgumentException ignore) {
|
||||
LOG.e(PLUGIN_NAME, "Invalid color hex code. Valid format: #RRGGBB or #AARRGGBB");
|
||||
return null;
|
||||
return INVALID_COLOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import android.webkit.JsPromptResult;
|
||||
import android.webkit.JsResult;
|
||||
import android.webkit.ValueCallback;
|
||||
import android.webkit.WebChromeClient;
|
||||
import android.webkit.WebStorage;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.PermissionRequest;
|
||||
import android.widget.LinearLayout;
|
||||
@@ -72,16 +73,22 @@ public class SystemWebChromeClient extends WebChromeClient {
|
||||
private PermissionListener permissionListener;
|
||||
private static final int FILECHOOSER_RESULTCODE = 5173;
|
||||
private static final String LOG_TAG = "SystemWebChromeClient";
|
||||
private long MAX_QUOTA = 100 * 1024 * 1024;
|
||||
protected final SystemWebViewEngine parentEngine;
|
||||
|
||||
// the video progress view
|
||||
private View mVideoProgressView;
|
||||
|
||||
private final CordovaDialogsHelper dialogsHelper;
|
||||
private CordovaDialogsHelper dialogsHelper;
|
||||
private Context appContext;
|
||||
|
||||
private WebChromeClient.CustomViewCallback mCustomViewCallback;
|
||||
private View mCustomView;
|
||||
|
||||
public SystemWebChromeClient(SystemWebViewEngine parentEngine) {
|
||||
this.parentEngine = parentEngine;
|
||||
dialogsHelper = new CordovaDialogsHelper(parentEngine.webView.getContext());
|
||||
appContext = parentEngine.webView.getContext();
|
||||
dialogsHelper = new CordovaDialogsHelper(appContext);
|
||||
permissionLauncher = parentEngine.cordova.getActivity().registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), isGranted -> {
|
||||
if (permissionListener != null) {
|
||||
boolean granted = true;
|
||||
@@ -98,11 +105,13 @@ public class SystemWebChromeClient extends WebChromeClient {
|
||||
*/
|
||||
@Override
|
||||
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
|
||||
dialogsHelper.showAlert(message, (success, value) -> {
|
||||
if (success) {
|
||||
result.confirm();
|
||||
} else {
|
||||
result.cancel();
|
||||
dialogsHelper.showAlert(message, new CordovaDialogsHelper.Result() {
|
||||
@Override public void gotResult(boolean success, String value) {
|
||||
if (success) {
|
||||
result.confirm();
|
||||
} else {
|
||||
result.cancel();
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
@@ -113,11 +122,14 @@ public class SystemWebChromeClient extends WebChromeClient {
|
||||
*/
|
||||
@Override
|
||||
public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
|
||||
dialogsHelper.showConfirm(message, (success, value) -> {
|
||||
if (success) {
|
||||
result.confirm();
|
||||
} else {
|
||||
result.cancel();
|
||||
dialogsHelper.showConfirm(message, new CordovaDialogsHelper.Result() {
|
||||
@Override
|
||||
public void gotResult(boolean success, String value) {
|
||||
if (success) {
|
||||
result.confirm();
|
||||
} else {
|
||||
result.cancel();
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
@@ -138,24 +150,39 @@ public class SystemWebChromeClient extends WebChromeClient {
|
||||
if (handledRet != null) {
|
||||
result.confirm(handledRet);
|
||||
} else {
|
||||
dialogsHelper.showPrompt(message, defaultValue, (success, value) -> {
|
||||
if (success) {
|
||||
result.confirm(value);
|
||||
} else {
|
||||
result.cancel();
|
||||
dialogsHelper.showPrompt(message, defaultValue, new CordovaDialogsHelper.Result() {
|
||||
@Override
|
||||
public void gotResult(boolean success, String value) {
|
||||
if (success) {
|
||||
result.confirm(value);
|
||||
} else {
|
||||
result.cancel();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle database quota exceeded notification.
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize,
|
||||
long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater)
|
||||
{
|
||||
LOG.d(LOG_TAG, "onExceededDatabaseQuota estimatedSize: %d currentQuota: %d totalUsedQuota: %d", estimatedSize, currentQuota, totalUsedQuota);
|
||||
quotaUpdater.updateQuota(MAX_QUOTA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs the client to show a prompt to ask the user to set the Geolocation permission state for the specified origin.
|
||||
*
|
||||
* <p>This also checks for the Geolocation Plugin and requests permission from the application to use Geolocation.</p>
|
||||
*
|
||||
* @param origin The origin of the web content attempting to use the Geolocation API.
|
||||
* @param callback The callback to use to set the permission state for the origin.
|
||||
* @param origin
|
||||
* @param callback
|
||||
*/
|
||||
@Override
|
||||
public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) {
|
||||
@@ -269,7 +296,7 @@ public class SystemWebChromeClient extends WebChromeClient {
|
||||
// Handle result
|
||||
Uri[] result = null;
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
List<Uri> uris = new ArrayList<>();
|
||||
List<Uri> uris = new ArrayList<Uri>();
|
||||
|
||||
if (intent != null && intent.getData() != null) { // single file
|
||||
LOG.v(LOG_TAG, "Adding file (single): " + intent.getData());
|
||||
@@ -290,8 +317,8 @@ public class SystemWebChromeClient extends WebChromeClient {
|
||||
}
|
||||
|
||||
if (!uris.isEmpty()) {
|
||||
LOG.d(LOG_TAG, "Receive file chooser URL: " + uris);
|
||||
result = uris.toArray(new Uri[0]);
|
||||
LOG.d(LOG_TAG, "Receive file chooser URL: " + uris.toString());
|
||||
result = uris.toArray(new Uri[uris.size()]);
|
||||
}
|
||||
}
|
||||
filePathsCallback.onReceiveValue(result);
|
||||
@@ -306,12 +333,14 @@ public class SystemWebChromeClient extends WebChromeClient {
|
||||
|
||||
private File createTempFile(Context context) throws IOException {
|
||||
// Create an image file name
|
||||
return File.createTempFile("temp", ".jpg", context.getCacheDir());
|
||||
File tempFile = File.createTempFile("temp", ".jpg", context.getCacheDir());
|
||||
return tempFile;
|
||||
}
|
||||
|
||||
private Uri createUriForFile(Context context, File tempFile) throws IOException {
|
||||
String appId = context.getPackageName();
|
||||
return FileProvider.getUriForFile(context, appId + ".cdv.core.file.provider", tempFile);
|
||||
Uri uri = FileProvider.getUriForFile(context, appId + ".cdv.core.file.provider", tempFile);
|
||||
return uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.AssetManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.net.http.SslError;
|
||||
import android.webkit.ClientCertRequest;
|
||||
import android.webkit.HttpAuthHandler;
|
||||
@@ -31,7 +32,6 @@ import android.webkit.RenderProcessGoneDetail;
|
||||
import android.webkit.ServiceWorkerClient;
|
||||
import android.webkit.ServiceWorkerController;
|
||||
import android.webkit.SslErrorHandler;
|
||||
import android.webkit.WebResourceError;
|
||||
import android.webkit.WebResourceRequest;
|
||||
import android.webkit.WebResourceResponse;
|
||||
import android.webkit.WebView;
|
||||
@@ -41,9 +41,12 @@ import org.apache.cordova.AuthenticationToken;
|
||||
import org.apache.cordova.CordovaClientCertRequest;
|
||||
import org.apache.cordova.CordovaHttpAuthHandler;
|
||||
import org.apache.cordova.CordovaPluginPathHandler;
|
||||
import org.apache.cordova.CordovaResourceApi;
|
||||
import org.apache.cordova.LOG;
|
||||
import org.apache.cordova.PluginManager;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Hashtable;
|
||||
|
||||
@@ -134,12 +137,13 @@ public class SystemWebViewClient extends WebViewClient {
|
||||
* is about to be loaded in the current WebView.
|
||||
*
|
||||
* @param view The WebView that is initiating the callback.
|
||||
* @param request The request to be loaded.
|
||||
* @param url The url to be loaded.
|
||||
* @return true to override, false for default behavior
|
||||
*/
|
||||
@Override
|
||||
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
|
||||
return parentEngine.client.onNavigationAttempt(request.getUrl().toString());
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
||||
return parentEngine.client.onNavigationAttempt(url);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -243,16 +247,13 @@ public class SystemWebViewClient extends WebViewClient {
|
||||
* The errorCode parameter corresponds to one of the ERROR_* constants.
|
||||
*
|
||||
* @param view The WebView that is initiating the callback.
|
||||
* @param request The request that caused the error.
|
||||
* @param error The error object.
|
||||
* @param errorCode The error code corresponding to an ERROR_* value.
|
||||
* @param description A String describing the error.
|
||||
* @param failingUrl The url that failed to load.
|
||||
*/
|
||||
@Override
|
||||
public void onReceivedError(WebView view,
|
||||
WebResourceRequest request,
|
||||
WebResourceError error) {
|
||||
int errorCode = error.getErrorCode();
|
||||
String description = error.getDescription().toString();
|
||||
String failingUrl = request.getUrl().toString();
|
||||
@SuppressWarnings("deprecation")
|
||||
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
|
||||
// Ignore error due to stopLoading().
|
||||
if (!isCurrentlyLoading) {
|
||||
return;
|
||||
@@ -269,7 +270,7 @@ public class SystemWebViewClient extends WebViewClient {
|
||||
view.goBack();
|
||||
return;
|
||||
} else {
|
||||
super.onReceivedError(view, request, error);
|
||||
super.onReceivedError(view, errorCode, description, failingUrl);
|
||||
}
|
||||
}
|
||||
parentEngine.client.onReceivedError(errorCode, description, failingUrl);
|
||||
@@ -381,6 +382,56 @@ public class SystemWebViewClient extends WebViewClient {
|
||||
this.authenticationTokens.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
|
||||
try {
|
||||
// Check the against the allow list and lock out access to the WebView directory
|
||||
// Changing this will cause problems for your application
|
||||
if (!parentEngine.pluginManager.shouldAllowRequest(url)) {
|
||||
LOG.w(TAG, "URL blocked by allow list: " + url);
|
||||
// Results in a 404.
|
||||
return new WebResourceResponse("text/plain", "UTF-8", null);
|
||||
}
|
||||
|
||||
CordovaResourceApi resourceApi = parentEngine.resourceApi;
|
||||
Uri origUri = Uri.parse(url);
|
||||
// Allow plugins to intercept WebView requests.
|
||||
Uri remappedUri = resourceApi.remapUri(origUri);
|
||||
|
||||
if (!origUri.equals(remappedUri) || needsSpecialsInAssetUrlFix(origUri) || needsContentUrlFix(origUri)) {
|
||||
CordovaResourceApi.OpenForReadResult result = resourceApi.openForRead(remappedUri, true);
|
||||
return new WebResourceResponse(result.mimeType, "UTF-8", result.inputStream);
|
||||
}
|
||||
// If we don't need to special-case the request, let the browser load it.
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
if (!(e instanceof FileNotFoundException)) {
|
||||
LOG.e(TAG, "Error occurred while loading a file (returning a 404).", e);
|
||||
}
|
||||
// Results in a 404.
|
||||
return new WebResourceResponse("text/plain", "UTF-8", null);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean needsContentUrlFix(Uri uri) {
|
||||
return "content".equals(uri.getScheme());
|
||||
}
|
||||
|
||||
private static boolean needsSpecialsInAssetUrlFix(Uri uri) {
|
||||
if (CordovaResourceApi.getUriType(uri) != CordovaResourceApi.URI_TYPE_ASSET) {
|
||||
return false;
|
||||
}
|
||||
if (uri.getQuery() != null || uri.getFragment() != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!uri.toString().contains("%")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
|
||||
|
||||
@@ -20,11 +20,13 @@
|
||||
package org.apache.cordova.engine;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
import android.webkit.ValueCallback;
|
||||
import android.webkit.WebSettings;
|
||||
@@ -42,6 +44,9 @@ import org.apache.cordova.LOG;
|
||||
import org.apache.cordova.NativeToJsMessageQueue;
|
||||
import org.apache.cordova.PluginManager;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
|
||||
/**
|
||||
* Glue class between CordovaWebView (main Cordova logic) and SystemWebView (the actual View).
|
||||
@@ -137,6 +142,7 @@ public class SystemWebViewEngine implements CordovaWebViewEngine {
|
||||
}
|
||||
|
||||
@SuppressLint({"NewApi", "SetJavaScriptEnabled"})
|
||||
@SuppressWarnings("deprecation")
|
||||
private void initWebViewSettings() {
|
||||
webView.setInitialScale(0);
|
||||
webView.setVerticalScrollBarEnabled(false);
|
||||
@@ -186,6 +192,9 @@ public class SystemWebViewEngine implements CordovaWebViewEngine {
|
||||
enableRemoteDebugging();
|
||||
}
|
||||
|
||||
// @todo remove when Cordova drop API level 24 support
|
||||
settings.setGeolocationDatabasePath(databasePath);
|
||||
|
||||
// Enable DOM storage
|
||||
settings.setDomStorageEnabled(true);
|
||||
|
||||
|
||||
Generated
+309
-47
@@ -24,7 +24,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cordova/eslint-config": "^6.0.1",
|
||||
"c8": "^11.0.0",
|
||||
"c8": "^10.1.3",
|
||||
"cordova-js": "^6.1.0",
|
||||
"elementtree": "^0.1.7",
|
||||
"jasmine": "^6.0.0",
|
||||
@@ -272,10 +272,113 @@
|
||||
"url": "https://github.com/sponsors/nzakas"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/cliui": {
|
||||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
||||
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^5.1.2",
|
||||
"string-width-cjs": "npm:string-width@^4.2.0",
|
||||
"strip-ansi": "^7.0.1",
|
||||
"strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
|
||||
"wrap-ansi": "^8.1.0",
|
||||
"wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/ansi-regex": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
|
||||
"integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/ansi-styles": {
|
||||
"version": "6.2.3",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
|
||||
"integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/emoji-regex": {
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
|
||||
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/string-width": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
|
||||
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"eastasianwidth": "^0.2.0",
|
||||
"emoji-regex": "^9.2.2",
|
||||
"strip-ansi": "^7.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/strip-ansi": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
|
||||
"integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^6.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
|
||||
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^6.1.0",
|
||||
"string-width": "^5.0.1",
|
||||
"strip-ansi": "^7.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@istanbuljs/schema": {
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz",
|
||||
"integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==",
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
|
||||
"integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -363,6 +466,17 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/@pkgjs/parseargs": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
||||
"integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@rtsao/scc": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
|
||||
@@ -753,9 +867,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/c8": {
|
||||
"version": "11.0.0",
|
||||
"resolved": "https://registry.npmjs.org/c8/-/c8-11.0.0.tgz",
|
||||
"integrity": "sha512-e/uRViGHSVIJv7zsaDKM7VRn2390TgHXqUSvYwPHBQaU6L7E9L0n9JbdkwdYPvshDT0KymBmmlwSpms3yBaMNg==",
|
||||
"version": "10.1.3",
|
||||
"resolved": "https://registry.npmjs.org/c8/-/c8-10.1.3.tgz",
|
||||
"integrity": "sha512-LvcyrOAaOnrrlMpW22n690PUvxiq4Uf9WMhQwNJ9vgagkL/ph1+D4uvjvDA5XCbykrc0sx+ay6pVi9YZ1GnhyA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
@@ -766,7 +880,7 @@
|
||||
"istanbul-lib-coverage": "^3.2.0",
|
||||
"istanbul-lib-report": "^3.0.1",
|
||||
"istanbul-reports": "^3.1.6",
|
||||
"test-exclude": "^8.0.0",
|
||||
"test-exclude": "^7.0.1",
|
||||
"v8-to-istanbul": "^9.0.0",
|
||||
"yargs": "^17.7.2",
|
||||
"yargs-parser": "^21.1.1"
|
||||
@@ -775,7 +889,7 @@
|
||||
"c8": "bin/c8.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"monocart-coverage-reports": "^2"
|
||||
@@ -1163,6 +1277,13 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/eastasianwidth": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
|
||||
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/elementtree": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/elementtree/-/elementtree-0.1.7.tgz",
|
||||
@@ -2889,25 +3010,41 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/jackspeak": {
|
||||
"version": "3.4.3",
|
||||
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
|
||||
"integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"@isaacs/cliui": "^8.0.2"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@pkgjs/parseargs": "^0.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jasmine": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/jasmine/-/jasmine-6.2.0.tgz",
|
||||
"integrity": "sha512-dvYt7bidcu0JvvSbiUnSDW7UQQiflUwDr6C+5wzoZ0J7RY9u+UcoSIzyhMPj6fnU/tC7KinJ5QrjwD2Y9p4T4w==",
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jasmine/-/jasmine-6.1.0.tgz",
|
||||
"integrity": "sha512-WPphPqEMY0uBRMjuhRHoVoxQNvJuxIMqz0yIcJ3k3oYxBedeGoH60/NXNgasxnx2FvfXrq5/r+2wssJ7WE8ABw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jasminejs/reporters": "^1.0.0",
|
||||
"glob": "^10.2.2 || ^11.0.3 || ^12.0.0 || ^13.0.0",
|
||||
"jasmine-core": "~6.2.0"
|
||||
"jasmine-core": "~6.1.0"
|
||||
},
|
||||
"bin": {
|
||||
"jasmine": "bin/jasmine.js"
|
||||
}
|
||||
},
|
||||
"node_modules/jasmine-core": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-6.2.0.tgz",
|
||||
"integrity": "sha512-b16WZG/pFEFj8qRW1ss7nDuNGYz9ji8BDGj7fJNrROauk5rj/diO3KPOuyIpcgUChdC+c0PfQ8iUk4nHE+EN4w==",
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-6.1.0.tgz",
|
||||
"integrity": "sha512-p/tjBw58O6vxKIWMlrU+yys8lqR3+l3UrqwNTT7wpj+dQ7N4etQekFM8joI+cWzPDYqZf54kN+hLC1+s5TvZvg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
@@ -2922,20 +3059,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz",
|
||||
"integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==",
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
|
||||
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/puzrin"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/nodeca"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1"
|
||||
@@ -3377,6 +3504,13 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/package-json-from-dist": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
|
||||
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0"
|
||||
},
|
||||
"node_modules/parent-module": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||
@@ -3739,9 +3873,9 @@
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz",
|
||||
"integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==",
|
||||
"version": "7.7.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
|
||||
"integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
@@ -3950,6 +4084,22 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width-cjs": {
|
||||
"name": "string-width",
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/string.prototype.trim": {
|
||||
"version": "1.2.10",
|
||||
"resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz",
|
||||
@@ -4022,6 +4172,20 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-ansi-cjs": {
|
||||
"name": "strip-ansi",
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-bom": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
|
||||
@@ -4095,18 +4259,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/test-exclude": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-8.0.0.tgz",
|
||||
"integrity": "sha512-ZOffsNrXYggvU1mDGHk54I96r26P8SyMjO5slMKSc7+IWmtB/MQKnEC2fP51imB3/pT6YK5cT5E8f+Dd9KdyOQ==",
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.2.tgz",
|
||||
"integrity": "sha512-u9E6A+ZDYdp7a4WnarkXPZOx8Ilz46+kby6p1yZ8zsGTz9gYa6FIS7lj2oezzNKmtdyyJNNmmXDppga5GB7kSw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@istanbuljs/schema": "^0.1.2",
|
||||
"glob": "^13.0.6",
|
||||
"glob": "^10.4.1",
|
||||
"minimatch": "^10.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/test-exclude/node_modules/balanced-match": {
|
||||
@@ -4120,9 +4284,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/test-exclude/node_modules/brace-expansion": {
|
||||
"version": "5.0.6",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz",
|
||||
"integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==",
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz",
|
||||
"integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -4132,14 +4296,76 @@
|
||||
"node": "18 || 20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/test-exclude/node_modules/glob": {
|
||||
"version": "10.5.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
|
||||
"integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
|
||||
"deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"foreground-child": "^3.1.0",
|
||||
"jackspeak": "^3.1.2",
|
||||
"minimatch": "^9.0.4",
|
||||
"minipass": "^7.1.2",
|
||||
"package-json-from-dist": "^1.0.0",
|
||||
"path-scurry": "^1.11.1"
|
||||
},
|
||||
"bin": {
|
||||
"glob": "dist/esm/bin.mjs"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/test-exclude/node_modules/glob/node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/test-exclude/node_modules/glob/node_modules/brace-expansion": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/test-exclude/node_modules/glob/node_modules/minimatch": {
|
||||
"version": "9.0.9",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
|
||||
"integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/test-exclude/node_modules/lru-cache": {
|
||||
"version": "10.4.3",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
|
||||
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/test-exclude/node_modules/minimatch": {
|
||||
"version": "10.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
|
||||
"integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
|
||||
"version": "10.2.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz",
|
||||
"integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^5.0.5"
|
||||
"brace-expansion": "^5.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "18 || 20 || >=22"
|
||||
@@ -4148,10 +4374,27 @@
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/test-exclude/node_modules/path-scurry": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
|
||||
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"lru-cache": "^10.2.0",
|
||||
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/tmp": {
|
||||
"version": "0.2.7",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.7.tgz",
|
||||
"integrity": "sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==",
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz",
|
||||
"integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -4520,6 +4763,25 @@
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi-cjs": {
|
||||
"name": "wrap-ansi",
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/xmlbuilder": {
|
||||
"version": "15.1.1",
|
||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cordova/eslint-config": "^6.0.1",
|
||||
"c8": "^11.0.0",
|
||||
"c8": "^10.1.3",
|
||||
"cordova-js": "^6.1.0",
|
||||
"elementtree": "^0.1.7",
|
||||
"jasmine": "^6.0.0",
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
<!--
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
-->
|
||||
|
||||
Files from the www folder of the Cordova project will be copied here.
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
* {
|
||||
-webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
|
||||
}
|
||||
|
||||
body {
|
||||
-webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */
|
||||
-webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */
|
||||
-webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
|
||||
background-color:#E4E4E4;
|
||||
background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
|
||||
background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
|
||||
background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
|
||||
background-image:-webkit-gradient(
|
||||
linear,
|
||||
left top,
|
||||
left bottom,
|
||||
color-stop(0, #A7A7A7),
|
||||
color-stop(0.51, #E4E4E4)
|
||||
);
|
||||
background-attachment:fixed;
|
||||
font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
|
||||
font-size:12px;
|
||||
height:100%;
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
text-transform:uppercase;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
/* Portrait layout (default) */
|
||||
.app {
|
||||
background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
|
||||
position:absolute; /* position in the center of the screen */
|
||||
left:50%;
|
||||
top:50%;
|
||||
height:50px; /* text area height */
|
||||
width:225px; /* text area width */
|
||||
text-align:center;
|
||||
padding:180px 0px 0px 0px; /* image height is 200px (bottom 20px are overlapped with text) */
|
||||
margin:-115px 0px 0px -112px; /* offset vertical: half of image height and text area height */
|
||||
/* offset horizontal: half of text area width */
|
||||
}
|
||||
|
||||
/* Landscape layout (with min-width) */
|
||||
@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
|
||||
.app {
|
||||
background-position:left center;
|
||||
padding:75px 0px 75px 170px; /* padding-top + padding-bottom + text area = image height */
|
||||
margin:-90px 0px 0px -198px; /* offset vertical: half of image height */
|
||||
/* offset horizontal: half of image width and text area width */
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size:24px;
|
||||
font-weight:normal;
|
||||
margin:0px;
|
||||
overflow:visible;
|
||||
padding:0px;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.event {
|
||||
border-radius:4px;
|
||||
-webkit-border-radius:4px;
|
||||
color:#FFFFFF;
|
||||
font-size:12px;
|
||||
margin:0px 30px;
|
||||
padding:2px 0px;
|
||||
}
|
||||
|
||||
.event.listening {
|
||||
background-color:#333333;
|
||||
display:block;
|
||||
}
|
||||
|
||||
.event.received {
|
||||
background-color:#4B946A;
|
||||
display:none;
|
||||
}
|
||||
|
||||
@keyframes fade {
|
||||
from { opacity: 1.0; }
|
||||
50% { opacity: 0.4; }
|
||||
to { opacity: 1.0; }
|
||||
}
|
||||
|
||||
@-webkit-keyframes fade {
|
||||
from { opacity: 1.0; }
|
||||
50% { opacity: 0.4; }
|
||||
to { opacity: 1.0; }
|
||||
}
|
||||
|
||||
.blink {
|
||||
animation:fade 3000ms infinite;
|
||||
-webkit-animation:fade 3000ms infinite;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
@@ -0,0 +1,49 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<!--
|
||||
Customize this policy to fit your own app's needs. For more guidance, see:
|
||||
https://cordova.apache.org/docs/en/latest/
|
||||
Some notes:
|
||||
* gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication
|
||||
* https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly
|
||||
* Disables use of inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:
|
||||
* Enable inline JS: add 'unsafe-inline' to default-src
|
||||
-->
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="msapplication-tap-highlight" content="no">
|
||||
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
|
||||
<link rel="stylesheet" type="text/css" href="css/index.css">
|
||||
<title>Hello World</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app">
|
||||
<h1>Apache Cordova</h1>
|
||||
<div id="deviceready" class="blink">
|
||||
<p class="event listening">Connecting to Device</p>
|
||||
<p class="event received">Device is Ready</p>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="cordova.js"></script>
|
||||
<script type="text/javascript" src="js/index.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
var app = {
|
||||
// Application Constructor
|
||||
initialize: function () {
|
||||
this.bindEvents();
|
||||
},
|
||||
// Bind Event Listeners
|
||||
//
|
||||
// Bind any events that are required on startup. Common events are:
|
||||
// 'load', 'deviceready', 'offline', and 'online'.
|
||||
bindEvents: function () {
|
||||
document.addEventListener('deviceready', this.onDeviceReady, false);
|
||||
},
|
||||
// deviceready Event Handler
|
||||
//
|
||||
// The scope of 'this' is the event. In order to call the 'receivedEvent'
|
||||
// function, we must explicitly call 'app.receivedEvent(...);'
|
||||
onDeviceReady: function () {
|
||||
app.receivedEvent('deviceready');
|
||||
},
|
||||
// Update DOM on a Received Event
|
||||
receivedEvent: function (id) {
|
||||
var parentElement = document.getElementById(id);
|
||||
var listeningElement = parentElement.querySelector('.listening');
|
||||
var receivedElement = parentElement.querySelector('.received');
|
||||
|
||||
listeningElement.setAttribute('style', 'display:none;');
|
||||
receivedElement.setAttribute('style', 'display:block;');
|
||||
|
||||
console.log('Received Event: ' + id);
|
||||
}
|
||||
};
|
||||
|
||||
app.initialize();
|
||||
Reference in New Issue
Block a user