diff --git a/config.xml b/config.xml index 876755b160677f589e6ebef96c48d81190443b3d..5900c5d319bee356ea13ef7244d72d2df72bc843 100644 --- a/config.xml +++ b/config.xml @@ -48,20 +48,18 @@ <feature name="MiniSodium"> <param name="android-package" onload="true" value="me.lockate.plugins.MiniSodium" /> </feature> + <feature name="Custom URL scheme"> + <param name="id" value="cordova-plugin-customurlscheme" /> + <param name="url" value="https://github.com/EddyVerbruggen/Custom-URL-scheme.git" /> + <variable name="URL_SCHEME" value="june" /> + </feature> <platform name="android"> <preference name="AndroidXEnabled" value="true" /> <preference name="cdvMinSdkVersion" value="16" /> <preference name="cdvCompileSdkVersion" value="29" /> <preference name="cdvBuildToolsVersion" value="29.0.2" /> - <hook src="scripts/hooks/before_prepare/061_copy_build_extras.js" type="before_prepare" /> - <hook src="scripts/hooks/after_prepare/010_add_platform_class.js" type="after_prepare" /> - <hook src="scripts/hooks/after_prepare/021_template_cache.js" type="after_prepare" /> - <hook src="scripts/hooks/after_prepare/022_translate.js" type="after_prepare" /> - <hook src="scripts/hooks/after_prepare/040_useref.js" type="after_prepare" /> - <hook src="scripts/hooks/after_prepare/040_useref.js" type="after_prepare" /> - <hook src="scripts/hooks/after_prepare/050_clean_unused_directories.js" type="after_prepare" /> - <hook src="scripts/hooks/after_prepare/061_copy_build_extras.js" type="after_prepare" /> - <hook src="scripts/hooks/before_compile/060_prepare_android_manifest.js" type="after_prepare" /> + <hook src="scripts/hooks/before_prepare.js" type="before_prepare" /> + <hook src="scripts/hooks/after_prepare.js" type="after_prepare" /> <icon density="ldpi" src="resources/android/icon/drawable-ldpi-icon.png" /> <icon density="mdpi" src="resources/android/icon/drawable-mdpi-icon.png" /> <icon density="hdpi" src="resources/android/icon/drawable-hdpi-icon.png" /> @@ -168,9 +166,6 @@ </plugin> <plugin name="cordova-plugin-customurlscheme" spec="^5.0.2"> <variable name="URL_SCHEME" value="june" /> - <variable name="ANDROID_SCHEME" value=" " /> - <variable name="ANDROID_HOST" value=" " /> - <variable name="ANDROID_PATHPREFIX" value="/" /> </plugin> <plugin name="ionic-plugin-keyboard" spec="^2.2.1" /> <plugin name="cordova-plugin-androidx" spec="^1.0.2" /> diff --git a/gulpfile.js b/gulpfile.js index f1b30e3a4f3262cbd81e29becc6170928a0534be..be0a2d265aaeb8f5dd66902344d5ea6ae491bad0 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,12 +1,14 @@ 'use strict'; const gulp = require('gulp'), + path = require("path"), sass = require('gulp-sass'), cleanCss = require('gulp-clean-css'), base64 = require('gulp-base64-v2'), rename = require('gulp-rename'), ngConstant = require('gulp-ng-constant'), fs = require("fs"), + es = require('event-stream'), header = require('gulp-header'), footer = require('gulp-footer'), removeCode = require('gulp-remove-code'), @@ -33,7 +35,8 @@ const gulp = require('gulp'), colors = require('ansi-colors'), argv = require('yargs').argv, sriHash = require('gulp-sri-hash'), - sort = require('gulp-sort'); + sort = require('gulp-sort'), + gulpfile = this; // Workaround because @ioni/v1-toolkit use gulp v3.9.2 instead of gulp v4 let jsonlint; @@ -59,6 +62,25 @@ const paths = { ng_annotate_plugin: ['./www/plugins/*/**/*.js', '!./www/plugins/*/js/vendor/*.js'] }; +const uglifyOptions = { + toplevel: true, + warnings: true, + mangle: { + reserved: ['qrcode', 'Base58'] + }, + compress: { + global_defs: { + "@console.log": "alert" + }, + passes: 2 + }, + output: { + beautify: false, + preamble: "/* minified */", + max_line_len: 120000 + } +}; + function appAndPluginWatch(done) { log(colors.green('Watching source files...')); @@ -311,14 +333,14 @@ function webCopyFiles() { logger: m => log(colors.grey(m)) }; - var tmpPath = './dist/web/www'; + var targetPath = './dist/web/www'; return merge( // Copy Js (and remove unused code) gulp.src('./www/js/**/*.js') .pipe(debug(debugOptions)) .pipe(removeCode({"no-device": true})) .pipe(jshint()) - .pipe(gulp.dest(tmpPath + '/js')), + .pipe(gulp.dest(targetPath + '/js')), // Copy HTML templates (and remove unused code) gulp.src('./www/templates/**/*.html') @@ -326,7 +348,7 @@ function webCopyFiles() { .pipe(removeHtml('.hidden-no-device')) .pipe(removeHtml('[remove-if][remove-if="no-device"]')) .pipe(htmlmin(htmlminOptions)) - .pipe(gulp.dest(tmpPath + '/templates')), + .pipe(gulp.dest(targetPath + '/templates')), // Copy index.html (and remove unused code) gulp.src('./www/index.html') @@ -334,7 +356,7 @@ function webCopyFiles() { .pipe(removeHtml('.hidden-no-device')) .pipe(removeHtml('[remove-if][remove-if="no-device"]')) .pipe(htmlmin(/*no options, to keep comments*/)) - .pipe(gulp.dest(tmpPath)), + .pipe(gulp.dest(targetPath)), // Copy API index.html gulp.src('./www/api/index.html') @@ -342,17 +364,17 @@ function webCopyFiles() { .pipe(removeHtml('.hidden-no-device')) .pipe(removeHtml('[remove-if][remove-if="no-device"]')) .pipe(htmlmin()) - .pipe(gulp.dest(tmpPath + '/api')), + .pipe(gulp.dest(targetPath + '/api')), // Copy fonts gulp.src('./www/fonts/**/*.*') .pipe(debug(debugOptions)) - .pipe(gulp.dest(tmpPath + '/fonts')), + .pipe(gulp.dest(targetPath + '/fonts')), // Copy CSS gulp.src('./www/css/**/*.*') .pipe(debug(debugOptions)) - .pipe(gulp.dest(tmpPath + '/css')), + .pipe(gulp.dest(targetPath + '/css')), // Copy i18n gulp.src('./www/i18n/locale-*.json') @@ -361,68 +383,68 @@ function webCopyFiles() { .pipe(sort()) .pipe(ngTranslate({standalone:true, module: 'cesium.translations'})) .pipe(debug(debugOptions)) - .pipe(gulp.dest(tmpPath + '/js')), + .pipe(gulp.dest(targetPath + '/js')), // Copy img gulp.src('./www/img/**/*.*') .pipe(debug(debugOptions)) - .pipe(gulp.dest(tmpPath + '/img')), + .pipe(gulp.dest(targetPath + '/img')), // Copy manifest.json gulp.src('./www/manifest.json') .pipe(debug(debugOptions)) - .pipe(gulp.dest(tmpPath)), + .pipe(gulp.dest(targetPath)), // Copy lib (JS, CSS and fonts) gulp.src(['./www/lib/**/*.js', './www/lib/**/*.css', './www/lib/**/fonts/**/*.*']) .pipe(debug(debugOptions)) - .pipe(gulp.dest(tmpPath + '/lib')), + .pipe(gulp.dest(targetPath + '/lib')), // Copy license into HTML gulp.src('./www/license/*.md') .pipe(markdown()) .pipe(header('<html><header><meta charset="utf-8"></header><body>')) .pipe(footer('</body></html>')) - .pipe(gulp.dest(tmpPath + '/license')), + .pipe(gulp.dest(targetPath + '/license')), // Copy license into txt gulp.src('./www/license/*.md') .pipe(header('\ufeff')) // Need BOM character for UTF-8 files .pipe(rename({ extname: '.txt' })) - .pipe(gulp.dest(tmpPath + '/license')) + .pipe(gulp.dest(targetPath + '/license')) ); } function webNgTemplate() { - var tmpPath = './dist/web/www'; - return gulp.src(tmpPath + '/templates/**/*.html') + var targetPath = './dist/web/www'; + return gulp.src(targetPath + '/templates/**/*.html') .pipe(sort()) .pipe(templateCache({ standalone:true, module:"cesium.templates", root: "templates/" })) - .pipe(gulp.dest(tmpPath + '/dist/dist_js/app')); + .pipe(gulp.dest(targetPath + '/dist/dist_js/app')); } function webAppNgAnnotate() { - var tmpPath = './dist/web/www'; + var targetPath = './dist/web/www'; var jsFilter = filter(["**/*.js", "!**/vendor/*"]); - return gulp.src(tmpPath + '/js/**/*.js') + return gulp.src(targetPath + '/js/**/*.js') .pipe(jsFilter) .pipe(ngAnnotate({single_quotes: true})) - .pipe(gulp.dest(tmpPath + '/dist/dist_js/app')); + .pipe(gulp.dest(targetPath + '/dist/dist_js/app')); } function webPluginCopyFiles() { - const tmpPath = './dist/web/www'; + const targetPath = './dist/web/www'; return merge( // Copy Js (and remove unused code) gulp.src('./www/plugins/**/*.js') .pipe(removeCode({"no-device": true})) .pipe(jshint()) - .pipe(gulp.dest(tmpPath + '/plugins')), + .pipe(gulp.dest(targetPath + '/plugins')), // Copy HTML templates (and remove unused code) gulp.src('./www/plugins/**/*.html') @@ -430,7 +452,7 @@ function webPluginCopyFiles() { .pipe(removeHtml('.hidden-no-device')) .pipe(removeHtml('[remove-if][remove-if="no-device"]')) .pipe(htmlmin()) - .pipe(gulp.dest(tmpPath + '/plugins')), + .pipe(gulp.dest(targetPath + '/plugins')), // Transform i18n into JS gulp.src(paths.ng_translate_plugin) @@ -438,43 +460,43 @@ function webPluginCopyFiles() { .pipe(jsonlint.reporter()) .pipe(sort()) .pipe(ngTranslate({standalone:true, module: 'cesium.plugins.translations'})) - .pipe(gulp.dest(tmpPath + '/dist/dist_js/plugins')), + .pipe(gulp.dest(targetPath + '/dist/dist_js/plugins')), // Copy plugin CSS gulp.src(paths.css_plugin) - .pipe(gulp.dest(tmpPath + '/dist/dist_css/plugins')), + .pipe(gulp.dest(targetPath + '/dist/dist_css/plugins')), // Copy Leaflet images - pluginLeafletImages(tmpPath + '/img'), + pluginLeafletImages(targetPath + '/img'), // Copy Leaflet CSS gulp.src('./www/css/**/leaflet.*') - .pipe(gulp.dest(tmpPath + '/css')) + .pipe(gulp.dest(targetPath + '/css')) ); } function webPluginNgTemplate() { - var tmpPath = './dist/web/www'; - return gulp.src(tmpPath + '/plugins/**/*.html') + var targetPath = './dist/web/www'; + return gulp.src(targetPath + '/plugins/**/*.html') .pipe(sort()) .pipe(templateCache({ standalone:true, module:"cesium.plugins.templates", root: "plugins/" })) - .pipe(gulp.dest(tmpPath + '/dist/dist_js/plugins')); + .pipe(gulp.dest(targetPath + '/dist/dist_js/plugins')); } function webPluginNgAnnotate() { - var tmpPath = './dist/web/www'; - return gulp.src(tmpPath + '/plugins/**/*.js') + var targetPath = './dist/web/www'; + return gulp.src(targetPath + '/plugins/**/*.js') .pipe(ngAnnotate({single_quotes: true})) - .pipe(gulp.dest(tmpPath + '/dist/dist_js/plugins')); + .pipe(gulp.dest(targetPath + '/dist/dist_js/plugins')); } -function webUglify(done) { - const wwwPath = './dist/web/www'; +function webUglify() { + const targetPath = './dist/web/www'; const enableUglify = argv.release || argv.uglify || false; const version = JSON.parse(fs.readFileSync('./package.json', 'utf8')).version; @@ -485,27 +507,9 @@ function webUglify(done) { const indexFilter = filter('**/index.html', {restore: true}); const jsFilter = filter(["**/*.js", '!**/config.js'], {restore: true}); const cssFilter = filter("**/*.css", {restore: true}); - const uglifyOptions = { - toplevel: true, - warnings: true, - mangle: { - reserved: ['qrcode', 'Base58'] - }, - compress: { - global_defs: { - "@console.log": "alert" - }, - passes: 2 - }, - output: { - beautify: false, - preamble: "/* minified */", - max_line_len: 120000 - } - }; // Process index.html - return gulp.src(wwwPath + '/index.html') + return gulp.src(targetPath + '/index.html') .pipe(useref({}, lazypipe().pipe(sourcemaps.init, { loadMaps: true }))) // Concatenate with gulp-useref // Process JS @@ -526,34 +530,34 @@ function webUglify(done) { .pipe(sourcemaps.write('maps')) - .pipe(gulp.dest(wwwPath)) - .on('end', done); + .pipe(gulp.dest(targetPath)); + } + else { + return Promise.resolve(); } - - if (done) done(); } function webIntegrity(done) { - const wwwPath = './dist/web/www'; + const targetPath = './dist/web/www'; const enableIntegrity = argv.release || false; if (enableIntegrity) { - log(colors.green('Add integrity hash to <script src> tag...')); + log(colors.green('Create index.integrity.html... ')); // Process index.html return gulp.series( - gulp.src(wwwPath + '/index.html', {base: wwwPath}) + gulp.src(targetPath + '/index.html', {base: targetPath}) // Add an integrity hash .pipe(sriHash()) .pipe(rename({ extname: '.integrity.html' })) - .pipe(gulp.dest(wwwPath)), + .pipe(gulp.dest(targetPath)), - gulp.src(wwwPath + '/index.html', {base: wwwPath}) + gulp.src(targetPath + '/index.html', {base: targetPath}) .pipe(rename({ extname: '.test.html' })) - .pipe(gulp.dest(wwwPath)) + .pipe(gulp.dest(targetPath)) ) .on('end', done); } @@ -562,7 +566,7 @@ function webIntegrity(done) { } function webApiUglify() { - const tmpPath = './dist/web/www'; + const targetPath = './dist/web/www'; const version = JSON.parse(fs.readFileSync('./package.json', 'utf8')).version; const jsFilter = filter(["**/*.js", '!**/config.js'], {restore: true}); @@ -570,27 +574,12 @@ function webApiUglify() { const indexFilter = filter('**/index.html', {restore: true}); // Skip if not required - const enableUglify = argv.release || argv.useref || argv.uglify || false; + const enableUglify = argv.release || argv.uglify || false; if (enableUglify) { log(colors.green('API: Minify JS and CSS files...')); - const uglifyOptions = { - toplevel: true, - warnings: true, - compress: { - global_defs: { - "@console.log": "alert" - }, - passes: 2 - }, - output: { - beautify: false, - preamble: "/* minified */", - max_line_len: 120000 - } - }; // Process api/index.html - return gulp.src(tmpPath + '/*/index.html') + return gulp.src(targetPath + '/*/index.html') .pipe(useref({}, lazypipe().pipe(sourcemaps.init, { loadMaps: true }))) // Concatenate with gulp-useref @@ -617,13 +606,13 @@ function webApiUglify() { .pipe(sourcemaps.write('maps')) - .pipe(gulp.dest(tmpPath)); + .pipe(gulp.dest(targetPath)); } else { log(colors.red('API: Skipping minify JS and CSS files') + colors.grey(' (missing options --release or --uglify)')); - return gulp.src(tmpPath + '/*/index.html') + return gulp.src(targetPath + '/*/index.html') .pipe(useref()) // Concatenate with gulp-useref .pipe(indexFilter) @@ -632,13 +621,14 @@ function webApiUglify() { .pipe(replace("config.js", "../config.js")) .pipe(indexFilter.restore) - .pipe(gulp.dest(tmpPath)); + .pipe(gulp.dest(targetPath)); } } function webCleanUnusedFiles(done) { log(colors.green('Clean unused files...')); - const enableUglify = argv.release || argv.useref || argv.uglify || false; + const targetPath = './dist/web/www'; + const enableUglify = argv.release || argv.uglify || false; const cleanSources = enableUglify; const debugOptions = { title: 'Deleting', @@ -648,25 +638,23 @@ function webCleanUnusedFiles(done) { logger: m => log(colors.grey(m)) }; - const wwwPath = './dist/web/www'; - if (cleanSources) { return merge( // Clean core JS - gulp.src(wwwPath + '/js/**/*.js', {read: false}) + gulp.src(targetPath + '/js/**/*.js', {read: false}) .pipe(debug(debugOptions)) .pipe(clean()), // Clean plugins JS + CSS - gulp.src(wwwPath + '/plugins/**/*.js', {read: false}) + gulp.src(targetPath + '/plugins/**/*.js', {read: false}) .pipe(debug(debugOptions)) .pipe(clean()), - gulp.src(wwwPath + '/plugins/**/*.css', {read: false}) + gulp.src(targetPath + '/plugins/**/*.css', {read: false}) .pipe(debug(debugOptions)) .pipe(clean()), // Unused maps/config.js.map - gulp.src(wwwPath + '/maps/config.js.map', {read: false, allowEmpty: true}) + gulp.src(targetPath + '/maps/config.js.map', {read: false, allowEmpty: true}) .pipe(debug(debugOptions)) .pipe(clean()) ) @@ -812,6 +800,513 @@ function webExtBuildSuccess(done) { if (done) done(); } +function cdvAddPlatformToBodyTag() { + log(colors.green('Add platform CSS class to <body>... ')); + + const projectRoot = argv.root || '.'; + const platform = argv.platform || 'android'; + let wwwPath; + if (platform === 'android') { + wwwPath = path.join(projectRoot, 'platforms', platform, 'app','src','main','assets','www'); + } else { + wwwPath = path.join(projectRoot, 'platforms', platform, 'www'); + } + const indexPath = path.join(wwwPath, 'index.html'); + + // no opening body tag, something's wrong + if (!fs.existsSync(indexPath)) throw new Error('Unable to find the file ' + indexPath +'!'); + + // add the platform class to the body tag + try { + const platformClass = 'platform-' + platform; + const cordovaClass = 'platform-cordova platform-webview'; + + let html = fs.readFileSync(indexPath, 'utf8'); + + // get the body tag + let matches = html && html.match(/<body[^>/]+>/gi) + const bodyTag = matches && matches[0]; + // no opening body tag, something's wrong + if (!bodyTag) throw new Error('No <body> element found in file ' + indexPath); + + if (bodyTag.indexOf(platformClass) > -1) return; // already added + + let newBodyTag = '' + bodyTag; + matches = bodyTag.match(/ class=["|'](.*?)["|']/gi); + const classAttr = matches && matches[0]; + if (classAttr) { + // body tag has existing class attribute, add the classname + let endingQuote = classAttr.substring(classAttr.length - 1); + let newClassAttr = classAttr.substring(0, classAttr.length - 1); + newClassAttr += ' ' + platformClass + ' ' + cordovaClass + endingQuote; + newBodyTag = newBodyTag.replace(classAttr, newClassAttr); + + } else { + // add class attribute to the body tag + newBodyTag = newBodyTag.replace('>', ' class="' + platformClass + ' ' + cordovaClass + '">'); + } + + html = html.replace(bodyTag, newBodyTag); + + fs.writeFileSync(indexPath, html, 'utf8'); + + return Promise.resolve(); + } catch (e) { + return Promise.reject(e); + } +} + +function cdvCopyFiles() { + log(colors.green('Copying files... ')); + + const projectRoot = argv.root || '.'; + const platform = argv.platform || 'android'; + let wwwPath; + if (platform === 'android') { + wwwPath = path.join(projectRoot, 'platforms', platform, 'app','src','main','assets','www'); + } else { + wwwPath = path.join(projectRoot, 'platforms', platform, 'www'); + } + + const jsFilter = filter(["**/*.js", "!**/vendor/*"]); + + return merge( + + // Ng annotate app JS file + gulp.src(wwwPath + '/js/**/*.js') + .pipe(jsFilter) + .pipe(ngAnnotate({single_quotes: true})) + .pipe(gulp.dest(wwwPath + '/dist/dist_js/app')), + + // Ng annotate app JS file + gulp.src(wwwPath + '/plugins/**/*.js') + .pipe(ngAnnotate({single_quotes: true})) + .pipe(gulp.dest(wwwPath + '/dist/dist_js/plugins')), + + // Copy plugin CSS + gulp.src(wwwPath + '/plugins/*/css/**/*.css') + .pipe(gulp.dest(wwwPath + '/dist/dist_css/plugins')), + + // Copy Leaflet images + pluginLeafletImages(wwwPath + '/img'), + + // Copy Leaflet CSS + gulp.src('./www/css/**/leaflet.*') + .pipe(gulp.dest(wwwPath + '/css')) + + ); +} + +function cdvRemoveCode() { + log(colors.green('Removing code... ')); + + const projectRoot = argv.root || '.'; + const platform = argv.platform || 'android'; + let wwwPath; + if (platform === 'android') { + wwwPath = path.join(projectRoot, 'platforms', platform, 'app','src','main','assets','www'); + } else { + wwwPath = path.join(projectRoot, 'platforms', platform, 'www'); + } + + const pluginPath = path.join(wwwPath, 'plugins', 'es'); + + // Compute options {device-<platform>: true} + let removeCodeOptions = {}; + removeCodeOptions[platform] = true; // = {<platform>: true} + + const htmlminOptions = {removeComments: true, collapseWhitespace: true}; + const debugOptions = { + title: 'Processing', + minimal: true, + showFiles: argv.debug || false, + showCount: false, + logger: m => log(colors.grey(m)) + }; + + // Do not remove desktop code for iOS and macOS (support for tablets and desktop macs) + if (platform !== 'ios' && platform !== 'osx') { + // Removing unused code for device... + return merge( + // Remove unused HTML tags + gulp.src(path.join(wwwPath, 'templates', '**', '*.html')) + .pipe(debug(debugOptions)) + .pipe(removeCode({device: true})) + .pipe(removeCode(removeCodeOptions)) + .pipe(removeHtml('.hidden-xs.hidden-sm')) + .pipe(removeHtml('.hidden-device')) + .pipe(removeHtml('[remove-if][remove-if="device"]')) + .pipe(htmlmin(htmlminOptions)) + .pipe(gulp.dest(wwwPath + '/templates')), + + gulp.src(path.join(pluginPath, '**', '*.html')) + .pipe(debug(debugOptions)) + .pipe(removeCode({device: true})) + .pipe(removeCode(removeCodeOptions)) + .pipe(removeHtml('.hidden-xs.hidden-sm')) + .pipe(removeHtml('.hidden-device')) + .pipe(removeHtml('[remove-if][remove-if="device"]')) + .pipe(htmlmin(htmlminOptions)) + .pipe(gulp.dest(pluginPath)), + + gulp.src(path.join(wwwPath, 'index.html')) + .pipe(debug(debugOptions)) + .pipe(removeCode({device: true})) + .pipe(removeCode(removeCodeOptions)) + .pipe(removeHtml('.hidden-xs.hidden-sm')) + .pipe(removeHtml('.hidden-device')) + .pipe(removeHtml('[remove-if][remove-if="device"]')) + .pipe(htmlmin(/*no options, to keep comments*/)) + .pipe(gulp.dest(wwwPath)), + + // Remove unused JS code + add ng annotations + gulp.src(path.join(wwwPath, 'js', '**', '*.js')) + .pipe(debug(debugOptions)) + .pipe(removeCode({device: true})) + .pipe(removeCode(removeCodeOptions)) + .pipe(ngAnnotate({single_quotes: true})) + .pipe(gulp.dest(wwwPath + '/dist/dist_js/app')), + + gulp.src([pluginPath + '/js/**/*.js']) + .pipe(debug(debugOptions)) + .pipe(removeCode({device: true})) + .pipe(removeCode(removeCodeOptions)) + .pipe(ngAnnotate({single_quotes: true})) + .pipe(gulp.dest(wwwPath + '/dist/dist_js/plugins')) + ); + } else { + return merge( + gulp.src(path.join(wwwPath, 'templates', '**', '*.html')) + .pipe(htmlmin(htmlminOptions)) + .pipe(gulp.dest(wwwPath + '/templates')), + + gulp.src(path.join(pluginPath, '**', '*.html')) + .pipe(htmlmin(htmlminOptions)) + .pipe(gulp.dest(pluginPath)), + + gulp.src(path.join(wwwPath, 'index.html')) + .pipe(gulp.dest(wwwPath)), + + gulp.src(path.join(wwwPath, 'js', '**', '*.js')) + .pipe(ngAnnotate({single_quotes: true})) + .pipe(gulp.dest(wwwPath + '/dist/dist_js/app')), + + gulp.src([pluginPath + '/js/**/*.js']) + .pipe(gulp.dest(wwwPath + '/dist/dist_js/plugins')) + ); + } +} + +function cdvNgTemplate() { + log(colors.green('Building template files...')); + + const projectRoot = argv.root || '.'; + const platform = argv.platform || 'android'; + + let wwwPath; + if (platform === 'android') { + wwwPath = path.join(projectRoot, 'platforms', platform, 'app','src','main','assets','www'); + } else { + wwwPath = path.join(projectRoot, 'platforms', platform, 'www'); + } + let distJsPath = path.join(wwwPath, 'dist', 'dist_js', 'app'); + let pluginDistJsPath = path.join(wwwPath, 'dist', 'dist_js', 'plugins'); + const debugOptions = { + title: 'Processing', + minimal: true, + showFiles: argv.debug || false, + showCount: false, + logger: m => log(colors.grey(m)) + }; + + // Concat templates into a JS + return merge( + gulp.src(path.join(wwwPath, 'templates', '**', '*.html')) + .pipe(debug(debugOptions)) + .pipe(templateCache({ + standalone: true, + module: "cesium.templates", + root: "templates/" + })) + .pipe(gulp.dest(distJsPath)), + + gulp.src(path.join(wwwPath, 'plugins', '*', 'templates', '**', '*.html')) + .pipe(debug(debugOptions)) + .pipe(templateCache({ + standalone: true, + module: "cesium.plugins.templates", + root: "plugins/" + })) + .pipe(gulp.dest(pluginDistJsPath)) + ); +} +function cdvNgTranslate() { + log(colors.green('Building translation files...')); + + const projectRoot = argv.root || '.'; + const platform = argv.platform || 'android'; + + let wwwPath; + if (platform === 'android') { + wwwPath = path.join(projectRoot, 'platforms', platform, 'app', 'src', 'main', 'assets', 'www'); + } else { + wwwPath = path.join(projectRoot, 'platforms', platform, 'www'); + } + let distJsPath = path.join(wwwPath, 'dist', 'dist_js', 'app'); + let pluginDistJsPath = path.join(wwwPath, 'dist', 'dist_js', 'plugins'); + + const debugOptions = { + title: 'Processing', + minimal: true, + showFiles: argv.debug || false, + showCount: false, + logger: m => log(colors.grey(m)) + }; + + // Concat templates into a JS + return merge( + gulp.src(wwwPath + '/i18n/locale-*.json') + .pipe(debug(debugOptions)) + .pipe(ngTranslate({standalone: true, module: 'cesium.translations'})) + .pipe(gulp.dest(distJsPath)), + + gulp.src(wwwPath + '/plugins/*/i18n/locale-*.json') + .pipe(debug(debugOptions)) + .pipe(ngTranslate({standalone: true, module: 'cesium.plugins.translations'})) + .pipe(gulp.dest(pluginDistJsPath)) + ); +} + +function cdvUglify() { + + const projectRoot = argv.root || '.'; + const platform = argv.platform || 'android'; + + let wwwPath; + if (platform === 'android') { + wwwPath = path.join(projectRoot, 'platforms', platform, 'app', 'src', 'main', 'assets', 'www'); + } else { + wwwPath = path.join(projectRoot, 'platforms', platform, 'www'); + } + let indexPath = path.join(wwwPath, 'index.html'); + + // Skip if not required + const enableUglify = argv.release || argv.uglify || false; + if (enableUglify) { + log(colors.green('Minify JS and CSS files...')); + + // WARN: uglify only libs, to keep sources readable (need by free repo) + const jsLibFilter = filter(['*/lib/**/*.js', '*/js/vendor/**/*.js'], {restore: true}); // External libs only + const cssFilter = filter("**/*.css", {restore: true}); + const cdvUglifyOptions = { + ...uglifyOptions, + ecma: '5' + }; + const debugOptions = { + title: 'Minifying', + minimal: true, + showFiles: argv.debug || false, + showCount: false, + logger: m => log(colors.grey(m)) + }; + + return gulp.src(indexPath) + .pipe(useref()) // Concatenate with gulp-useref + + // Process JS + .pipe(jsLibFilter) + .pipe(debug(debugOptions)) + .pipe(uglify(cdvUglifyOptions))// Minify javascript sources + .pipe(jsLibFilter.restore) + + // Process CSS + .pipe(cssFilter) + .pipe(debug(debugOptions)) + .pipe(csso()) // Minify any CSS sources + .pipe(cssFilter.restore) + + .pipe(gulp.dest(wwwPath)); + } + else { + log(colors.red('Skipping minify JS and CSS files') + colors.grey(' (missing options --release or --uglify)')); + return Promise.resolve(); + } +} + +function cdvCleanUnusedDirectories() { + log(colors.green('Clean unused directories...')); + + const projectRoot = argv.root || '.'; + const platform = argv.platform || 'android'; + + let wwwPath; + if (platform === 'android') { + wwwPath = path.join(projectRoot, 'platforms', platform, 'app', 'src', 'main', 'assets', 'www'); + } else { + wwwPath = path.join(projectRoot, 'platforms', platform, 'www'); + } + + const enableUglify = argv.release || argv.uglify || false; + const debugOptions = { + title: 'Deleting', + minimal: true, + showFiles: argv.debug || false, + showCount: !argv.debug, + logger: m => log(colors.grey(m)) + }; + + let patterns = [ + wwwPath + '/api', + + // Remove HTML templates - replaced by ngTemplate() + wwwPath + '/templates', + + // Remove Cesium plugins + // (WARN: remove one by one, to keep Cordova plugins) + wwwPath + '/plugins/es', + wwwPath + '/plugins/graph', + wwwPath + '/plugins/map', + wwwPath + '/plugins/rml9', + + // Remove translations - replaced by ngTranslate() + wwwPath + '/**/i18n', + ]; + + if (enableUglify) { + patterns = patterns.concat([ + wwwPath + '/js', + wwwPath + '/css', // Have been replaced by useref(), into 'dist_css' + wwwPath + '/dist', // Have been replaced by useref(), into 'dist_js' + wwwPath + '/cordova-js-src', + + // Clean lib directory... + wwwPath + '/lib/*', + + // ...but Keep IonIcons font + '!' + wwwPath + '/lib/ionic', + wwwPath + '/lib/ionic/*', + '!' + wwwPath + '/lib/ionic/fonts', + + // ...but Keep RobotoDraft font + '!' + wwwPath + '/lib/robotodraft', + wwwPath + '/lib/robotodraft/*', + '!' + wwwPath + '/lib/robotodraft/fonts' + ]); + } + else { + patterns = patterns.concat([ + wwwPath + '/js/*', // Have been replace into dist/dist_js + '!' + wwwPath + '/js/vendor', // BUT keep vendor lib + ]); + } + + return gulp.src(patterns, {read: false, allowEmpty: true}) + .pipe(debug(debugOptions)) + .pipe(clean()); +} + + +function cdvCopyBuildFiles() { + + log(colors.green('Copy build files... ')); + + const projectRoot = argv.root || '.'; + const platform = argv.platform || 'android'; + + const srcPath = path.join(projectRoot, 'resources', platform, 'build'); + const targetPath = path.join(projectRoot, 'platforms', platform); + const debugOptions = { + title: 'Copying', + minimal: true, + showFiles: argv.debug || false, + showCount: !argv.debug, + logger: m => log(colors.grey(m)) + }; + + if (fs.existsSync(srcPath)) { + return gulp.src(srcPath + '/**/*.*') + .pipe(debug(debugOptions)) + .pipe(gulp.dest(targetPath)); + } + else { + log(colors.blue(' Directory ' + srcPath + 'not found. Skipping copy to ' + targetPath)); + return Promise.resolve(); + } +} + +function cdvAndroidManifest() { + + const projectRoot = argv.root || '.'; + const platform = argv.platform || 'android'; + + const srcMainPath = path.join(projectRoot, 'platforms', platform, 'app', 'src', 'main'); + const androidManifestFile = path.join(srcMainPath, 'AndroidManifest.xml'); + + log(colors.green(' Updating Android manifest... ') + colors.grey(androidManifestFile)); + + if (!fs.existsSync(androidManifestFile)) { + throw Error("Missing required file " + androidManifestFile); + } + + return gulp.src(androidManifestFile) + + // Add 'tools' namespace to root tag + .pipe(replace(/(xmlns:android="http:\/\/schemas.android.com\/apk\/res\/android")\s*>/g, '$1 xmlns:tools="http://schemas.android.com/tools">')) + + // Use AndroidX + .pipe(replace(/\s+tools:replace="android:appComponentFactory"/, '')) + .pipe(replace(/\s+android:appComponentFactory="[^"]+"/, '')) + .pipe(replace(/(\s*<application)\s*/, '$1 tools:replace="android:appComponentFactory" android:appComponentFactory="androidx.core.app.CoreComponentFactory" ')) + + // remove all <uses-sdk> + .pipe(replace(/<uses-sdk [^>]+\/>/g, '')) + + // add <uses-sdk> (tools:overrideLibrary) + .pipe(replace(/(<\/manifest>)/, ' <uses-sdk tools:overrideLibrary="org.kaliumjni.lib,org.apache.cordova" />\n$1')) + + .pipe(gulp.dest(srcMainPath)); +} + +function cdvAndroidCheckSigning() { + + const projectRoot = argv.root || '.'; + const platform = argv.platform || 'android'; + const targetPath = path.join(projectRoot, 'platforms', platform); + const signingFile = path.join(targetPath, 'release-signing.properties'); + + // Check signing file exists + if (fs.existsSync(targetPath) && !fs.existsSync(signingFile)) { + log(colors.blue('WARNING: Missing file ' + signingFile)); + log(colors.blue(' Please create it manually, otherwise release APK files will NOT be signed! ')); + } + + return Promise.resolve(); +} + +function cdvAfterPrepare(done, projectRoot, platform) { + + projectRoot = (typeof projectRoot === 'string' && projectRoot) || argv.root || '.'; + platform = ((typeof platform === 'string' && platform) || argv.platform || 'android').toLowerCase(); + + // Override arguments, to pass it to other tasks + argv.root = projectRoot; + argv.platform = platform; + + let wrapper = gulp.series( + gulp.parallel(cdvCopyFiles, cdvAddPlatformToBodyTag), + cdvRemoveCode, + gulp.parallel(cdvNgTemplate, cdvNgTranslate), + cdvUglify, + gulp.parallel(cdvCleanUnusedDirectories,cdvCopyBuildFiles) + ); + + if (platform === 'android') { + wrapper = gulp.series(wrapper, cdvAndroidManifest, cdvAndroidCheckSigning); + } + + wrapper(done); +} + function help() { log(colors.green("Usage: gulp {config|webBuild|webExtBuild} OPTIONS")); log(colors.green("")); @@ -871,8 +1366,19 @@ const webExtBuild = gulp.series( webExtBuildSuccess ); + +exports.cdvRemoveCode = cdvRemoveCode; +exports.cdvNgTemplate = cdvNgTemplate; +exports.cdvNgTranslate = cdvNgTranslate; +exports.cdvUglify = cdvUglify; +exports.cdvCleanUnusedDirectories = cdvCleanUnusedDirectories; +exports.cdvCopyBuildFiles = cdvCopyBuildFiles; +exports.cdvAndroidManifest = cdvAndroidManifest; +exports.cdvAndroidCheckSigning = cdvAndroidCheckSigning; +exports.cdvAfterPrepare = cdvAfterPrepare; + /* -------------------------------------------------------------------------- - -- Define gulp public tasks + -- Define public tasks --------------------------------------------------------------------------*/ exports.help = help; diff --git a/package.json b/package.json index c768593e6bfcd5ba5ddb67e938b182d45341c799..e321ac062dcd9792d17b906d62abc712e07a4fc5 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "scripts": { "clean": "trash www/dist/** dist/web/* dist/desktop/**/*.deb platforms/android/**/*.apk", "postinstall": "node scripts/node/postinstall.js", + "lint": "node scripts/node/jshint.js", "install-platforms": "ionic cordova prepare", "start": "ionic serve", "start:firefox": "gulp webExtCompile && web-ext run --source-dir ./dist/web/ext/", diff --git a/resources/android/build/app/src/main/java/fr/duniter/cesium/MainActivity.java b/resources/android/build/app/src/main/java/fr/duniter/cesium/MainActivity.java index 7271039ff0b3523b9714c3c23cc0bd09a9f3b0e2..3287e5747e28af4c332377406fb1cc5ac2e0c256 100644 --- a/resources/android/build/app/src/main/java/fr/duniter/cesium/MainActivity.java +++ b/resources/android/build/app/src/main/java/fr/duniter/cesium/MainActivity.java @@ -73,8 +73,14 @@ public class MainActivity extends CordovaActivity pathSegments = uri.getPathSegments(); } else if ("web+june".equals(scheme) || "june".equals(scheme)) { pathSegments = new ArrayList<String>(); - // Use the host as first path segment - pathSegments.add(uri.getHost()); + // Use the host as first path segment, if any + if (uri.getHost() != null) { + pathSegments.add(uri.getHost()); + } + // Or use + else if (uri.getEncodedSchemeSpecificPart() != null) { + pathSegments.add(uri.getEncodedSchemeSpecificPart()); + } if (uri.getPathSegments() != null) pathSegments.addAll(uri.getPathSegments()); } else { return; // Skip @@ -92,11 +98,15 @@ public class MainActivity extends CordovaActivity if (appView == null) { init(); } - this.appView.loadUrlIntoView(url, false); + runOnUiThread(new Runnable() { + public void run() { + MainActivity.this.appView.loadUrlIntoView(url, false); + } + }); } protected String getLaunchUrlNoHash() { - String url = this.launchUrl; + String url = "http://localhost/";//this.launchUrl; // Remove hash path int hashIndex = url.indexOf('#'); if (hashIndex != -1) { @@ -117,89 +127,4 @@ public class MainActivity extends CordovaActivity return sb.toString(); } - - // Taken from commons StringEscapeUtils - protected void escapeJavaStyleString(Writer out, String str, boolean escapeSingleQuote, - boolean escapeForwardSlash) throws IOException { - if (out == null) { - throw new IllegalArgumentException("The Writer must not be null"); - } - if (str == null) { - return; - } - int sz; - sz = str.length(); - for (int i = 0; i < sz; i++) { - char ch = str.charAt(i); - - // handle unicode - if (ch > 0xfff) { - out.write("\\u" + hex(ch)); - } else if (ch > 0xff) { - out.write("\\u0" + hex(ch)); - } else if (ch > 0x7f) { - out.write("\\u00" + hex(ch)); - } else if (ch < 32) { - switch (ch) { - case '\b': - out.write('\\'); - out.write('b'); - break; - case '\n': - out.write('\\'); - out.write('n'); - break; - case '\t': - out.write('\\'); - out.write('t'); - break; - case '\f': - out.write('\\'); - out.write('f'); - break; - case '\r': - out.write('\\'); - out.write('r'); - break; - default: - if (ch > 0xf) { - out.write("\\u00" + hex(ch)); - } else { - out.write("\\u000" + hex(ch)); - } - break; - } - } else { - switch (ch) { - case '\'': - if (escapeSingleQuote) { - out.write('\\'); - } - out.write('\''); - break; - case '"': - out.write('\\'); - out.write('"'); - break; - case '\\': - out.write('\\'); - out.write('\\'); - break; - case '/': - if (escapeForwardSlash) { - out.write('\\'); - } - out.write('/'); - break; - default: - out.write(ch); - break; - } - } - } - } - - private static String hex(char ch) { - return Integer.toHexString(ch).toUpperCase(Locale.ENGLISH); - } } diff --git a/resources/android/build/gradle/wrapper/gradle-wrapper.properties b/resources/android/build/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000000000000000000000000000000000..ee93d6819ddbcbcfe0ca286e71f4987343dcfc5d --- /dev/null +++ b/resources/android/build/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https://services.gradle.org/distributions/gradle-6.5.1-all.zip diff --git a/scripts/hooks/after_prepare.js b/scripts/hooks/after_prepare.js new file mode 100644 index 0000000000000000000000000000000000000000..9f42741279c04fb6451f1b81ef1aa130014177d2 --- /dev/null +++ b/scripts/hooks/after_prepare.js @@ -0,0 +1,25 @@ +#!/usr/bin/env node + +const gulp = require('gulp'), + path = require("path"), + log = require('fancy-log'), + colors = require('ansi-colors'); + +module.exports = function(context) { + const now = Date.now(); + log("Executing '" + colors.cyan("after_prepare") + "' hook..."); + + const projectRoot = context && context.opts && context.opts.projectRoot || '.'; + const platforms = context && context.opts && context.opts.platforms || ['android']; + const gulpFile = require(path.join(projectRoot, 'gulpfile')); + + if (!projectRoot || !platforms || !gulpFile) return; // Skip + + return Promise.all(platforms + .map(platform => { + return new Promise(done => gulpFile.cdvAfterPrepare(done, projectRoot, platform.trim().toLowerCase())); + })) + .then(() => { + log(colors.grey("Hook 'after_prepare' finished in " + (Date.now() - now) + 'ms')); + }); +} diff --git a/scripts/hooks/after_prepare/010_add_platform_class.js b/scripts/hooks/after_prepare/010_add_platform_class.js deleted file mode 100755 index d0278aa6c0b39363b3713af91de5b28741809d8f..0000000000000000000000000000000000000000 --- a/scripts/hooks/after_prepare/010_add_platform_class.js +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env node - -const fs = require('fs'), - path = require('path'); - -function addPlatformBodyTag(indexPath, platform) { - // add the platform class to the body tag - try { - const platformClass = 'platform-' + platform; - const cordovaClass = 'platform-cordova platform-webview'; - - let html = fs.readFileSync(indexPath, 'utf8'); - - const bodyTag = findBodyTag(html); - if (!bodyTag) return; // no opening body tag, something's wrong - - if (bodyTag.indexOf(platformClass) > -1) return; // already added - - let newBodyTag = bodyTag; - - let classAttr = findClassAttr(bodyTag); - if (classAttr) { - // body tag has existing class attribute, add the classname - let endingQuote = classAttr.substring(classAttr.length - 1); - let newClassAttr = classAttr.substring(0, classAttr.length - 1); - newClassAttr += ' ' + platformClass + ' ' + cordovaClass + endingQuote; - newBodyTag = bodyTag.replace(classAttr, newClassAttr); - - } else { - // add class attribute to the body tag - newBodyTag = bodyTag.replace('>', ' class="' + platformClass + ' ' + cordovaClass + '">'); - } - - html = html.replace(bodyTag, newBodyTag); - - fs.writeFileSync(indexPath, html, 'utf8'); - - process.stdout.write('add to body class: ' + platformClass + '\n'); - } catch (e) { - process.stdout.write(e); - } -} - -function findBodyTag(html) { - // get the body tag - try { - return html.match(/<body(?=[\s>])(.*?)>/gi)[0]; - } catch (e) { - } -} - -function findClassAttr(bodyTag) { - // get the body tag's class attribute - try { - return bodyTag.match(/ class=["|'](.*?)["|']/gi)[0]; - } catch (e) { - } -} - -module.exports = function(context) { - - const rootdir = context.opts.projectRoot; - const platforms = context.opts.platforms; - - if (rootdir && platforms) { - - // go through each of the platform directories that have been prepared - for (let x = 0; x < platforms.length; x++) { - // open up the index.html file at the www root - try { - const platform = platforms[x].trim().toLowerCase(); - let indexPath; - - if (platform === 'android') { - //indexPath = path.join(rootdir, 'platforms', platform, 'app', 'src', 'main', 'assets', 'www', 'index.html'); - indexPath = path.join('platforms', platform, 'assets', 'www', 'index.html'); - } else { - indexPath = path.join('platforms', platform, 'www', 'index.html'); - } - - if (fs.existsSync(indexPath)) { - addPlatformBodyTag(indexPath, platform); - } - - } catch (e) { - process.stdout.write(e); - } - } - - } - -} diff --git a/scripts/hooks/after_prepare/020_remove_code.js b/scripts/hooks/after_prepare/020_remove_code.js deleted file mode 100755 index 1889cb18664dc57568260355dbd87b0fe6a4025e..0000000000000000000000000000000000000000 --- a/scripts/hooks/after_prepare/020_remove_code.js +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env node - -module.exports = function(context) { - - const gulp = require('gulp'), - path = require("path"), - removeCode = require('gulp-remove-code'), - removeHtml = require('gulp-html-remove'), - ngAnnotate = require('gulp-ng-annotate'), - htmlmin = require('gulp-htmlmin'), - merge = require('merge2'); - - const rootdir = context.opts.projectRoot; - const platforms = context.opts.platforms; - - if (rootdir && platforms) { - - // go through each of the platform directories that have been prepared - for(let x=0; x<platforms.length; x++) { - - let platform = platforms[x].trim().toLowerCase(); - - let wwwPath; - if(platform === 'android') { - wwwPath = path.join(rootdir, 'platforms', platform, 'app/src/main/assets/www'); - } else { - wwwPath = path.join(rootdir, 'platforms', platform, 'www'); - } - - var pluginPath = path.join(wwwPath, 'plugins') + '/es'; - - // Log - //console.log('['+process.mainModule.filename+'] Removing code for platform '+platform+'\n'); - - // Compute options {device-<platform>: true} - let platformRemoveCodeOptions = {}; - platformRemoveCodeOptions[platform] = true; // = {<platform>: true} - - let htmlminOptions = {removeComments: true, collapseWhitespace: true}; - - // Do not remove desktop code for iOS and macOS (support for tablets and desktop macs) - if (platform !== 'ios' && platform !== 'osx') { - // Removing unused code for device... - merge( - // Remove unused HTML tags - gulp.src(path.join(wwwPath, 'templates', '**', '*.html')) - .pipe(removeCode({device: true})) - .pipe(removeCode(platformRemoveCodeOptions)) - .pipe(removeHtml('.hidden-xs.hidden-sm')) - .pipe(removeHtml('.hidden-device')) - .pipe(removeHtml('[remove-if][remove-if="device"]')) - .pipe(htmlmin(htmlminOptions)) - .pipe(gulp.dest(wwwPath + '/templates')), - - gulp.src(path.join(pluginPath, '**', '*.html')) - .pipe(removeCode({device: true})) - .pipe(removeCode(platformRemoveCodeOptions)) - .pipe(removeHtml('.hidden-xs.hidden-sm')) - .pipe(removeHtml('.hidden-device')) - .pipe(removeHtml('[remove-if][remove-if="device"]')) - .pipe(htmlmin(htmlminOptions)) - .pipe(gulp.dest(pluginPath)), - - gulp.src(path.join(wwwPath, 'index.html')) - .pipe(removeCode({device: true})) - .pipe(removeCode(platformRemoveCodeOptions)) - .pipe(removeHtml('.hidden-xs.hidden-sm')) - .pipe(removeHtml('.hidden-device')) - .pipe(removeHtml('[remove-if][remove-if="device"]')) - .pipe(htmlmin(/*no options, to keep comments*/)) - .pipe(gulp.dest(wwwPath)), - - // Remove unused JS code + add ng annotations - gulp.src(path.join(wwwPath, 'js', '**', '*.js')) - .pipe(removeCode({device: true})) - .pipe(removeCode(platformRemoveCodeOptions)) - .pipe(ngAnnotate({single_quotes: true})) - .pipe(gulp.dest(wwwPath + '/dist/dist_js/app')), - - gulp.src([pluginPath + '/js/**/*.js']) - .pipe(removeCode({device: true})) - .pipe(removeCode(platformRemoveCodeOptions)) - .pipe(ngAnnotate({single_quotes: true})) - .pipe(gulp.dest(wwwPath + '/dist/dist_js/plugins')) - ); - } else { - merge( - gulp.src(path.join(wwwPath, 'templates', '**', '*.html')) - .pipe(htmlmin(htmlminOptions)) - .pipe(gulp.dest(wwwPath + '/templates')), - - gulp.src(path.join(pluginPath, '**', '*.html')) - .pipe(htmlmin(htmlminOptions)) - .pipe(gulp.dest(pluginPath)), - - gulp.src(path.join(wwwPath, 'index.html')) - .pipe(gulp.dest(wwwPath)), - - gulp.src(path.join(wwwPath, 'js', '**', '*.js')) - .pipe(ngAnnotate({single_quotes: true})) - .pipe(gulp.dest(wwwPath + '/dist/dist_js/app')), - - gulp.src([pluginPath + '/js/**/*.js']) - .pipe(gulp.dest(wwwPath + '/dist/dist_js/plugins')) - ); - } - } - } - - -} diff --git a/scripts/hooks/after_prepare/021_template_cache.js b/scripts/hooks/after_prepare/021_template_cache.js deleted file mode 100755 index 539eb58adbc785c4ed20f796c628f1e00a594990..0000000000000000000000000000000000000000 --- a/scripts/hooks/after_prepare/021_template_cache.js +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env node - -const gulp = require('gulp'), - path = require("path"), - templateCache = require('gulp-angular-templatecache'), - merge = require('merge2'); - -module.exports = function(context) { - - const rootdir = context.opts.projectRoot; - const platforms = context.opts.platforms; - - if (rootdir && platforms) { - - // go through each of the platform directories that have been prepared - for (let x = 0; x < platforms.length; x++) { - - let platform = platforms[x].trim().toLowerCase(); - - let wwwPath; - if (platform === 'android') { - wwwPath = path.join(rootdir, 'platforms', platform, 'app/src/main/assets/www'); - } else { - wwwPath = path.join(rootdir, 'platforms', platform, 'www'); - } - - let distJsPath = path.join(wwwPath, 'dist', 'dist_js', 'app'); - let pluginDistJsPath = path.join(wwwPath, 'dist', 'dist_js', 'plugins'); - - // Concat templates into a JS - merge( - gulp.src(path.join(wwwPath, 'templates', '**', '*.html')) - .pipe(templateCache({ - standalone: true, - module: "cesium.templates", - root: "templates/" - })) - .pipe(gulp.dest(distJsPath)), - - gulp.src(path.join(wwwPath, 'plugins', '*', 'templates', '**', '*.html')) - .pipe(templateCache({ - standalone: true, - module: "cesium.plugins.templates", - root: "plugins/" - })) - .pipe(gulp.dest(pluginDistJsPath)) - ); - } - } -} diff --git a/scripts/hooks/after_prepare/022_translate.js b/scripts/hooks/after_prepare/022_translate.js deleted file mode 100755 index 05d982fadadd0c154beafbb32aee7316f3207d1a..0000000000000000000000000000000000000000 --- a/scripts/hooks/after_prepare/022_translate.js +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env node - -const gulp = require('gulp'), - path = require("path"), - merge = require('merge2'), - ngTranslate = require('gulp-angular-translate'); - -module.exports = function(context) { - const rootdir = context.opts.projectRoot; - const platforms = context.opts.platforms; - - if (rootdir && platforms) { - - // go through each of the platform directories that have been prepared - for (let x = 0; x < platforms.length; x++) { - - let platform = platforms[x].trim().toLowerCase(); - - let wwwPath; - if (platform === 'android') { - wwwPath = path.join(rootdir, 'platforms', platform, 'app/src/main/assets/www'); - } else { - wwwPath = path.join(rootdir, 'platforms', platform, 'www'); - } - - let distJsPath = path.join(wwwPath, 'dist', 'dist_js', 'app'); - let pluginDistJsPath = path.join(wwwPath, 'dist', 'dist_js', 'plugins'); - - // Concat templates into a JS - merge( - gulp.src(wwwPath + '/i18n/locale-*.json') - .pipe(ngTranslate({standalone: true, module: 'cesium.translations'})) - .pipe(gulp.dest(distJsPath)), - - gulp.src(wwwPath + '/plugins/*/i18n/locale-*.json') - .pipe(ngTranslate({standalone: true, module: 'cesium.plugins.translations'})) - .pipe(gulp.dest(pluginDistJsPath)) - ); - } - } - -} diff --git a/scripts/hooks/after_prepare/040_useref.js b/scripts/hooks/after_prepare/040_useref.js deleted file mode 100755 index c03dd700e41d6d6a412cecacd206609ca7e77f6f..0000000000000000000000000000000000000000 --- a/scripts/hooks/after_prepare/040_useref.js +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env node - -const gulp = require('gulp'), - path = require("path"), - es = require('event-stream'), - useref = require('gulp-useref'), - filter = require('gulp-filter'), - uglify = require('gulp-uglify-es').default, - csso = require('gulp-csso'), - log = require('fancy-log'), - colors = require('ansi-colors'); - -module.exports = function(context) { - - let skip = true; - if (context.cmdLine.indexOf("--release") > -1 || context.cmdLine.indexOf("--useref") > -1) { - skip = false; - } else { - log(colors.grey('Skipping useref')); - } - - const rootdir = context.opts.projectRoot; - const platforms = context.opts.platforms; - - if (rootdir && platforms && !skip) { - - // go through each of the platform directories that have been prepared - const platforms = (process.env.CORDOVA_PLATFORMS ? process.env.CORDOVA_PLATFORMS.split(',') : []); - - for (let x = 0; x < platforms.length; x++) { - - let platform = platforms[x].trim().toLowerCase(); - - let wwwPath; - if (platform === 'android') { - wwwPath = path.join(rootdir, 'platforms', platform, 'app/src/main/assets/www'); - } else { - wwwPath = path.join(rootdir, 'platforms', platform, 'www'); - } - - let indexPath = path.join(wwwPath, 'index.html'); - - const jsFilter = filter(['*/lib/**/*.js', '*/js/vendor/**/*.js'], {restore: true}); - const cssFilter = filter('**/*.css', {restore: true}); - const uglifyOptions = { - toplevel: true, - warnings: true, - ecma: '5', - mangle: { - reserved: ['qrcode', 'Base58'] - }, - compress: { - global_defs: { - "@console.log": "alert" - }, - passes: 2 - }, - output: { - beautify: false, - preamble: "/* minified */", - max_line_len: 120000 - } - }; - - // Removing unused code for device... - es.concat( - gulp.src(indexPath) - .pipe(useref()) // Concatenate with gulp-useref - - .pipe(jsFilter) - .pipe(uglify(uglifyOptions)) // Minify any javascript sources - .pipe(jsFilter.restore) - - .pipe(cssFilter) - .pipe(csso()) // Minify any CSS sources - .pipe(cssFilter.restore) - - .pipe(gulp.dest(wwwPath)) - ); - } - } - -} diff --git a/scripts/hooks/after_prepare/050_clean_unused_directories.js b/scripts/hooks/after_prepare/050_clean_unused_directories.js deleted file mode 100755 index 652207869b8f853c3455dd75a0d28955d721a1e2..0000000000000000000000000000000000000000 --- a/scripts/hooks/after_prepare/050_clean_unused_directories.js +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env node - -const path = require("path"), - del = require('del'); - -module.exports = function(context) { - - let skip = true; - if (context.cmdLine.indexOf("--release") > -1 || context.cmdLine.indexOf("--useref") > -1) { - skip = false; - } - - const rootdir = context.opts.projectRoot; - const platforms = context.opts.platforms; - - if (rootdir && platforms && !skip) { - - // go through each of the platform directories that have been prepared - for(let x=0; x<platforms.length; x++) { - - let platform = platforms[x].trim().toLowerCase(); - - let wwwPath; - if(platform === 'android') { - wwwPath = path.join(rootdir, 'platforms', platform, 'app/src/main/assets/www'); - } else { - wwwPath = path.join(rootdir, 'platforms', platform, 'www'); - } - - // Log - console.log('['+process.mainModule.filename+'] Cleaning unused directories'); - - // Clean unused directories - del.sync([ - path.join(wwwPath, 'api'), - path.join(wwwPath, 'i18n'), - path.join(wwwPath, 'js'), - path.join(wwwPath, 'templates'), - path.join(wwwPath, 'css'), - path.join(wwwPath, 'dist'), - path.join(wwwPath, 'cordova-js-src'), - path.join(wwwPath, 'plugins', 'es'), - path.join(wwwPath, 'plugins', 'graph'), - path.join(wwwPath, 'plugins', 'map'), - path.join(wwwPath, 'plugins', 'rml9'), - - // Clean lib directory... - path.join(wwwPath, 'lib', '*'), - - // ...but keep Ionic fonts directory - '!'+path.join(wwwPath, 'lib', 'ionic'), - path.join(wwwPath, 'lib', 'ionic', '*'), - '!'+path.join(wwwPath, 'lib', 'ionic', 'fonts'), - - // ...and keep Robotodraft fonts directory - '!'+path.join(wwwPath, 'lib', 'robotdraft'), - path.join(wwwPath, 'lib', 'robotdraft', '*'), - '!'+path.join(wwwPath, 'lib', 'robotdraft', 'fonts') - ]); - } - } - - -} diff --git a/scripts/hooks/after_prepare/060_prepare_android_manifest.js b/scripts/hooks/after_prepare/060_prepare_android_manifest.js deleted file mode 100755 index fe7a6a714a9483b9f3153b805ddf7cd9c2441bf8..0000000000000000000000000000000000000000 --- a/scripts/hooks/after_prepare/060_prepare_android_manifest.js +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env node - -const gulp = require('gulp'), - path = require("path"), - replace = require('gulp-replace'); - -module.exports = function(context) { - const rootdir = context.opts.projectRoot; - const platforms = context.opts.platforms; - - if (rootdir && platforms) { - - // go through each of the platform directories that have been prepared - for (let x = 0; x < platforms.length; x++) { - - let platform = platforms[x].trim().toLowerCase(); - - if (platform === 'android') { - let srcMainPath = path.join(rootdir, 'platforms', platform, 'app/src/main'); - let androidManifestFile = path.join(srcMainPath, 'AndroidManifest.xml'); - - // Clean unused directories - console.log('-----------------------------------------'); - console.log(' Updating file: ' + androidManifestFile); - gulp.src(androidManifestFile) - - // Add 'tools' namespace to root tag - .pipe(replace(/(xmlns:android="http:\/\/schemas.android.com\/apk\/res\/android")\s*>/g, '$1 xmlns:tools="http://schemas.android.com/tools">')) - - // Add <application> (replace 'targetSdkversion' and add tools:overrideLibrary) - .pipe(replace(/\s+tools:replace="android:appComponentFactory"/, '')) - .pipe(replace(/\s+android:appComponentFactory="[^"]+"/, '')) - .pipe(replace(/(\s*<application)\s*/, '$1 tools:replace="android:appComponentFactory" android:appComponentFactory="androidx.core.app.CoreComponentFactory" ')) - - // remove all <uses-sdk> - .pipe(replace(/<uses-sdk [^>]+\/>/g, '')) - - // add <uses-sdk> (replace 'targetSdkversion' and add tools:overrideLibrary) - .pipe(replace(/(<\/manifest>)/, ' <uses-sdk tools:overrideLibrary="org.kaliumjni.lib,org.apache.cordova" />\n$1')) - - .pipe(gulp.dest(srcMainPath)); - - console.log('-----------------------------------------'); - } - - } - } -} diff --git a/scripts/hooks/after_prepare/061_copy_build_extras.js b/scripts/hooks/after_prepare/061_copy_build_extras.js deleted file mode 100755 index 99d353d48228da80368f43bb3aa23018818bcef3..0000000000000000000000000000000000000000 --- a/scripts/hooks/after_prepare/061_copy_build_extras.js +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env node - -const fs = require('fs'), - glob = require('glob'), - path = require('path'), - log = require('fancy-log'), - colors = require('ansi-colors'); - -function mkdirp(dir) { - const parent = path.dirname(dir); - if (!fs.existsSync(parent)){ - mkdirp(parent); - } - if (!fs.existsSync(dir)){ - fs.mkdirSync(dir); - } -} - -function copyFiles(src_dir, dest_dir) { - glob(src_dir + '/**/*.*', null, function(er, files) { - files.forEach(function(file) { - log(colors.grey(' Copy file ' + file + ' to ' + dest_dir)); - const dest_file = file.replace(src_dir, dest_dir); - mkdirp(path.dirname(dest_file)); - fs.copyFile(file, dest_file, (err) => { - if (err) { - log(colors.red(' ERROR: ' + err)); - throw err; - } - }); - }); - }); -} - -// See: https://stackoverflow.com/questions/49162538/running-cordova-build-android-unable-to-find-attribute-androidfontvariation -module.exports = function(context) { - - const rootdir = context.opts.projectRoot; - const platforms = context.opts.platforms; - - if (rootdir && platforms) { - // go through each of the platform directories that have been prepared - for (let x = 0; x < platforms.length; x++) { - try { - const platform = platforms[x].trim().toLowerCase(); - - if (platform === 'android') { - const gradle_dir = path.join(rootdir, 'gradle'); - const buildRelativePath = path.join('resources', 'android', 'build'); - const build_dir = path.join(rootdir, buildRelativePath); - const android_dir = path.join(rootdir, 'platforms', 'android'); - - // Copy gradle files - if (fs.existsSync(gradle_dir)) { - copyFiles(gradle_dir, android_dir + '/gradle') - } - - if (fs.existsSync(android_dir) && fs.existsSync(build_dir)) { - - // Copy resources files - copyFiles(build_dir, android_dir); - - // Copy signing stuff - const signing_file = build_dir + '/release-signing.properties'; - if (!fs.existsSync(signing_file) && !fs.existsSync(android_dir + '/release-signing.properties')) { - log(colors.blue('WARNING: Missing file ' + buildRelativePath + '/release-signing.properties. Cannot copy it into ' + android_dir)); - log(colors.blue(' Please create it manually at ' + android_dir + '/release-signing.properties')); - log(colors.blue(' otherwise release APK files will NOT be signed! ')); - } - - } else { - log(colors.red(' Directory ' + build_dir + 'not found. Skipping copy to ' + android_dir)); - } - } - } catch (e) { - process.stdout.write(e); - } - } - } - -} diff --git a/scripts/hooks/before_compile/060_prepare_android_manifest.js b/scripts/hooks/before_compile/060_prepare_android_manifest.js deleted file mode 100755 index 27061d7b5cd42b8448864b892e88c1ad540ea0af..0000000000000000000000000000000000000000 --- a/scripts/hooks/before_compile/060_prepare_android_manifest.js +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env node - -const gulp = require('gulp'), - path = require("path"), - replace = require('gulp-replace'); - -module.exports = function(context) { - const rootdir = context.opts.projectRoot; - const platforms = context.opts.platforms; - - if (rootdir && platforms) { - - // go through each of the platform directories that have been prepared - for (let x = 0; x < platforms.length; x++) { - - let platform = platforms[x].trim().toLowerCase(); - - if (platform === 'android') { - let srcMainPath = path.join(rootdir, 'platforms', platform, 'app/src/main'); - let androidManifestFile = path.join(srcMainPath, 'AndroidManifest.xml'); - - // Clean unused directories - console.log('-----------------------------------------'); - console.log(' Updating file: ' + androidManifestFile); - gulp.src(androidManifestFile) - - // Add 'tools' namespace to root tag - .pipe(replace(/(xmlns:android="http:\/\/schemas.android.com\/apk\/res\/android")\s*>/g, '$1 xmlns:tools="http://schemas.android.com/tools">')) - - // Add <application> (replace 'targetSdkversion' and add tools:overrideLibrary) - //.pipe(replace(/\s+tools:replace="android:appComponentFactory"/, '')) - //.pipe(replace(/\s+android:appComponentFactory="[^"]+"/, '')) - //.pipe(replace(/(\s*<application)\s*/, '$1 tools:replace="android:appComponentFactory" android:appComponentFactory="androidx.core.app.CoreComponentFactory" ')) - - // remove all <uses-sdk> - .pipe(replace(/<uses-sdk [^>]+\/>/g, '')) - - // add <uses-sdk> (replace 'targetSdkversion' and add tools:overrideLibrary) - .pipe(replace(/(<\/manifest>)/, ' <uses-sdk tools:overrideLibrary="org.kaliumjni.lib,org.apache.cordova" />\n$1')) - - .pipe(gulp.dest(srcMainPath)); - - console.log('-----------------------------------------'); - } - - } - } -} diff --git a/scripts/hooks/before_prepare.js b/scripts/hooks/before_prepare.js new file mode 100644 index 0000000000000000000000000000000000000000..811e08822faeb44b3b136b9a33e0bd76021c9d44 --- /dev/null +++ b/scripts/hooks/before_prepare.js @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +const log = require('fancy-log'), + colors = require('ansi-colors'), + jshint = require('../node/jshint-utils'); + +module.exports = function(context) { + const now = Date.now(); + log("Executing '" + colors.cyan("before_prepare") + "' hook..."); + + const projectRoot = context && context.opts && context.opts.projectRoot || '.'; + const platforms = context && context.opts && context.opts.platforms || ['android']; + if (!projectRoot || !platforms) return; // Skip + + // Run JS Lint + return jshint.validate(projectRoot) + .then(() => { + log(colors.grey("Hook 'before_prepare' finished in " + (Date.now() - now) + 'ms')); + }); +} diff --git a/scripts/hooks/before_prepare/02_jshint.js b/scripts/hooks/before_prepare/02_jshint.js deleted file mode 100755 index f2bac138147fb639f993a91202c1532af0f28534..0000000000000000000000000000000000000000 --- a/scripts/hooks/before_prepare/02_jshint.js +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env node - -const fs = require('fs'), - path = require('path'), - jshint = require('jshint').JSHINT, - async = require('async'), - log = require('fancy-log'), - colors = require('ansi-colors'), - glob = require("glob"); - - -function processFiles(dir) { - let errorCount = 0; - log(colors.grey('Processing folder ' + dir + '...')); - fs.readdir(dir, function(err, list) { - if (err) { - log(colors.red('processFiles err: ' + err)); - return; - } - async.eachSeries(list, function(file, innercallback) { - file = dir + '/' + file; - log(colors.grey('Processing file ./' + file + '...')); - fs.stat(file, function(err, stat) { - if(!stat.isDirectory()) { - if(path.extname(file) === ".js") { - lintFile(file, function(hasError) { - if(hasError) { - errorCount++; - } - innercallback(); - }); - } else { - innercallback(); - } - } else { - innercallback(); - } - }); - }, function(error) { - if(errorCount > 0) { - throw error; - } - }); - }); -} - -function lintFile(file, callback) { - //log(colors.grey(`Linting ${colors.bold(file)}...`)); - fs.readFile(file, (err, data) => { - if(err) { - log(colors.red('Error: ' + err)); - return; - } - if(jshint(data.toString())) { - callback(false); - } else { - const out = jshint.data(), - errors = out.errors; - for(let j = 0; j < errors.length; j++) { - log(colors.red(`${colors.bold(file + ':' + errors[j].line + ':0' )} -> ${colors.bold(errors[j].evidence.trim())}`)); - log(colors.red(` ${errors[j].reason}`)); - } - log('-----------------------------------------'); - callback(true); - } - }); -} - -function getJSFolder(rootDir) { - // Get folders, from files - const jsFolders = glob.sync(rootDir + "/www/**/*.js", {nonull: true}) - // Map to file's folder - .map(file => file.substring(0, file.lastIndexOf('/'))) - // Reduce to a map of folders - .reduce((res, folder) => { - if (folder.indexOf('www/dist/') !== -1 || // Exclude dist js - folder.indexOf('/plugins/rml') !== -1 || // Exclude plugin tutorial - folder.indexOf('www/js/vendor') !== -1 || // exclude vendor libs - folder.indexOf('www/lib') !== -1 // exclude www/lib - ) { - return res; - } - res[folder] = res[folder] || true; - return res; - }, {}); - return Object.keys(jsFolders); -} - - -module.exports = function(context) { - const rootdir = context.opts.projectRoot; - - if (rootdir) { - const errors = []; - - // Process each folder with Js file - getJSFolder(rootdir).forEach(folder => { - try { - processFiles(folder) - } catch (err) { - errors.push(err); - } - }); - - if (errors.length) { - log(colors.red(`Some JS files have errors`)); - process.exit(1); - } - } - -} diff --git a/scripts/node/jshint-utils.js b/scripts/node/jshint-utils.js new file mode 100755 index 0000000000000000000000000000000000000000..7a591aca5d4c0e2e5bd369a2e649ebebfa81fb62 --- /dev/null +++ b/scripts/node/jshint-utils.js @@ -0,0 +1,100 @@ +'use strict'; +const fs = require('fs'), + path = require('path'), + jshint = require('jshint').JSHINT, + log = require('fancy-log'), + colors = require('ansi-colors'), + glob = require("glob"); + +async function lintFolder(dir) { + log(colors.grey('Processing folder ' + dir + '...')); + const files = fs.readdirSync(dir); + return Promise.all(files.map(file => { + file = dir + '/' + file; + return new Promise((resolve, reject) => { + const stat = fs.statSync(file); + if (stat.isDirectory() || path.extname(file) !== ".js") return resolve(); // Skip + return lintFile(file).then(resolve).catch(reject); + }) + })); +} + +function lintFile(file) { + return new Promise((resolve, reject) => { + log(colors.grey('Processing file ./' + file + '...')); + fs.readFile(file, (err, data) => { + if(err) { + log(colors.red('Error: ' + err)); + reject(err); + return; + } + if(jshint(data.toString())) { + resolve(); + } else { + const out = jshint.data(), + errors = out.errors; + for(let j = 0; j < errors.length; j++) { + log(colors.red(`${colors.bold(file + ':' + errors[j].line + ':0' )} -> ${colors.bold(errors[j].evidence.trim())}`)); + log(colors.red(` ${errors[j].reason}`)); + } + log('-----------------------------------------'); + reject(); + } + }); + }); + +} + +function getJSFolder(rootDir) { + // Get folders, from files + const jsFolders = glob.sync(rootDir + "/www/**/*.js", {nonull: true}) + // Map to file's folder + .map(file => file.substring(0, file.lastIndexOf('/'))) + // Reduce to a map of folders + .reduce((res, folder) => { + if (folder.indexOf('www/dist/') !== -1 || // Exclude dist js + folder.indexOf('/plugins/rml') !== -1 || // Exclude plugin tutorial + folder.indexOf('www/js/vendor') !== -1 || // exclude vendor libs + folder.indexOf('www/lib') !== -1 // exclude www/lib + ) { + return res; + } + res[folder] = res[folder] || true; + return res; + }, {}); + return Object.keys(jsFolders); +} + + +function validate(projectRoot) { + + projectRoot = projectRoot || '.'; + + const now = Date.now(); + log(colors.green('Linting JS files... ' + projectRoot)); + + const jsFolders = getJSFolder(projectRoot); + + // Process each folder with Js file + return Promise.all( + jsFolders.map(folder => lintFolder(folder)) + ) + .catch(err => { + console.log(err); + log(colors.red(`Some JS files have errors`)); + process.exit(1); + throw err; + }) + .then(() => { + // Success message + log(colors.grey('Linting JS files finished in ' + (Date.now() - now) + 'ms')); + }); + +} + +/* -------------------------------------------------------------------------- + -- Define public function + --------------------------------------------------------------------------*/ + +exports.validate = validate; + diff --git a/scripts/node/jshint.js b/scripts/node/jshint.js new file mode 100755 index 0000000000000000000000000000000000000000..1f4ef9015e5b75e78a8fe54bdd2f308bf7364707 --- /dev/null +++ b/scripts/node/jshint.js @@ -0,0 +1,6 @@ +#!/usr/bin/env node + +const jshint = require('./jshint-utils'); + +jshint.validate(); + diff --git a/scripts/run-android.sh b/scripts/run-android.sh index 7ccd00625643e28caf80c06ec1a591e72062026d..0a87279875cd416650c6440e9e91de8a2418fbaa 100755 --- a/scripts/run-android.sh +++ b/scripts/run-android.sh @@ -15,13 +15,17 @@ cd ${PROJECT_DIR} # Run the build echo "Building Android application..." -ionic cordova build android --warning-mode=none --verbose --color $* +ionic cordova build android --warning-mode=none --color $* [[ $? -ne 0 ]] && exit 1 echo "Running Android application..." if [[ "$1" == "--release" ]]; then - native-run android --app ${ANDROID_OUTPUT_APK_RELEASE}/app-release.apk + if [[ -f ${ANDROID_OUTPUT_APK_RELEASE}/app-release.apk ]]; then + native-run android --app ${ANDROID_OUTPUT_APK_RELEASE}/app-release-unsigned.apk + elif [[ -f ${ANDROID_OUTPUT_APK_RELEASE}/app-release.apk ]]; then + native-run android --app ${ANDROID_OUTPUT_APK_RELEASE}/app-release-unsigned.apk + fi else - native-run android --app ${ANDROID_OUTPUT_APK_DEBUG}/app-debug.apk + native-run android --app ${ls }/app-debug.apk fi diff --git a/www/manifest.json b/www/manifest.json index 7969871fe6f0206a12dc5d444460656a52ef3c6f..2fb9d5a172014fd3844650a5f8a7fa87ccd7a65a 100644 --- a/www/manifest.json +++ b/www/manifest.json @@ -31,5 +31,17 @@ "theme_color": "black", "dir": "ltr", "start_url": "/#/app/home", - "display": "standalone" + "display": "standalone", + "protocol_handlers": [ + { + "protocol": "june", + "name": "Cesium", + "uriTemplate": "/#/app/home?uri=%s" + }, + { + "protocol": "web+june", + "name": "Cesium", + "uriTemplate": "/#/app/home?uri=%s" + } + ] }