Repository: apache/cordova-browser
Branch: master
Commit: 6e93ff817b13
Files: 43
Total size: 116.2 KB
Directory structure:
gitextract_zo_vyim0/
├── .asf.yaml
├── .gitattributes
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── BUG_REPORT.md
│ │ ├── FEATURE_REQUEST.md
│ │ └── SUPPORT_QUESTION.md
│ ├── ISSUE_TEMPLATE.md
│ ├── PULL_REQUEST_TEMPLATE.md
│ └── workflows/
│ ├── ci.yml
│ └── release-audit.yml
├── .gitignore
├── .npmignore
├── .npmrc
├── .ratignore
├── CONTRIBUTING.md
├── LICENSE
├── NOTICE
├── README.md
├── RELEASENOTES.md
├── bin/
│ ├── lib/
│ │ ├── check_reqs.js
│ │ ├── create.js
│ │ └── update.js
│ └── template/
│ ├── cordova/
│ │ ├── Api.js
│ │ ├── browser_handler.js
│ │ ├── browser_parser.js
│ │ ├── defaults.xml
│ │ ├── lib/
│ │ │ ├── build.js
│ │ │ ├── clean.js
│ │ │ └── run.js
│ │ └── version
│ └── www/
│ ├── css/
│ │ └── index.css
│ ├── index.html
│ ├── js/
│ │ └── index.js
│ └── manifest.json
├── cordova-js-src/
│ ├── confighelper.js
│ ├── exec.js
│ └── platform.js
├── eslint.config.js
├── licence_checker.yml
├── package.json
└── spec/
├── browser_handler.spec.js
├── create.spec.js
├── projectApi.spec.js
└── support/
└── jasmine.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .asf.yaml
================================================
# 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.
notifications:
commits: commits@cordova.apache.org
issues: issues@cordova.apache.org
pullrequests_status: issues@cordova.apache.org
pullrequests_comment: issues@cordova.apache.org
================================================
FILE: .gitattributes
================================================
# 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.
* text eol=lf
# source code
*.php text
*.css text
*.sass text
*.scss text
*.less text
*.styl text
*.js text
*.coffee text
*.json text
*.htm text
*.html text
*.xml text
*.svg text
*.txt text
*.ini text
*.inc text
*.pl text
*.rb text
*.py text
*.scm text
*.sql text
*.sh text
*.bat text
# templates
*.ejs text
*.hbt text
*.jade text
*.haml text
*.hbs text
*.dot text
*.tmpl text
*.phtml text
# server config
.htaccess text
# git config
.gitattributes text
.gitignore text
.gitconfig text
# code analysis config
.jshintrc text
.jscsrc text
.jshintignore text
.csslintrc text
# misc config
*.yaml text
*.yml text
.editorconfig text
# build config
*.npmignore text
*.bowerrc text
# Heroku
Procfile text
.slugignore text
# Documentation
*.md text
LICENSE text
AUTHORS text
#
## These files are binary and should be left untouched
#
# (binary is a macro for -text -diff)
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.mov binary
*.mp4 binary
*.mp3 binary
*.flv binary
*.fla binary
*.swf binary
*.gz binary
*.zip binary
*.7z binary
*.ttf binary
*.eot binary
*.woff binary
*.pyc binary
*.pdf binary
================================================
FILE: .github/ISSUE_TEMPLATE/BUG_REPORT.md
================================================
---
name: 🐛 Bug Report
about: If something isn't working as expected.
---
# Bug Report
## Problem
### What is expected to happen?
### What does actually happen?
## Information
<!-- Include all relevant information that might help understand and reproduce the problem -->
### Command or Code
<!-- What command or code is needed to reproduce the problem? -->
### Environment, Platform, Device
<!-- In what environment, on what platform or on which device are you experiencing the issue? -->
### Version information
<!--
What are relevant versions you are using?
For example:
Cordova: Cordova CLI, Cordova Platforms, Cordova Plugins
Other Frameworks: Ionic Framework and CLI version
Operating System, Android Studio, Xcode etc.
-->
## Checklist
<!-- Please check the boxes by putting an x in the [ ] like so: [x] -->
- [ ] I searched for existing GitHub issues
- [ ] I updated all Cordova tooling to most recent version
- [ ] I included all the necessary information above
================================================
FILE: .github/ISSUE_TEMPLATE/FEATURE_REQUEST.md
================================================
---
name: 🚀 Feature Request
about: A suggestion for a new functionality
---
# Feature Request
## Motivation Behind Feature
<!-- Why should this feature be implemented? What problem does it solve? -->
## Feature Description
<!--
Describe your feature request in detail
Please provide any code examples or screenshots of what this feature would look like
Are there any drawbacks? Will this break anything for existing users?
-->
## Alternatives or Workarounds
<!--
Describe alternatives or workarounds you are currently using
Are there ways to do this with existing functionality?
-->
================================================
FILE: .github/ISSUE_TEMPLATE/SUPPORT_QUESTION.md
================================================
---
name: 💬 Support Question
about: If you have a question, please check out our Slack or StackOverflow!
---
<!------------^ Click "Preview" for a nicer view! -->
Apache Cordova uses GitHub Issues as a feature request and bug tracker _only_.
For usage and support questions, please check out the resources below. Thanks!
---
You can get answers to your usage and support questions about **Apache Cordova** on:
* Slack Community Chat: https://cordova.slack.com (you can sign-up at http://slack.cordova.io/)
* StackOverflow: https://stackoverflow.com/questions/tagged/cordova using the tag `cordova`
---
If you are using a tool that uses Cordova internally, like e.g. Ionic, check their support channels:
* **Ionic Framework**
* [Ionic Community Forum](https://forum.ionicframework.com/)
* [Ionic Worldwide Slack](https://ionicworldwide.herokuapp.com/)
* **PhoneGap**
* [PhoneGap Developer Community](https://forums.adobe.com/community/phonegap)
================================================
FILE: .github/ISSUE_TEMPLATE.md
================================================
<!--
Please have a look at the issue templates you get when you click "New issue" in the GitHub UI.
We very much prefer issues created by using one of these templates.
-->
### Issue Type
<!-- Please check the boxes by putting an x in the [ ] like so: [x] -->
- [ ] Bug Report
- [ ] Feature Request
- [ ] Support Question
## Description
## Information
<!-- Include all relevant information that might help understand and reproduce the problem -->
### Command or Code
<!-- What command or code is needed to reproduce the problem? -->
### Environment, Platform, Device
<!-- In what environment, on what platform or on which device are you experiencing the issue? -->
### Version information
<!--
What are relevant versions you are using?
For example:
Cordova: Cordova CLI, Cordova Platforms, Cordova Plugins
Other Frameworks: Ionic Framework and CLI version
Operating System, Android Studio, Xcode etc.
-->
## Checklist
<!-- Please check the boxes by putting an `x` in the `[ ]` like so: `[x]` -->
- [ ] I searched for already existing GitHub issues about this
- [ ] I updated all Cordova tooling to their most recent version
- [ ] I included all the necessary information above
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
<!--
Please make sure the checklist boxes are all checked before submitting the PR. The checklist is intended as a quick reference, for complete details please see our Contributor Guidelines:
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. -->
### Description
<!-- Describe your changes in detail -->
### Testing
<!-- Please describe in detail how you tested your changes. -->
### Checklist
- [ ] I've run the tests to see all new and existing tests pass
- [ ] I added automated test coverage as appropriate for this change
- [ ] Commit is prefixed with `(platform)` if this change only applies to one platform (e.g. `(android)`)
- [ ] If this Pull Request resolves an issue, I linked to the issue in the text above (and used the correct [keyword to close issues using keywords](https://help.github.com/articles/closing-issues-using-keywords/))
- [ ] I've updated the documentation if necessary
================================================
FILE: .github/workflows/ci.yml
================================================
# 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.
name: Node CI
on:
push:
branches-ignore:
- 'dependabot/**'
pull_request:
branches:
- '*'
permissions:
contents: read
security-events: write
jobs:
test:
name: NodeJS ${{ matrix.node-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
node-version: [20.x, 22.x, 24.x]
os: [ubuntu-latest, windows-latest, macos-15]
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Environment Information
run: |
node --version
npm --version
# "bin/template/www/cordova.js" is ignored because it is a generated file.
# 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@v3
with:
languages: javascript
queries: security-and-quality
config: |
paths-ignore:
- coverage
- node_modules
- bin/template/www/cordova.js
- name: npm install and test
run: |
npm i
npm t
env:
CI: true
- uses: github/codeql-action/analyze@v3
# v4.6.0
- uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238
if: success()
with:
name: ${{ runner.os }} node.js ${{ matrix.node-version }}
token: ${{ secrets.CORDOVA_CODECOV_TOKEN }}
fail_ci_if_error: false
================================================
FILE: .github/workflows/release-audit.yml
================================================
# 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.
name: Release Auditing
on:
push:
branches-ignore:
- 'dependabot/**'
pull_request:
branches:
- '*'
permissions:
contents: read
jobs:
test:
name: Audit Licenses
runs-on: ubuntu-latest
steps:
# Checkout project
- uses: actions/checkout@v6
# Check license headers (v2.0.0)
- uses: erisu/apache-rat-action@46fb01ce7d8f76bdcd7ab10e7af46e1ea95ca01c
# Setup environment with node
- uses: actions/setup-node@v6
with:
node-version: 24
# Install node packages
- name: npm install packages
run: npm ci
# Check node package licenses (v2.0.1)
- uses: erisu/license-checker-action@99cffa11264fe545fd0baa6c13bca5a00ae608f2
with:
license-config: 'licence_checker.yml'
include-asf-category-a: true
================================================
FILE: .gitignore
================================================
# 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.
# System
.DS_Store
# IDE
.vscode
# npm
npm-debug.log
node_modules/
# Testing, code coverage, and linting output
coverage/
.nyc_output/
temp
# Output of 'npm pack'
*.tgz
# Other
bin/template/www/cordova.js
================================================
FILE: .npmignore
================================================
# 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.
# Config related files
.*
# Testing, code coverage, and linting
coverage
spec
eslint.config.js
licence_checker.yml
# Logging
logs
*.log
npm-debug.log*
# Output of 'npm pack'
*.tgz
# others
cordova-js-src
================================================
FILE: .npmrc
================================================
# 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.
registry=https://registry.npmjs.org
================================================
FILE: .ratignore
================================================
# 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.
.git/
coverage/
node_modules/
VERSION
================================================
FILE: CONTRIBUTING.md
================================================
<!--
#
# 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.
#
-->
# Contributing to Apache Cordova
Anyone can contribute to Cordova. And we need your contributions.
There are multiple ways to contribute: report bugs, improve the docs, and
contribute code.
For instructions on this, start with the
[contribution overview](http://cordova.apache.org/contribute/).
The details are explained there, but the important items are:
- Check for Github issues that corresponds to your contribution and link or create them if necessary.
- Run the tests so your patch doesn't break existing functionality.
We look forward to your contributions!
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed 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.
================================================
FILE: NOTICE
================================================
Apache Cordova
Copyright 2012-2015 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
================================================
FILE: README.md
================================================
<!--
#
# 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.
#
-->
[](https://github.com/apache/cordova-browser/actions?query=branch%3Amaster)
[](https://codecov.io/github/apache/cordova-browser?branch=master)
# Cordova Browser
Target modern web browsers to build Apache Cordova based applications.
# Goals
- Browser targeted deployment
- Surfacing native platform incompatibilities from the open web platform
# PWA support
## cordova-browser now includes support for progressive web apps (PWAs)
- if your project supplies a `manifest.json` in the `www/` dir, it will be used
- a `manifest.json` will be generated otherwise
- if your js code registers a service worker, it will also be used
================================================
FILE: RELEASENOTES.md
================================================
<!--
#
# 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.
#
-->
## Release Notes for Cordova Browser ##
### 7.0.0 (May 13, 2023)
#### Breaking Changes
* [GH-121](https://github.com/apache/cordova-browser/pull/121) Minimum NodeJS Required: 16.13.0
* [GH-115](https://github.com/apache/cordova-browser/pull/115) Update ShellJS to 0.8.5.
* [GH-78](https://github.com/apache/cordova-browser/pull/78) feat: Replace `Q` with native Promises.
#### Other Notable Changes
* [GH-117](https://github.com/apache/cordova-browser/pull/117) Added `.npmrc` file to ensure the official NPM registry is used during development and deployments.
* [GH-107](https://github.com/apache/cordova-browser/pull/107) Enabled `package-lock.json` file.
* [GH-119](https://github.com/apache/cordova-browser/pull/119) Added NodeJS 20 to our test matrix.
* [GH-118](https://github.com/apache/cordova-browser/pull/118) Updated ESLint config to match better match Apache Cordova's coding style standards.
* [GH-80](https://github.com/apache/cordova-browser/pull/80) Enabled CodeCov test coverage
* [GH-113](https://github.com/apache/cordova-browser/pull/113) Migrated to GitHub Action workflows for our testing CI.
For a full list of changes, see the [commit history](https://github.com/apache/cordova-browser/compare/rel/6.0.0...4669c4dce952c658ba7eb951ebfcae35b96a56ea)
### 6.0.0 (Feb 01, 2019)
* [GH-70](https://github.com/apache/cordova-browser/pull/70) Browser Platform Release Preparation (Cordova 9)
* [GH-68](https://github.com/apache/cordova-browser/pull/68) Copy node_modules if the directory exists
* [GH-63](https://github.com/apache/cordova-browser/pull/63) Dependency bump cordova-common@^3.0.0
* [CB-13740](https://issues.apache.org/jira/browse/CB-13740) Return expected promise resolving with array
* [GH-59](https://github.com/apache/cordova-browser/pull/59) Remove Bundled Dependencies
* [CB-14073](https://issues.apache.org/jira/browse/CB-14073) **Browser**: Drop Node 4, Added Node 10
* [CB-14252](https://issues.apache.org/jira/browse/CB-14252) Allow to send --silent arg to run command to disable output (#57)
* [CB-13999](https://issues.apache.org/jira/browse/CB-13999) (browser) - Reading `config.xml` respects base href (#52)
* [GH-50](https://github.com/apache/cordova-browser/pull/50) corrected path for `config.xml`
* [CB-13689](https://issues.apache.org/jira/browse/CB-13689) Updated RELEASENOTES and Version for release 5.0.3
### 5.0.2 (Dec 18, 2017)
* [CB-13689](https://issues.apache.org/jira/browse/CB-13689): Updated checked-in node_modules
* [CB-13562](https://issues.apache.org/jira/browse/CB-13562): fixed asset tag when adding push plugin to **Browser**
### 5.0.1 (Oct 16, 2017)
* [CB-13444](https://issues.apache.org/jira/browse/CB-13444) Updated checked-in `node_modules`
* [CB-13435](https://issues.apache.org/jira/browse/CB-13435) fix merges directory support for **Browser**
* [CB-12895](https://issues.apache.org/jira/browse/CB-12895) ignoring `cordova.js` for `eslint`
### 5.0.0 (Aug 24, 2017)
* [CB-13214](https://issues.apache.org/jira/browse/CB-13214) Updated `cordova-serve` dependnecy to 2.0.0. `cordova serve` command now opens system default browser instead of a new instance of `chrome`. A specific target can still be passed in.
* [CB-13214](https://issues.apache.org/jira/browse/CB-13214) Updated checked-in `node_modules`
* [CB-13188](https://issues.apache.org/jira/browse/CB-13188) fixed issues with run and build scripts.
* [CB-12895](https://issues.apache.org/jira/browse/CB-12895): set up `eslint` and remove `jshint`
* [CB-11181](https://issues.apache.org/jira/browse/CB-11181) add default favicon
* [CB-11710](https://issues.apache.org/jira/browse/CB-11710) Add missing 'clean.bat' file
* remove old `xhr-activex` **Windows** code, update to use `pagevisibility` instead of `webkitpagevisibility`
* [CB-12804](https://issues.apache.org/jira/browse/CB-12804): `manifest.json` added to **Browser** during create. Adding basic PWA support
* [CB-12762](https://issues.apache.org/jira/browse/CB-12762) Point repo items to github mirrors
* Clean up PRs. Closes #2. Closes #25
* [CB-12617](https://issues.apache.org/jira/browse/CB-12617) : removed node 0.x support and added engineStrict. This closes #27
* [CB-12847](https://issues.apache.org/jira/browse/CB-12847) added `bugs` entry to `package.json`.
* [CB-12527](https://issues.apache.org/jira/browse/CB-12527) large refactor. Implemented `PlatformApi`
* [CB-12114](https://issues.apache.org/jira/browse/CB-12114) added travis and appveyor files
* Add github pull request template
### 4.0.0 (Aug 13, 2015)
* updated version in version script
* added `.ratignore` and added missing AL header to readme
* removed other platform screens from template
* updated to 4.0.0-dev
* [CB-8965](https://issues.apache.org/jira/browse/CB-8965) Copy `cordova-js-src` directory to platform folder during create
* Adds LICENSE and NOTICE files.
* [CB-9350](https://issues.apache.org/jira/browse/CB-9350) 'cordova run browser' throws an exception.
* Update 'cordova run browser' command to use cordova-serve module.
* [CB-8417](https://issues.apache.org/jira/browse/CB-8417) update platform specific js from cordovajs
* [CB-8760](https://issues.apache.org/jira/browse/CB-8760) platform list shows wrong version for browser platform.
* [CB-8182](https://issues.apache.org/jira/browse/CB-8182) port `cordova serve` to `cordova run browser`
* [CB-8182](https://issues.apache.org/jira/browse/CB-8182) add dependency on `mime` library
* [CB-8196](https://issues.apache.org/jira/browse/CB-8196) Browser platform `run` should default source file to index.html even if it's missing in the config.xml
* [CB-8223](https://issues.apache.org/jira/browse/CB-8223) Expose config.xml in the Browser platform
* [CB-8417](https://issues.apache.org/jira/browse/CB-8417) renamed platform_modules into cordova-js-src
* [CB-8417](https://issues.apache.org/jira/browse/CB-8417) moved platform specific js into platform
* [CB-8224](https://issues.apache.org/jira/browse/CB-8224) Add support to launch a specified browser using --target switch. Support for multiple browsers on Windows, Mac and Linux
* Add Windows specific shim wrappers for shjs - auto-generated by npm install
* [CB-8206](https://issues.apache.org/jira/browse/CB-8206) Browser platform: Add support for update
* --user-data-dir working on windows
* [CB-7978](https://issues.apache.org/jira/browse/CB-7978) Cleaning code and creating temporary dir - Using path.resolve and path.join instead of concatenating paths - Fixing error when temporary dir already exists by using shelljs instead of fs
* [CB-7978](https://issues.apache.org/jira/browse/CB-7978) Cleaning code and creating temporary dir - Cleaning code - Declaring variables only when needed - Creating chrome for Cordova temp dir prior using it by std and err
* [CB-7978](https://issues.apache.org/jira/browse/CB-7978) Fixed launching chrome in Linux
### 3.6.0 ###
* Update JS snapshot to version 3.6.0 (via coho)
* Set VERSION to 3.6.0 (via coho)
* added run.bat file
* added windows run support, still a few issues
* No longer need to kill Chrome for mac
* added create.bat for windows support
* Removed old dependency from source
* Fixed issue with npm cache when adding browser
* Fixed directory structure
* Creating browser project
* [CB-6818](https://issues.apache.org/jira/browse/CB-6818) Add license for CONTRIBUTING.md
* [CB-6491](https://issues.apache.org/jira/browse/CB-6491) add CONTRIBUTING.md
================================================
FILE: bin/lib/check_reqs.js
================================================
#!/usr/bin/env node
/*
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.
*/
// add methods as we determine what are the requirements
module.exports.run = function () {
// caller expects a promise resolved with an array of conditions
return Promise.resolve([]);
};
================================================
FILE: bin/lib/create.js
================================================
#!/usr/bin/env node
/*
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.
*/
const fs = require('node:fs');
const path = require('node:path');
const ROOT = path.join(__dirname, '..', '..');
const events = require('cordova-common').events;
const check_reqs = require('./check_reqs');
// exported method to create a project, returns a promise that resolves with null
module.exports.createProject = function (project_path, package_name, project_name) {
/*
// create the dest and the standard place for our api to live
// platforms/platformName/cordova/Api.js
*/
events.emit('log', 'Creating Cordova project for cordova-browser:');
events.emit('log', '\tPath: ' + project_path);
events.emit('log', '\tName: ' + project_name);
// Set default values for path, package and name
project_path = project_path || 'CordovaExample';
// Check if project already exists
if (fs.existsSync(project_path)) {
events.emit('error', 'Oops, destination already exists! Delete it and try again');
} else {
fs.mkdirSync(project_path);
}
// Check that requirements are met and proper targets are installed
if (!check_reqs.run()) {
// TODO: use events.emit
events.emit('error', 'Please make sure you meet the software requirements in order to build a browser cordova project');
}
// copy template/* to project_path directory ( recursive )
fs.cpSync(path.join(ROOT, 'bin/template'), project_path, { recursive: true });
// TODO: stop copying cordova-browser logic into platforms/browser/
// recreate our node_modules structure in the new project
const nodeModulesDir = path.join(ROOT, 'node_modules');
if (fs.existsSync(nodeModulesDir)) {
fs.cpSync(nodeModulesDir, path.join(project_path, 'cordova/node_modules'), { recursive: true });
}
// copy check_reqs file
fs.cpSync(
path.join(ROOT, 'bin/lib/check_reqs.js'),
path.join(project_path, 'cordova/lib/check_reqs.js')
);
// create platform_www dir if it does not exist yet
const platform_www = path.join(project_path, 'platform_www');
fs.mkdirSync(platform_www, { recursive: true });
// copy cordova js file to platform_www
fs.cpSync(
path.join(ROOT, 'bin/template/www/cordova.js'),
path.join(platform_www, 'cordova.js')
);
// copy favicon file to platform_www
fs.cpSync(
path.join(ROOT, 'bin/template/www/favicon.ico'),
path.join(platform_www, 'favicon.ico')
);
// load manifest to write name/shortname
const manifest = require(path.join(ROOT, 'bin/template/www', 'manifest.json'));
manifest.name = project_name;
manifest.short_name = project_name;
// copy manifest file to platform_www
fs.writeFileSync(path.join(platform_www, 'manifest.json'),
JSON.stringify(manifest, null, 2), 'utf-8');
return Promise.resolve();
};
================================================
FILE: bin/lib/update.js
================================================
/*
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.
*/
const create = require('./create');
const fs = require('node:fs');
const { CordovaError } = require('cordova-common');
module.exports.help = function () {
console.log('WARNING : Make sure to back up your project before updating!');
console.log('Usage: update PathToProject ');
console.log(' PathToProject : The path the project you would like to update.');
console.log('examples:');
console.log(' update C:\\Users\\anonymous\\Desktop\\MyProject');
};
module.exports.run = function (argv) {
const projectPath = argv[2];
// If the specified project path is not valid then reject promise.
if (!fs.existsSync(projectPath)) {
return Promise.reject(new CordovaError(`Browser platform does not exist here: ${projectPath}`));
}
console.log('Removing existing browser platform.');
fs.rmSync(projectPath, { recursive: true, force: true });
// Create Project returns a resolved promise.
return create.createProject(projectPath);
};
================================================
FILE: bin/template/cordova/Api.js
================================================
/*
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.
*/
/*
this file is found by cordova-lib when you attempt to
'cordova platform add PATH' where path is this repo.
*/
const path = require('node:path');
const fs = require('node:fs');
const cdvcmn = require('cordova-common');
const CordovaLogger = cdvcmn.CordovaLogger;
const ConfigParser = cdvcmn.ConfigParser;
const ActionStack = cdvcmn.ActionStack;
const selfEvents = cdvcmn.events;
const xmlHelpers = cdvcmn.xmlHelpers;
const PlatformJson = cdvcmn.PlatformJson;
const PlatformMunger = cdvcmn.ConfigChanges.PlatformMunger;
const PluginInfoProvider = cdvcmn.PluginInfoProvider;
const CordovaError = cdvcmn.CordovaError;
const FileUpdater = cdvcmn.FileUpdater;
const PLATFORM_NAME = 'browser';
function setupEvents (externalEventEmitter) {
if (externalEventEmitter) {
// This will make the platform internal events visible outside
selfEvents.forwardEventsTo(externalEventEmitter);
return externalEventEmitter;
}
// There is no logger if external emitter is not present,
// so attach a console logger
CordovaLogger.get().subscribe(selfEvents);
return selfEvents;
}
/**
* Logs all file operations via the verbose event stream, indented.
*/
function logFileOp (message) {
selfEvents.emit('verbose', ' ' + message);
}
function dirExists (dir) {
return fs.existsSync(dir) && fs.statSync(dir).isDirectory();
}
function Api (platform, platformRootDir, events) {
this.platform = platform || PLATFORM_NAME;
// MyApp/platforms/browser
this.root = path.resolve(__dirname, '..');
this.events = setupEvents(events);
if (!dirExists(this.root) || !dirExists(path.join(this.root, 'cordova'))) {
throw new CordovaError('The provided path "' + this.root + '" is not a valid browser project.');
}
this._handler = require('./browser_handler');
this.locations = {
platformRootDir,
root: this.root,
www: path.join(this.root, 'www'),
res: path.join(this.root, 'res'),
platformWww: path.join(this.root, 'platform_www'),
configXml: path.join(this.root, 'config.xml'),
defaultConfigXml: path.join(this.root, 'cordova/defaults.xml'),
build: path.join(this.root, 'build'),
// NOTE: Due to platformApi spec we need to return relative paths here
cordovaJs: 'bin/templates/project/assets/www/cordova.js',
cordovaJsSrc: 'cordova-js-src'
};
this._platformJson = PlatformJson.load(this.root, platform);
this._pluginInfoProvider = new PluginInfoProvider();
this._munger = new PlatformMunger(platform, this.root, this._platformJson, this._pluginInfoProvider);
}
Api.createPlatform = function (dest, config, options, events) {
const creator = require('../../lib/create');
events = setupEvents(events);
let name = 'HelloCordova';
let id = 'io.cordova.hellocordova';
if (config) {
name = config.name();
id = config.packageName();
}
let result;
try {
// we create the project using our scripts in this platform
result = creator.createProject(dest, id, name, options)
.then(function () {
// after platform is created we return Api instance based on new Api.js location
// Api.js has been copied to the new project
// This is required to correctly resolve paths in the future api calls
const PlatformApi = require(path.resolve(dest, 'cordova/Api'));
return new PlatformApi('browser', dest, events);
});
} catch (e) {
events.emit('error', 'createPlatform is not callable from the browser project API.');
throw (e);
}
return result;
};
Api.updatePlatform = function (dest, options, events) {
// console.log("test-platform:Api:updatePlatform");
// todo?: create projectInstance and fulfill promise with it.
return Promise.resolve();
};
Api.prototype.getPlatformInfo = function () {
// console.log("browser-platform:Api:getPlatformInfo");
// return PlatformInfo object
return {
locations: this.locations,
root: this.root,
name: this.platform,
version: { version: '1.0.0' }, // um, todo!
projectConfig: this.config
};
};
Api.prototype.prepare = async function (cordovaProject, options) {
// First cleanup current config and merge project's one into own
const defaultConfigPath = path.join(this.locations.platformRootDir, 'cordova',
'defaults.xml');
const ownConfigPath = this.locations.configXml;
const sourceCfg = cordovaProject.projectConfig;
// If defaults.xml is present, overwrite platform config.xml with it.
// Otherwise save whatever is there as defaults so it can be
// restored or copy project config into platform if none exists.
if (fs.existsSync(defaultConfigPath)) {
this.events.emit('verbose', 'Generating config.xml from defaults for platform "' + this.platform + '"');
fs.cpSync(defaultConfigPath, ownConfigPath, { force: true });
} else if (fs.existsSync(ownConfigPath)) {
this.events.emit('verbose', 'Generating defaults.xml from own config.xml for platform "' + this.platform + '"');
fs.cpSync(ownConfigPath, defaultConfigPath, { force: true });
} else {
this.events.emit('verbose', 'case 3"' + this.platform + '"');
fs.cpSync(sourceCfg.path, ownConfigPath, { force: true });
}
// merge our configs
this.config = new ConfigParser(ownConfigPath);
xmlHelpers.mergeXml(cordovaProject.projectConfig.doc.getroot(),
this.config.doc.getroot(),
this.platform, true);
this.config.write();
// Update own www dir with project's www assets and plugins' assets and js-files
this._updateWww(cordovaProject);
// Copy or Create manifest.json
// todo: move this to a manifest helper module
// output path
const manifestPath = path.join(this.locations.www, 'manifest.json');
const srcManifestPath = path.join(cordovaProject.locations.www, 'manifest.json');
if (fs.existsSync(srcManifestPath)) {
// just blindly copy it to our output/www
// todo: validate it? ensure all properties we expect exist?
this.events.emit('verbose', 'copying ' + srcManifestPath + ' => ' + manifestPath);
fs.cpSync(srcManifestPath, manifestPath, { force: true });
} else {
const manifestJson = {
background_color: '#FFF',
display: 'standalone'
};
if (this.config) {
if (this.config.name()) {
manifestJson.name = this.config.name();
}
if (this.config.shortName()) {
manifestJson.short_name = this.config.shortName();
}
if (this.config.packageName()) {
manifestJson.version = this.config.packageName();
}
if (this.config.description()) {
manifestJson.description = this.config.description();
}
if (this.config.author()) {
manifestJson.author = this.config.author();
}
// icons
const icons = this.config.getStaticResources('browser', 'icon');
const manifestIcons = icons.map(function (icon) {
// given a tag like this :
// <icon src="res/ios/icon.png" width="57" height="57" density="mdpi" />
/* configParser returns icons that look like this :
{ src: 'res/ios/icon.png',
target: undefined,
density: 'mdpi',
platform: null,
width: 57,
height: 57
} ******/
/* manifest expects them to be like this :
{ "src": "images/touch/icon-128x128.png",
"type": "image/png",
"sizes": "128x128"
} ******/
// ?Is it worth looking at file extentions?
return {
src: icon.src,
type: 'image/png',
sizes: (icon.width + 'x' + icon.height)
};
});
manifestJson.icons = manifestIcons;
// orientation
// <preference name="Orientation" value="landscape" />
const oriPref = this.config.getGlobalPreference('Orientation');
if (oriPref) {
// if it's a supported value, use it
if (['landscape', 'portrait'].indexOf(oriPref) > -1) {
manifestJson.orientation = oriPref;
} else { // anything else maps to 'any'
manifestJson.orientation = 'any';
}
}
// get start_url
const contentNode = this.config.doc.find('content') || { attrib: { src: 'index.html' } }; // sensible default
manifestJson.start_url = contentNode.attrib.src;
// now we get some values from start_url page ...
const startUrlPath = path.join(cordovaProject.locations.www, manifestJson.start_url);
if (fs.existsSync(startUrlPath)) {
const contents = fs.readFileSync(startUrlPath, 'utf-8');
// matches <meta name="theme-color" content="#FF0044">
const themeColorRegex = /<meta(?=[^>]*name="theme-color")\s[^>]*content="([^>]*)"/i;
const result = themeColorRegex.exec(contents);
let themeColor;
if (result && result.length >= 2) {
themeColor = result[1];
} else { // see if there is a preference in config.xml
// <preference name="StatusBarBackgroundColor" value="#000000" />
themeColor = this.config.getGlobalPreference('StatusBarBackgroundColor');
}
if (themeColor) {
manifestJson.theme_color = themeColor;
}
}
}
fs.writeFileSync(manifestPath, JSON.stringify(manifestJson, null, 2), 'utf8');
}
// Copy munged config.xml to platform www dir
fs.cpSync(
this.locations.configXml,
path.join(this.locations.www, 'config.xml'),
{ force: true, recursive: true }
);
};
// Replace the www dir with contents of platform_www and app www.
Api.prototype._updateWww = function (cordovaProject) {
// add cordova www and platform_www to sourceDirs
const sourceDirs = [
path.relative(cordovaProject.root, cordovaProject.locations.www),
path.relative(cordovaProject.root, this.locations.platformWww)
];
// If project contains 'merges' for our platform, use them as another overrides
const merges_path = path.join(cordovaProject.root, 'merges', 'browser');
if (fs.existsSync(merges_path)) {
selfEvents.emit('verbose', 'Found "merges/browser" folder. Copying its contents into the browser project.');
// add merges/browser to sourceDirs
sourceDirs.push(path.join('merges', 'browser'));
}
// targetDir points to browser/www
const targetDir = path.relative(cordovaProject.root, this.locations.www);
selfEvents.emit('verbose', 'Merging and updating files from [' + sourceDirs.join(', ') + '] to ' + targetDir);
FileUpdater.mergeAndUpdateDir(sourceDirs, targetDir, { rootDir: cordovaProject.root }, logFileOp);
};
Api.prototype.addPlugin = function (pluginInfo, installOptions) {
// console.log(new Error().stack);
if (!pluginInfo) {
return Promise.reject(new Error('The parameter is incorrect. The first parameter ' +
'should be valid PluginInfo instance'));
}
installOptions = installOptions || {};
installOptions.variables = installOptions.variables || {};
// CB-10108 platformVersion option is required for proper plugin installation
installOptions.platformVersion = installOptions.platformVersion ||
this.getPlatformInfo().version;
const self = this;
const actions = new ActionStack();
const projectFile = this._handler.parseProjectFile && this._handler.parseProjectFile(this.root);
// gather all files needs to be handled during install
pluginInfo.getFilesAndFrameworks(this.platform)
.concat(pluginInfo.getAssets(this.platform))
.concat(pluginInfo.getJsModules(this.platform))
.forEach(function (item) {
actions.push(actions.createAction(
self._getInstaller(item.itemType),
[item, pluginInfo.dir, pluginInfo.id, installOptions, projectFile],
self._getUninstaller(item.itemType),
[item, pluginInfo.dir, pluginInfo.id, installOptions, projectFile]));
});
// run through the action stack
return actions.process(this.platform, this.root)
.then(function () {
if (projectFile) {
projectFile.write();
}
// Add PACKAGE_NAME variable into vars
if (!installOptions.variables.PACKAGE_NAME) {
installOptions.variables.PACKAGE_NAME = self._handler.package_name(self.root);
}
self._munger
// Ignore passed `is_top_level` option since platform itself doesn't know
// anything about managing dependencies - it's responsibility of caller.
.add_plugin_changes(pluginInfo, installOptions.variables, /* is_top_level= */true, /* should_increment= */true)
.save_all();
const targetDir = installOptions.usePlatformWww
? self.getPlatformInfo().locations.platformWww
: self.getPlatformInfo().locations.www;
self._addModulesInfo(pluginInfo, targetDir);
});
};
Api.prototype.removePlugin = function (plugin, uninstallOptions) {
// console.log("NotImplemented :: browser-platform:Api:removePlugin ",plugin, uninstallOptions);
uninstallOptions = uninstallOptions || {};
// CB-10108 platformVersion option is required for proper plugin installation
uninstallOptions.platformVersion = uninstallOptions.platformVersion ||
this.getPlatformInfo().version;
const self = this;
const actions = new ActionStack();
const projectFile = this._handler.parseProjectFile && this._handler.parseProjectFile(this.root);
// queue up plugin files
plugin.getFilesAndFrameworks(this.platform)
.concat(plugin.getAssets(this.platform))
.concat(plugin.getJsModules(this.platform))
.forEach(function (item) {
actions.push(actions.createAction(
self._getUninstaller(item.itemType), [item, plugin.dir, plugin.id, uninstallOptions, projectFile],
self._getInstaller(item.itemType), [item, plugin.dir, plugin.id, uninstallOptions, projectFile]));
});
// run through the action stack
return actions.process(this.platform, this.root)
.then(function () {
if (projectFile) {
projectFile.write();
}
self._munger
// Ignore passed `is_top_level` option since platform itself doesn't know
// anything about managing dependencies - it's responsibility of caller.
.remove_plugin_changes(plugin, /* is_top_level= */true)
.save_all();
const targetDir = uninstallOptions.usePlatformWww
? self.getPlatformInfo().locations.platformWww
: self.getPlatformInfo().locations.www;
self._removeModulesInfo(plugin, targetDir);
// Remove stale plugin directory
// TODO: this should be done by plugin files uninstaller
fs.rmSync(
path.resolve(self.root, 'Plugins', plugin.id),
{ force: true, recursive: true }
);
});
};
Api.prototype._getInstaller = function (type) {
const self = this;
return function (item, plugin_dir, plugin_id, options, project) {
const installer = self._handler[type];
if (!installer) {
console.log('unrecognized type ' + type);
} else {
const wwwDest = options.usePlatformWww
? self.getPlatformInfo().locations.platformWww
: self._handler.www_dir(self.root);
if (type === 'asset') {
installer.install(item, plugin_dir, wwwDest);
} else if (type === 'js-module') {
installer.install(item, plugin_dir, plugin_id, wwwDest);
} else {
installer.install(item, plugin_dir, self.root, plugin_id, options, project);
}
}
};
};
Api.prototype._getUninstaller = function (type) {
const self = this;
return function (item, plugin_dir, plugin_id, options, project) {
const installer = self._handler[type];
if (!installer) {
console.log('browser plugin uninstall: unrecognized type, skipping : ' + type);
} else {
const wwwDest = options.usePlatformWww
? self.getPlatformInfo().locations.platformWww
: self._handler.www_dir(self.root);
if (['asset', 'js-module'].indexOf(type) > -1) {
return installer.uninstall(item, wwwDest, plugin_id);
} else {
return installer.uninstall(item, self.root, plugin_id, options, project);
}
}
};
};
/**
* Removes the specified modules from list of installed modules and updates
* platform_json and cordova_plugins.js on disk.
*
* @param {PluginInfo} plugin PluginInfo instance for plugin, which modules
* needs to be added.
* @param {String} targetDir The directory, where updated cordova_plugins.js
* should be written to.
*/
Api.prototype._addModulesInfo = function (plugin, targetDir) {
const installedModules = this._platformJson.root.modules || [];
const installedPaths = installedModules.map(function (installedModule) {
return installedModule.file;
});
const modulesToInstall = plugin.getJsModules(this.platform)
.filter(function (moduleToInstall) {
return installedPaths.indexOf(moduleToInstall.file) === -1;
}).map(function (moduleToInstall) {
const moduleName = plugin.id + '.' + (moduleToInstall.name || moduleToInstall.src.match(/([^/]+)\.js/)[1]);
const obj = {
file: ['plugins', plugin.id, moduleToInstall.src].join('/'),
id: moduleName,
pluginId: plugin.id
};
if (moduleToInstall.clobbers.length > 0) {
obj.clobbers = moduleToInstall.clobbers.map(function (o) { return o.target; });
}
if (moduleToInstall.merges.length > 0) {
obj.merges = moduleToInstall.merges.map(function (o) { return o.target; });
}
if (moduleToInstall.runs) {
obj.runs = true;
}
return obj;
});
this._platformJson.root.modules = installedModules.concat(modulesToInstall);
if (!this._platformJson.root.plugin_metadata) {
this._platformJson.root.plugin_metadata = {};
}
this._platformJson.root.plugin_metadata[plugin.id] = plugin.version;
this._writePluginModules(targetDir);
this._platformJson.save();
};
/**
* Fetches all installed modules, generates cordova_plugins contents and writes
* it to file.
*
* @param {String} targetDir Directory, where write cordova_plugins.js to.
* Ususally it is either <platform>/www or <platform>/platform_www
* directories.
*/
Api.prototype._writePluginModules = function (targetDir) {
// Write out moduleObjects as JSON wrapped in a cordova module to cordova_plugins.js
let final_contents = 'cordova.define(\'cordova/plugin_list\', function(require, exports, module) {\n';
final_contents += 'module.exports = ' + JSON.stringify(this._platformJson.root.modules, null, ' ') + ';\n';
final_contents += 'module.exports.metadata = \n';
final_contents += '// TOP OF METADATA\n';
final_contents += JSON.stringify(this._platformJson.root.plugin_metadata || {}, null, ' ') + '\n';
final_contents += '// BOTTOM OF METADATA\n';
final_contents += '});'; // Close cordova.define.
fs.mkdirSync(targetDir, { recursive: true });
fs.writeFileSync(path.join(targetDir, 'cordova_plugins.js'), final_contents, 'utf-8');
};
/**
* Removes the specified modules from list of installed modules and updates
* platform_json and cordova_plugins.js on disk.
*
* @param {PluginInfo} plugin PluginInfo instance for plugin, which modules
* needs to be removed.
* @param {String} targetDir The directory, where updated cordova_plugins.js
* should be written to.
*/
Api.prototype._removeModulesInfo = function (plugin, targetDir) {
const installedModules = this._platformJson.root.modules || [];
const modulesToRemove = plugin.getJsModules(this.platform)
.map(function (jsModule) {
return ['plugins', plugin.id, jsModule.src].join('/');
});
const updatedModules = installedModules
.filter(function (installedModule) {
return (modulesToRemove.indexOf(installedModule.file) === -1);
});
this._platformJson.root.modules = updatedModules;
if (this._platformJson.root.plugin_metadata) {
delete this._platformJson.root.plugin_metadata[plugin.id];
}
this._writePluginModules(targetDir);
this._platformJson.save();
};
Api.prototype.build = function (buildOptions) {
const self = this;
return require('./lib/check_reqs').run()
.then(function () {
return require('./lib/build').run.call(self, buildOptions);
});
};
Api.prototype.run = function (runOptions) {
return require('./lib/run').run(runOptions);
};
Api.prototype.clean = function (cleanOptions) {
return require('./lib/clean').run(cleanOptions);
};
Api.prototype.requirements = function () {
return require('./lib/check_reqs').run();
};
module.exports = Api;
================================================
FILE: bin/template/cordova/browser_handler.js
================================================
/*
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.
*/
const path = require('node:path');
const fs = require('node:fs');
const events = require('cordova-common').events;
module.exports = {
www_dir: function (project_dir) {
return path.join(project_dir, 'www');
},
package_name: function (project_dir) {
// this method should the id from root config.xml => <widget id=xxx
// return common.package_name(project_dir, this.www_dir(project_dir));
// console.log('package_name called with ' + project_dir);
let pkgName = 'io.cordova.hellocordova';
const widget_id_regex = /(?:<widget\s+id=['"])(\S+)(?:['"])/;
const configPath = path.join(project_dir, 'config.xml');
if (fs.existsSync(configPath)) {
const configStr = fs.readFileSync(configPath, 'utf8');
const res = configStr.match(widget_id_regex);
if (res && res.length > 1) {
pkgName = res[1];
}
}
return pkgName;
},
'js-module': {
install: function (jsModule, plugin_dir, plugin_id, www_dir) {
// Copy the plugin's files into the www directory.
const moduleSource = path.resolve(plugin_dir, jsModule.src);
// Get module name based on existing 'name' attribute or filename
// Must use path.extname/path.basename instead of path.parse due to CB-9981
const moduleName = plugin_id + '.' + (jsModule.name || path.basename(jsModule.src, path.extname(jsModule.src)));
// Read in the file, prepend the cordova.define, and write it back out.
let scriptContent = fs.readFileSync(moduleSource, 'utf-8').replace(/^\ufeff/, ''); // Window BOM
if (moduleSource.match(/.*\.json$/)) {
scriptContent = 'module.exports = ' + scriptContent;
}
scriptContent = 'cordova.define("' + moduleName + '", function(require, exports, module) { ' + scriptContent + '\n});\n';
const moduleDestination = path.resolve(www_dir, 'plugins', plugin_id, jsModule.src);
fs.mkdirSync(path.dirname(moduleDestination), { recursive: true });
fs.writeFileSync(moduleDestination, scriptContent, 'utf-8');
},
uninstall: function (jsModule, www_dir, plugin_id) {
const pluginRelativePath = path.join('plugins', plugin_id, jsModule.src);
// common.removeFileAndParents(www_dir, pluginRelativePath);
console.log('js-module uninstall called : ' + pluginRelativePath);
}
},
'source-file': {
install: function (obj, plugin_dir, project_dir, plugin_id, options) {
// var dest = path.join(obj.targetDir, path.basename(obj.src));
// common.copyFile(plugin_dir, obj.src, project_dir, dest);
console.log('install called');
},
uninstall: function (obj, project_dir, plugin_id, options) {
// var dest = path.join(obj.targetDir, path.basename(obj.src));
// common.removeFile(project_dir, dest);
console.log('uninstall called');
}
},
'header-file': {
install: function (obj, plugin_dir, project_dir, plugin_id, options) {
events.emit('verbose', 'header-fileinstall is not supported for browser');
},
uninstall: function (obj, project_dir, plugin_id, options) {
events.emit('verbose', 'header-file.uninstall is not supported for browser');
}
},
'resource-file': {
install: function (obj, plugin_dir, project_dir, plugin_id, options) {
events.emit('verbose', 'resource-file.install is not supported for browser');
},
uninstall: function (obj, project_dir, plugin_id, options) {
events.emit('verbose', 'resource-file.uninstall is not supported for browser');
}
},
framework: {
install: function (obj, plugin_dir, project_dir, plugin_id, options) {
events.emit('verbose', 'framework.install is not supported for browser');
},
uninstall: function (obj, project_dir, plugin_id, options) {
events.emit('verbose', 'framework.uninstall is not supported for browser');
}
},
'lib-file': {
install: function (obj, plugin_dir, project_dir, plugin_id, options) {
events.emit('verbose', 'lib-file.install is not supported for browser');
},
uninstall: function (obj, project_dir, plugin_id, options) {
events.emit('verbose', 'lib-file.uninstall is not supported for browser');
}
},
asset: {
install: function (asset, plugin_dir, wwwDest) {
const src = path.join(plugin_dir, asset.src);
const dest = path.join(wwwDest, asset.target);
const destDir = path.parse(dest).dir;
if (destDir !== '' && !fs.existsSync(destDir)) {
fs.mkdirSync(destDir, { recursive: true });
}
if (fs.statSync(src).isDirectory()) {
fs.cpSync(src, dest, { recursive: true, force: true });
} else {
fs.cpSync(src, dest, { force: true });
}
},
uninstall: function (asset, wwwDest, plugin_id) {
fs.rmSync(path.join(wwwDest, asset.target), { recursive: true, force: true });
fs.rmSync(path.join(wwwDest, 'plugins', plugin_id), { recursive: true, force: true });
}
}
};
================================================
FILE: bin/template/cordova/browser_parser.js
================================================
/*
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.
*/
const fs = require('node:fs');
const path = require('node:path');
const CordovaError = require('cordova-common').CordovaError;
const events = require('cordova-common').events;
const FileUpdater = require('cordova-common').FileUpdater;
function dirExists (dir) {
return fs.existsSync(dir) && fs.statSync(dir).isDirectory();
}
function browser_parser (project) {
if (!dirExists(project) || !dirExists(path.join(project, 'cordova'))) {
throw new CordovaError('The provided path "' + project + '" is not a valid browser project.');
}
this.path = project;
}
module.exports = browser_parser;
browser_parser.prototype.www_dir = function () {
return path.join(this.path, 'www');
};
/**
* Logs all file operations via the verbose event stream, indented.
*/
function logFileOp (message) {
events.emit('verbose', ' ' + message);
}
// Replace the www dir with contents of platform_www and app www.
browser_parser.prototype.update_www = function (cordovaProject, opts) {
const platform_www = path.join(this.path, 'platform_www');
const my_www = this.www_dir();
// add cordova www and platform_www to sourceDirs
const sourceDirs = [
path.relative(cordovaProject.root, cordovaProject.locations.www),
path.relative(cordovaProject.root, platform_www)
];
// If project contains 'merges' for our platform, use them as another overrides
const merges_path = path.join(cordovaProject.root, 'merges', 'browser');
if (fs.existsSync(merges_path)) {
events.emit('verbose', 'Found "merges/browser" folder. Copying its contents into the browser project.');
// add merges/browser to sourceDirs
sourceDirs.push(path.join('merges', 'browser'));
}
// targetDir points to browser/www
const targetDir = path.relative(cordovaProject.root, my_www);
events.emit('verbose', 'Merging and updating files from [' + sourceDirs.join(', ') + '] to ' + targetDir);
FileUpdater.mergeAndUpdateDir(sourceDirs, targetDir, { rootDir: cordovaProject.root }, logFileOp);
};
browser_parser.prototype.config_xml = function () {
return path.join(this.path, 'config.xml');
};
browser_parser.prototype.update_project = async function (cfg) {
// Copy munged config.xml to platform www dir
fs.cpSync(this.config_xml(), this.www_dir(), { recursive: true, force: true });
};
================================================
FILE: bin/template/cordova/defaults.xml
================================================
<?xml version='1.0' encoding='utf-8'?>
<!--
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.
-->
<widget id="io.cordova.hellocordova" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
</widget>
================================================
FILE: bin/template/cordova/lib/build.js
================================================
#!/usr/bin/env node
/*
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.
*/
const path = require('node:path');
const check_reqs = require('./check_reqs');
/**
* run
* Creates a zip file int platform/build folder
*/
module.exports.run = function () {
return check_reqs.run();
};
module.exports.help = function () {
console.log('Usage: cordova build browser');
const wwwPath = path.resolve(path.join(__dirname, '../../www'));
console.log("Build will create the packaged app in '" + wwwPath + "'.");
};
================================================
FILE: bin/template/cordova/lib/clean.js
================================================
#!/usr/bin/env node
/*
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.
*/
const fs = require('node:fs');
const path = require('node:path');
const check_reqs = require('./check_reqs');
const platformBuildDir = path.join('platforms', 'browser', 'www');
const run = function () {
// TODO: everything calls check_reqs ... why?
// Check that requirements are (still) met
if (!check_reqs.run()) {
console.error('Please make sure you meet the software requirements in order to clean an browser cordova project');
process.exit(2);
}
try {
if (fs.existsSync(platformBuildDir)) {
fs.rmSync(platformBuildDir, { recursive: true });
}
} catch (err) {
console.log('could not remove ' + platformBuildDir + ' : ' + err.message);
}
};
module.exports.run = run;
// just on the off chance something is still calling cleanProject, we will leave this here for a while
module.exports.cleanProject = function () {
console.log('lib/clean will soon only export a `run` command, please update to not call `cleanProject`.');
return run();
};
================================================
FILE: bin/template/cordova/lib/run.js
================================================
#!/usr/bin/env node
/*
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.
*/
const fs = require('node:fs');
const path = require('node:path');
const url = require('node:url');
const cordovaServe = require('cordova-serve');
module.exports.run = function (args) {
// defaults
args.port = args.port || 8000;
args.target = args.target || 'default'; // make default the system browser
args.noLogOutput = args.silent || false;
const wwwPath = path.join(__dirname, '../../www');
const manifestFilePath = path.resolve(path.join(wwwPath, 'manifest.json'));
let startPage;
// get start page from manifest
if (fs.existsSync(manifestFilePath)) {
try {
const manifest = require(manifestFilePath);
startPage = manifest.start_url;
} catch (err) {
console.log('failed to require manifest ... ' + err);
}
}
const server = cordovaServe();
server.servePlatform('browser', { port: args.port, noServerInfo: true, noLogOutput: args.noLogOutput })
.then(function () {
if (!startPage) {
// failing all else, set the default
startPage = 'index.html';
}
const projectUrl = (new url.URL(`http://localhost:${server.port}/${startPage}`)).href;
console.log('startPage = ' + startPage);
console.log('Static file server running @ ' + projectUrl + '\nCTRL + C to shut down');
return server.launchBrowser({ target: args.target, url: projectUrl });
})
.catch(function (error) {
console.log(error.message || error.toString());
if (server.server) {
server.server.close();
}
});
};
================================================
FILE: bin/template/cordova/version
================================================
#!/usr/bin/env node
/*
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.
*/
// Coho updates this line:
const VERSION = '8.0.0-dev';
console.log(VERSION);
================================================
FILE: bin/template/www/css/index.css
================================================
/*
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;
}
================================================
FILE: bin/template/www/index.html
================================================
<!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>
<meta charset="utf-8" />
<meta name="format-detection" content="telephone=no" />
<meta name="theme-color" content="#2196F3"/>
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
<link rel="stylesheet" type="text/css" href="css/index.css" />
<link rel="manifest" href="manifest.json">
<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>
<script type="text/javascript">
app.initialize();
</script>
</body>
</html>
================================================
FILE: bin/template/www/js/index.js
================================================
/*
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.
*/
const 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 explicity call 'app.receivedEvent(...);'
onDeviceReady: function () {
app.receivedEvent('deviceready');
},
// Update DOM on a Received Event
receivedEvent: function (id) {
const parentElement = document.getElementById(id);
const listeningElement = parentElement.querySelector('.listening');
const receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
console.log('Received Event: ' + id);
}
};
================================================
FILE: bin/template/www/manifest.json
================================================
{
"name": "My App",
"short_name":"My Ap",
"description": "Description of your app from template",
"start_url": "index.html",
"scope":"index.html",
"icons": [{
"src": "img/logo.png",
"sizes": "192x192",
"type": "image/png"
}, {
"src": "img/splash.png",
"sizes": "512x512",
"type": "image/png"
}],
"default_locale": "en",
"display": "standalone",
"background_color":"#FFF",
"theme_color":"#000",
"orientation": "landscape"
}
================================================
FILE: cordova-js-src/confighelper.js
================================================
/*
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.
*/
let config;
function Config (xhr) {
function loadPreferences (xhr) {
const parser = new DOMParser();
const doc = parser.parseFromString(xhr.responseText, 'application/xml');
const preferences = doc.getElementsByTagName('preference');
return Array.prototype.slice.call(preferences);
}
this.xhr = xhr;
this.preferences = loadPreferences(this.xhr);
}
function readConfig (success, error) {
const xhr = new XMLHttpRequest();
if (typeof config !== 'undefined') {
success(config);
}
function fail (msg) {
console.error(msg);
if (error) {
error(msg);
}
}
const xhrStatusChangeHandler = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200 || xhr.status === 304 || xhr.status === 0 /* file:// */) {
config = new Config(xhr);
success(config);
} else {
fail('[Browser][cordova.js][xhrStatusChangeHandler] Could not XHR config.xml: ' + xhr.statusText);
}
}
};
xhr.addEventListener('load', xhrStatusChangeHandler);
try {
xhr.open('get', 'config.xml', true);
xhr.send();
} catch (e) {
fail('[Browser][cordova.js][readConfig] Could not XHR config.xml: ' + JSON.stringify(e));
}
}
/**
* Reads a preference value from config.xml.
* Returns preference value or undefined if it does not exist.
* @param {String} preferenceName Preference name to read */
Config.prototype.getPreferenceValue = function getPreferenceValue (preferenceName) {
const preferenceItem = this.preferences && this.preferences.filter(function (item) {
return item.attributes.name && item.attributes.name.value === preferenceName;
});
if (preferenceItem && preferenceItem[0] && preferenceItem[0].attributes && preferenceItem[0].attributes.value) {
return preferenceItem[0].attributes.value.value;
}
};
exports.readConfig = readConfig;
================================================
FILE: cordova-js-src/exec.js
================================================
/*
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.
*/
/* jslint sloppy:true, plusplus:true */
/* global require, module, console */
const cordova = require('cordova');
const execProxy = require('cordova/exec/proxy');
/**
* Execute a cordova command. It is up to the native side whether this action
* is synchronous or asynchronous. The native side can return:
* Synchronous: PluginResult object as a JSON string
* Asynchronous: Empty string ""
* If async, the native side will cordova.callbackSuccess or cordova.callbackError,
* depending upon the result of the action.
*
* @param {Function} success The success callback
* @param {Function} fail The fail callback
* @param {String} service The name of the service to use
* @param {String} action Action to be run in cordova
* @param {String[]} [args] Zero or more arguments to pass to the method
*/
module.exports = function (success, fail, service, action, args) {
const proxy = execProxy.get(service, action);
args = args || [];
if (proxy) {
const callbackId = service + cordova.callbackId++;
if (typeof success === 'function' || typeof fail === 'function') {
cordova.callbacks[callbackId] = { success, fail };
}
try {
// callbackOptions param represents additional optional parameters command could pass back, like keepCallback or
// custom callbackId, for example {callbackId: id, keepCallback: true, status: cordova.callbackStatus.JSON_EXCEPTION }
const onSuccess = function (result, callbackOptions) {
callbackOptions = callbackOptions || {};
let callbackStatus;
// covering both undefined and null.
// strict null comparison was causing callbackStatus to be undefined
// and then no callback was called because of the check in cordova.callbackFromNative
// see CB-8996 Mobilespec app hang on windows
if (callbackOptions.status !== undefined && callbackOptions.status !== null) {
callbackStatus = callbackOptions.status;
} else {
callbackStatus = cordova.callbackStatus.OK;
}
cordova.callbackSuccess(callbackOptions.callbackId || callbackId,
{
status: callbackStatus,
message: result,
keepCallback: callbackOptions.keepCallback || false
});
};
const onError = function (err, callbackOptions) {
callbackOptions = callbackOptions || {};
let callbackStatus;
// covering both undefined and null.
// strict null comparison was causing callbackStatus to be undefined
// and then no callback was called because of the check in cordova.callbackFromNative
// note: status can be 0
if (callbackOptions.status !== undefined && callbackOptions.status !== null) {
callbackStatus = callbackOptions.status;
} else {
callbackStatus = cordova.callbackStatus.OK;
}
cordova.callbackError(callbackOptions.callbackId || callbackId,
{
status: callbackStatus,
message: err,
keepCallback: callbackOptions.keepCallback || false
});
};
proxy(onSuccess, onError, args);
} catch (e) {
console.log('Exception calling native with command :: ' + service + ' :: ' + action + ' ::exception=' + e);
}
} else {
console.log('Error: exec proxy not found for :: ' + service + ' :: ' + action);
if (typeof fail === 'function') {
fail('Missing Command Error');
}
}
};
================================================
FILE: cordova-js-src/platform.js
================================================
/*
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.
*/
module.exports = {
id: 'browser',
cordovaVersion: '4.2.0', // cordova-js
bootstrap: function () {
const modulemapper = require('cordova/modulemapper');
const channel = require('cordova/channel');
modulemapper.clobbers('cordova/exec/proxy', 'cordova.commandProxy');
channel.onNativeReady.fire();
document.addEventListener('visibilitychange', function () {
if (document.hidden) {
channel.onPause.fire();
} else {
channel.onResume.fire();
}
});
// End of bootstrap
}
};
================================================
FILE: eslint.config.js
================================================
/*
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.
*/
const { defineConfig, globalIgnores } = require('eslint/config');
const nodeConfig = require('@cordova/eslint-config/node');
const nodeTestConfig = require('@cordova/eslint-config/node-tests');
const browserConfig = require('@cordova/eslint-config/browser');
module.exports = defineConfig([
globalIgnores([
'**/coverage/',
'bin/template/www/cordova.js'
]),
...nodeConfig.map(config => ({
files: [
'**/*.js',
'bin/template/cordova/version'
],
...config
})),
...nodeTestConfig.map(config => ({
files: ['spec/**/*.js'],
...config
})),
...browserConfig.map(config => ({
files: [
'cordova-js-src/**/*.js',
'bin/template/www/**/*.js'
],
...config,
languageOptions: {
...(config?.languageOptions || {}),
globals: {
...(config.languageOptions?.globals || {}),
require: 'readonly',
module: 'readonly'
}
}
}))
]);
================================================
FILE: licence_checker.yml
================================================
# 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.
# Empty for the release audit workflow.
# The `license-config` is required even if there are no custom configs
================================================
FILE: package.json
================================================
{
"name": "cordova-browser",
"version": "8.0.0-dev",
"description": "cordova-browser release",
"main": "bin/template/cordova/Api.js",
"repository": "github:apache/cordova-browser",
"bugs": "https://github.com/apache/cordova-browser/issues",
"keywords": [
"cordova",
"browser",
"apache"
],
"scripts": {
"prepare": "cordova-js build > bin/template/www/cordova.js",
"cover": "c8 jasmine",
"lint": "eslint .",
"lint:fix": "npm run lint -- --fix",
"jasmine": "jasmine",
"test": "npm run lint && npm run cover"
},
"dependencies": {
"cordova-common": "^6.0.0",
"cordova-serve": "^4.0.1"
},
"devDependencies": {
"@cordova/eslint-config": "^6.0.1",
"c8": "^11.0.0",
"cordova-js": "^6.1.0",
"jasmine": "^6.1.0",
"tmp": "^0.2.5"
},
"author": "Apache Software Foundation",
"license": "Apache-2.0",
"engines": {
"node": "^20.17.0 || >=22.9.0"
},
"c8": {
"include": [
"bin/lib/**",
"bin/templates/cordova/**"
],
"reporter": [
"lcov",
"text"
]
}
}
================================================
FILE: spec/browser_handler.spec.js
================================================
/*
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.
*/
const browser_handler = require('../bin/template/cordova/browser_handler');
const fs = require('node:fs');
const path = require('node:path');
describe('Asset install tests', function () {
let fsstatMock;
const asset = {
itemType: 'asset',
src: path.join('someSrc', 'ServiceWorker.js'),
target: 'ServiceWorker.js'
};
const assetWithPath = {
itemType: 'asset',
src: path.join('someSrc', 'reformat.js'),
target: path.join('js', 'deepdown', 'reformat.js')
};
const assetWithPath2 = {
itemType: 'asset',
src: path.join('someSrc', 'reformat.js'),
target: path.join('js', 'deepdown', 'reformat2.js')
};
const plugin_dir = 'pluginDir';
const wwwDest = 'dest';
it('if src is a directory, should be called with cpSync recursive force', function () {
const cp = spyOn(fs, 'cpSync').and.callFake(() => {});
fsstatMock = {
isDirectory: function () {
return true;
}
};
spyOn(fs, 'statSync').and.returnValue(fsstatMock);
browser_handler.asset.install(asset, plugin_dir, wwwDest);
expect(cp).toHaveBeenCalledWith(jasmine.any(String), path.join('dest', asset.target), {
recursive: true,
force: true
});
});
it('if src is not a directory and asset has no path, should be called with cp, -f', function () {
const cp = spyOn(fs, 'cpSync').and.callFake(() => {});
const mkdir = spyOn(fs, 'mkdirSync');
spyOn(fs, 'existsSync').and.returnValue(true);
fsstatMock = {
isDirectory: function () {
return false;
}
};
spyOn(fs, 'statSync').and.returnValue(fsstatMock);
browser_handler.asset.install(asset, plugin_dir, wwwDest);
expect(mkdir).not.toHaveBeenCalled();
expect(cp).toHaveBeenCalledWith(path.join('pluginDir', asset.src), path.join('dest', asset.target), {
force: true
});
});
it('if src is not a directory and asset has a path, should be called with cp, -f', function () {
/*
Test that a dest directory gets created if it does not exist
*/
const cp = spyOn(fs, 'cpSync').and.callFake(() => {});
const mkdir = spyOn(fs, 'mkdirSync');
fsstatMock = {
isDirectory: function () {
return false;
}
};
spyOn(fs, 'statSync').and.returnValue(fsstatMock);
browser_handler.asset.install(assetWithPath, plugin_dir, wwwDest);
expect(mkdir).toHaveBeenCalledWith(path.join('dest', 'js', 'deepdown'), {
recursive: true
});
expect(cp).toHaveBeenCalledWith(path.join('pluginDir', assetWithPath.src), path.join('dest', assetWithPath.target), {
force: true
});
/*
Now test that a second call to the same dest folder skips mkdir because the first asset call should have created it.
*/
spyOn(fs, 'existsSync').and.returnValue(true);
browser_handler.asset.install(assetWithPath2, plugin_dir, wwwDest);
expect(mkdir.calls.count()).toBe(1); // not called again
});
});
================================================
FILE: spec/create.spec.js
================================================
/*
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.
*/
const fs = require('node:fs');
const path = require('node:path');
const tmp = require('tmp');
const create = require('../bin/lib/create');
tmp.setGracefulCleanup();
function makeTempDir () {
const tempdir = tmp.dirSync({ unsafeCleanup: true });
return path.join(tempdir.name, `cordova-browser-create-test-${Date.now()}`);
}
/**
* Verifies that some of the project file exists. Not all will be tested.
* E.g. App's resource directory, xcodeproj, xcworkspace, and CordovaLib.
*
* @param {String} tmpDir
* @param {String} projectName
*/
function verifyProjectFiles (tmpDir, projectName) {
expect(fs.existsSync(path.join(tmpDir, 'www'))).toBe(true);
expect(fs.existsSync(path.join(tmpDir, 'platform_www'))).toBe(true);
}
/**
* Runs various project creation checks.
*
* @param {String} tmpDir
* @param {String} packageName
* @param {String} projectName
* @returns {Promise}
*/
async function verifyCreatedProject (tmpDir, packageName, projectName) {
await create.createProject(tmpDir, packageName, projectName)
.then(() => verifyProjectFiles(tmpDir, projectName));
}
function verifyManifestFiles (tmpDir, projectName) {
const manifestPath = path.join(tmpDir, 'platform_www/manifest.json');
expect(fs.existsSync(manifestPath)).toBe(true);
const manifestObj = require(manifestPath);
expect(manifestObj.name).toBe(projectName);
// start_url
expect(manifestObj.start_url).toBe('index.html');
// display
expect(manifestObj.display).toBe('standalone');
// description
expect(manifestObj.description).toBeDefined();
// background_color
expect(manifestObj.background_color).toBeDefined();
// theme_color
expect(manifestObj.theme_color).toBeDefined();
// scope
expect(manifestObj.scope).toBeDefined();
// orientation
expect(manifestObj.orientation).toBeDefined();
// icons
expect(manifestObj.icons).toBeDefined();
expect(Array.isArray(manifestObj.icons)).toBe(true);
expect(manifestObj.icons.length).toBeDefined();
expect(manifestObj.icons.length).toBeGreaterThan(0);
}
describe('create', () => {
let tmpDir;
beforeEach(function () {
tmpDir = makeTempDir();
});
afterEach(() => {
fs.rmSync(tmpDir, { recursive: true, force: true });
});
it('create project with ascii name, no spaces', function () {
const projectName = 'testcreate';
const packageName = 'com.test.app1';
return verifyCreatedProject(tmpDir, packageName, projectName);
});
it('create project with ascii name, and spaces', function () {
const projectName = 'test create';
const packageName = 'com.test.app2';
return verifyCreatedProject(tmpDir, packageName, projectName);
});
it('create project with unicode name, no spaces', function () {
const projectName = '応応応応用用用用';
const packageName = 'com.test.app3';
return verifyCreatedProject(tmpDir, packageName, projectName);
});
it('create project with unicode name, and spaces', function () {
const projectName = '応応応応 用用用用';
const packageName = 'com.test.app4';
return verifyCreatedProject(tmpDir, packageName, projectName);
});
it('create project with ascii+unicode name, no spaces', function () {
const projectName = '応応応応hello用用用用';
const packageName = 'com.test.app5';
return verifyCreatedProject(tmpDir, packageName, projectName);
});
it('create project with ascii+unicode name, and spaces', function () {
const projectName = '応応応応 hello 用用用用';
const packageName = 'com.test.app6';
return verifyCreatedProject(tmpDir, packageName, projectName);
});
it('should have manifest.json', function () {
const projectName = 'testcreate';
const packageName = 'com.test.app1';
return verifyCreatedProject(tmpDir, packageName, projectName)
.then(() => verifyManifestFiles(tmpDir, projectName));
});
});
================================================
FILE: spec/projectApi.spec.js
================================================
/*
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.
*/
const path = require('node:path');
const EventEmitter = require('node:events');
const Api = require('../bin/template/cordova/Api');
const create = require('../bin/lib/create');
describe('can get the Api', function () {
it('should be defined', function () {
expect(Api).toBeDefined();
});
it('should export static createPlatform function', function () {
expect(Api.createPlatform).toBeDefined();
expect(typeof Api.createPlatform).toBe('function');
});
it('should export static updatePlatform function', function () {
expect(Api.updatePlatform).toBeDefined();
expect(typeof Api.updatePlatform).toBe('function');
});
describe('static createPlatform method', () => {
it('should create a platform app and return the Api', () => {
// Trick function under test to load our Api after calling createProject
const testDir = path.join(__dirname, '../bin/template');
const testOpts = {};
spyOn(create, 'createProject').and.returnValue(Promise.resolve());
return Api.createPlatform(testDir, null, testOpts, new EventEmitter()).then(api => {
expect(api).toBeInstanceOf(Api);
expect(create.createProject).toHaveBeenCalledWith(
testDir, jasmine.any(String), jasmine.any(String), testOpts
);
});
});
});
});
describe('project level Api', function () {
const testApi = new Api();
it('can be created', function () {
expect(testApi).toBeDefined();
});
it('has a requirements method', function () {
expect(testApi.requirements).toBeDefined();
expect(typeof testApi.requirements).toBe('function');
});
it('has a clean method', function () {
expect(testApi.clean).toBeDefined();
expect(typeof testApi.clean).toBe('function');
});
it('has a run method', function () {
expect(testApi.run).toBeDefined();
expect(typeof testApi.run).toBe('function');
});
it('has a build method', function () {
expect(testApi.build).toBeDefined();
expect(typeof testApi.build).toBe('function');
});
it('has a removePlugin method', function () {
expect(testApi.removePlugin).toBeDefined();
expect(typeof testApi.removePlugin).toBe('function');
});
it('has a addPlugin method', function () {
expect(testApi.addPlugin).toBeDefined();
expect(typeof testApi.addPlugin).toBe('function');
});
it('has a prepare method', function () {
expect(testApi.prepare).toBeDefined();
expect(typeof testApi.prepare).toBe('function');
});
it('has a getPlatformInfo method', function () {
expect(testApi.getPlatformInfo).toBeDefined();
expect(typeof testApi.getPlatformInfo).toBe('function');
});
});
// Static methods
// Static method: createPlatform
// returns promise fulfilled with Api
// emits error using provided emmitter on error
// Static method: updatePlatform
// returns a promise fulfilled with an Api
// emits error using provided emmitter on error
// Instance methods
// requirements, clean, run, build, removePlugin, addPlugin, prepare, getPlatformInfo
================================================
FILE: spec/support/jasmine.json
================================================
{
"spec_dir": "spec",
"spec_files": [
"*[sS]pec.js"
],
"helpers": [
],
"stopSpecOnExpectationFailure": false,
"random": false
}
gitextract_zo_vyim0/
├── .asf.yaml
├── .gitattributes
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── BUG_REPORT.md
│ │ ├── FEATURE_REQUEST.md
│ │ └── SUPPORT_QUESTION.md
│ ├── ISSUE_TEMPLATE.md
│ ├── PULL_REQUEST_TEMPLATE.md
│ └── workflows/
│ ├── ci.yml
│ └── release-audit.yml
├── .gitignore
├── .npmignore
├── .npmrc
├── .ratignore
├── CONTRIBUTING.md
├── LICENSE
├── NOTICE
├── README.md
├── RELEASENOTES.md
├── bin/
│ ├── lib/
│ │ ├── check_reqs.js
│ │ ├── create.js
│ │ └── update.js
│ └── template/
│ ├── cordova/
│ │ ├── Api.js
│ │ ├── browser_handler.js
│ │ ├── browser_parser.js
│ │ ├── defaults.xml
│ │ ├── lib/
│ │ │ ├── build.js
│ │ │ ├── clean.js
│ │ │ └── run.js
│ │ └── version
│ └── www/
│ ├── css/
│ │ └── index.css
│ ├── index.html
│ ├── js/
│ │ └── index.js
│ └── manifest.json
├── cordova-js-src/
│ ├── confighelper.js
│ ├── exec.js
│ └── platform.js
├── eslint.config.js
├── licence_checker.yml
├── package.json
└── spec/
├── browser_handler.spec.js
├── create.spec.js
├── projectApi.spec.js
└── support/
└── jasmine.json
SYMBOL INDEX (15 symbols across 5 files)
FILE: bin/lib/create.js
constant ROOT (line 24) | const ROOT = path.join(__dirname, '..', '..');
FILE: bin/template/cordova/Api.js
constant PLATFORM_NAME (line 40) | const PLATFORM_NAME = 'browser';
function setupEvents (line 42) | function setupEvents (externalEventEmitter) {
function logFileOp (line 58) | function logFileOp (message) {
function dirExists (line 62) | function dirExists (dir) {
function Api (line 66) | function Api (platform, platformRootDir, events) {
FILE: bin/template/cordova/browser_parser.js
function dirExists (line 26) | function dirExists (dir) {
function browser_parser (line 30) | function browser_parser (project) {
function logFileOp (line 46) | function logFileOp (message) {
FILE: cordova-js-src/confighelper.js
function Config (line 22) | function Config (xhr) {
function readConfig (line 35) | function readConfig (success, error) {
FILE: spec/create.spec.js
function makeTempDir (line 27) | function makeTempDir () {
function verifyProjectFiles (line 39) | function verifyProjectFiles (tmpDir, projectName) {
function verifyCreatedProject (line 52) | async function verifyCreatedProject (tmpDir, packageName, projectName) {
function verifyManifestFiles (line 57) | function verifyManifestFiles (tmpDir, projectName) {
Condensed preview — 43 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (125K chars).
[
{
"path": ".asf.yaml",
"chars": 1002,
"preview": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements. See the NOTICE f"
},
{
"path": ".gitattributes",
"chars": 1909,
"preview": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements. See the NOTICE f"
},
{
"path": ".github/ISSUE_TEMPLATE/BUG_REPORT.md",
"chars": 995,
"preview": "---\nname: 🐛 Bug Report\nabout: If something isn't working as expected.\n\n---\n\n# Bug Report\n\n## Problem\n\n### What is expect"
},
{
"path": ".github/ISSUE_TEMPLATE/FEATURE_REQUEST.md",
"chars": 598,
"preview": "---\nname: 🚀 Feature Request\nabout: A suggestion for a new functionality\n\n---\n\n# Feature Request\n\n## Motivation Behind Fe"
},
{
"path": ".github/ISSUE_TEMPLATE/SUPPORT_QUESTION.md",
"chars": 959,
"preview": "---\nname: 💬 Support Question\nabout: If you have a question, please check out our Slack or StackOverflow!\n\n---\n\n<!-------"
},
{
"path": ".github/ISSUE_TEMPLATE.md",
"chars": 1191,
"preview": "<!--\nPlease have a look at the issue templates you get when you click \"New issue\" in the GitHub UI.\nWe very much prefer "
},
{
"path": ".github/PULL_REQUEST_TEMPLATE.md",
"chars": 1118,
"preview": "<!--\nPlease make sure the checklist boxes are all checked before submitting the PR. The checklist is intended as a quick"
},
{
"path": ".github/workflows/ci.yml",
"chars": 2573,
"preview": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements. See the NOTICE f"
},
{
"path": ".github/workflows/release-audit.yml",
"chars": 1627,
"preview": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements. See the NOTICE f"
},
{
"path": ".gitignore",
"chars": 996,
"preview": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements. See the NOTICE f"
},
{
"path": ".npmignore",
"chars": 994,
"preview": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements. See the NOTICE f"
},
{
"path": ".npmrc",
"chars": 822,
"preview": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements. See the NOTICE f"
},
{
"path": ".ratignore",
"chars": 824,
"preview": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements. See the NOTICE f"
},
{
"path": "CONTRIBUTING.md",
"chars": 1375,
"preview": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements. See the N"
},
{
"path": "LICENSE",
"chars": 11358,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "NOTICE",
"chars": 168,
"preview": "Apache Cordova\nCopyright 2012-2015 The Apache Software Foundation\n\nThis product includes software developed at\nThe Apach"
},
{
"path": "README.md",
"chars": 1623,
"preview": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements. See the N"
},
{
"path": "RELEASENOTES.md",
"chars": 8214,
"preview": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements. See the N"
},
{
"path": "bin/lib/check_reqs.js",
"chars": 1038,
"preview": "#!/usr/bin/env node\n\n/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license a"
},
{
"path": "bin/lib/create.js",
"chars": 3675,
"preview": "#!/usr/bin/env node\n\n/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license a"
},
{
"path": "bin/lib/update.js",
"chars": 1812,
"preview": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements. See the N"
},
{
"path": "bin/template/cordova/Api.js",
"chars": 23018,
"preview": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements. See the N"
},
{
"path": "bin/template/cordova/browser_handler.js",
"chars": 6262,
"preview": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements. See the N"
},
{
"path": "bin/template/cordova/browser_parser.js",
"chars": 3183,
"preview": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements. See the N"
},
{
"path": "bin/template/cordova/defaults.xml",
"chars": 1008,
"preview": "<?xml version='1.0' encoding='utf-8'?>\n<!--\n Licensed to the Apache Software Foundation (ASF) under one\n or more c"
},
{
"path": "bin/template/cordova/lib/build.js",
"chars": 1288,
"preview": "#!/usr/bin/env node\n\n/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license a"
},
{
"path": "bin/template/cordova/lib/clean.js",
"chars": 1873,
"preview": "#!/usr/bin/env node\n\n/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license a"
},
{
"path": "bin/template/cordova/lib/run.js",
"chars": 2511,
"preview": "#!/usr/bin/env node\n\n/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license a"
},
{
"path": "bin/template/cordova/version",
"chars": 920,
"preview": "#!/usr/bin/env node\n\n/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license a"
},
{
"path": "bin/template/www/css/index.css",
"chars": 3733,
"preview": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements. See the N"
},
{
"path": "bin/template/www/index.html",
"chars": 1885,
"preview": "<!DOCTYPE html>\n<!--\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agre"
},
{
"path": "bin/template/www/js/index.js",
"chars": 1940,
"preview": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements. See the N"
},
{
"path": "bin/template/www/manifest.json",
"chars": 472,
"preview": "{\n \"name\": \"My App\",\n \"short_name\":\"My Ap\",\n \"description\": \"Description of your app from template\",\n \"start_url\": \""
},
{
"path": "cordova-js-src/confighelper.js",
"chars": 2828,
"preview": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements. See the N"
},
{
"path": "cordova-js-src/exec.js",
"chars": 4741,
"preview": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements. See the N"
},
{
"path": "cordova-js-src/platform.js",
"chars": 1428,
"preview": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements. See the N"
},
{
"path": "eslint.config.js",
"chars": 1885,
"preview": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements. See the N"
},
{
"path": "licence_checker.yml",
"chars": 897,
"preview": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements. See the NOTICE f"
},
{
"path": "package.json",
"chars": 1081,
"preview": "{\n \"name\": \"cordova-browser\",\n \"version\": \"8.0.0-dev\",\n \"description\": \"cordova-browser release\",\n \"main\": \"bin/temp"
},
{
"path": "spec/browser_handler.spec.js",
"chars": 4058,
"preview": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements. See the N"
},
{
"path": "spec/create.spec.js",
"chars": 4834,
"preview": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements. See the N"
},
{
"path": "spec/projectApi.spec.js",
"chars": 4082,
"preview": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements. See the N"
},
{
"path": "spec/support/jasmine.json",
"chars": 160,
"preview": "{\n \"spec_dir\": \"spec\",\n \"spec_files\": [\n \t\"*[sS]pec.js\"\n ],\n \"helpers\": [\n ],\n \"stopSpecOnExpectati"
}
]
About this extraction
This page contains the full source code of the apache/cordova-browser GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 43 files (116.2 KB), approximately 28.0k tokens, and a symbol index with 15 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.