Skip to content

Commit

Permalink
Merge branch 'master' into TIMOB-27240
Browse files Browse the repository at this point in the history
  • Loading branch information
jquick-axway committed Jul 15, 2020
2 parents 1e0d48d + c8cab5a commit 226f5b1
Show file tree
Hide file tree
Showing 247 changed files with 4,438 additions and 1,852 deletions.
5 changes: 3 additions & 2 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ android/runtime/v8/tools/bootstrap.js
android/dev
android/modules/ui/assets/Resources/ti.internal/webview/*.js
android/titanium/build
android/**/generated/

iphone/Resources/app.js

# TODO: We probably do want to lint these eventually!
templates/**


titanium-mobile-mocha-suite/
tests/Resources/fake_node_modules/

dist/
android/**/generated/
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,5 @@ junit_report.xml

.nyc_output/
coverage/

tests/diffs/
2 changes: 2 additions & 0 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ def androidUnitTests(nodeVersion, npmVersion, testSuiteBranch, testOnDevices) {
stash includes: 'junit.*.xml', name: 'test-report-android'
junit 'junit.*.xml'
} // dir('scripts')
archiveArtifacts allowEmptyArchive: true, artifacts: 'diffs/'
} // nodejs
} // dir('titanium-mobile-mocha-suite')
} finally {
Expand Down Expand Up @@ -172,6 +173,7 @@ def iosUnitTests(deviceFamily, nodeVersion, npmVersion, testSuiteBranch) {
stash includes: 'junit.ios.*.xml', name: "test-report-ios-${deviceFamily}"
junit 'junit.ios.*.xml'
} // dir('scripts')
archiveArtifacts allowEmptyArchive: true, artifacts: 'diffs/'
} // nodejs
} // dir('titanium-mobile-mocha-suite')
} finally {
Expand Down
16 changes: 15 additions & 1 deletion android/cli/commands/_build.js
Original file line number Diff line number Diff line change
Expand Up @@ -1959,9 +1959,23 @@ AndroidBuilder.prototype.checkIfShouldForceRebuild = function checkIfShouldForce
};

AndroidBuilder.prototype.checkIfNeedToRecompile = async function checkIfNeedToRecompile() {
// Delete all files under the "./build/android" if we need to do a full rebuild.
// Determine if we should do a "clean" build.
this.forceRebuild = this.checkIfShouldForceRebuild();
if (this.forceRebuild) {
// On Windows, stop gradle daemon to make it release its file locks so that they can be deleted.
if (process.platform === 'win32') {
try {
const gradlew = new GradleWrapper(this.buildDir);
gradlew.logger = this.logger;
if (await gradlew.hasWrapperFiles()) {
await gradlew.stopDaemon();
}
} catch (err) {
this.logger.error(`Failed to stop gradle daemon. Reason:\n${err}`);
}
}

// Delete all files under the "./build/android" directory.
await fs.emptyDir(this.buildDir);
this.unmarkBuildDirFiles(this.buildDir);
}
Expand Down
84 changes: 56 additions & 28 deletions android/cli/commands/_cleanModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,39 +12,67 @@
*/

'use strict';
const path = require('path');
const fs = require('fs-extra');

const appc = require('node-appc');
const fs = require('fs-extra');
const GradleWrapper = require('../lib/gradle-wrapper');
const path = require('path');
const __ = appc.i18n(__dirname).__;

exports.run = function run(logger, config, cli, finished) {
const projectDir = cli.argv['project-dir'];

const toDelete = [ 'build', 'dist', 'java-sources.txt' ];
toDelete.forEach(f => {
const target = path.join(projectDir, f);
if (appc.fs.exists(target)) {
logger.debug(__('Deleting %s', target.cyan));
fs.removeSync(target);
} else {
logger.debug(__('File does not exist %s', target.cyan));
exports.run = async function run(logger, config, cli, finished) {
try {
const projectDir = cli.argv['project-dir'];

// On Windows, stop gradle daemon to make it release its file locks so that they can be deleted.
if (process.platform === 'win32') {
try {
const gradlew = new GradleWrapper(path.join(projectDir, 'build'));
gradlew.logger = logger;
if (await gradlew.hasWrapperFiles()) {
logger.debug('Stopping gradle daemon.');
await gradlew.stopDaemon();
}
} catch (err) {
logger.error(`Failed to stop gradle daemon. Reason:\n${err}`);
}
}
});

// remove only the libraries we generate
const libsDir = path.join(projectDir, 'libs');
if (appc.fs.exists(libsDir)) {
const moduleid = cli.manifest.moduleid;
const arches = fs.readdirSync(libsDir);
arches.forEach(arch => {
const target = path.join(projectDir, 'libs', arch, `lib${moduleid}.so`);
if (appc.fs.exists(target)) {
logger.debug(__('Deleting %s', target.cyan));
fs.removeSync(target);
} else {
logger.debug(__('File does not exist %s', target.cyan));

const buildDir = path.join(projectDir, 'build');
for (const file of await fs.readdir(buildDir)) {
if (file === 'clean_android.log') {
continue;
}
});
const filePath = path.join(buildDir, file);
logger.debug(__('Deleting %s', filePath.cyan));
await fs.remove(filePath);
}

// Delete the following files and directory trees.
const fileNames = [ 'dist', 'java-sources.txt' ];
for (const nextFileName of fileNames) {
const nextFilePath = path.join(projectDir, nextFileName);
if (await fs.exists(nextFilePath)) {
logger.debug(__('Deleting %s', nextFilePath.cyan));
await fs.remove(nextFilePath);
}
}

// Delete this module's last built "*.so" libraries from "libs" directory.
// Do not delete all files from "libs". Some modules put 3rd party "*.so" library dependencies there.
// Note: As of Titanium 9.0.0, "*.so" files are not built here anymore. This is legacy behavior.
const libsDirPath = path.join(projectDir, 'libs');
if (await fs.exists(libsDirPath)) {
const libFileName = `lib${cli.manifest.moduleid}.so`;
for (const architectureFolderName of await fs.readdir(libsDirPath)) {
const libFilePath = path.join(libsDirPath, architectureFolderName, libFileName);
if (await fs.exists(libFilePath)) {
logger.debug(__('Deleting %s', libFilePath.cyan));
await fs.remove(libFilePath);
}
}
}
} catch (err) {
finished(err);
}

finished();
Expand Down
52 changes: 50 additions & 2 deletions android/cli/lib/gradle-wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ class GradleWrapper {
return this._gradlewDirPath;
}

/**
* Gets a path to the "gradlew" script file that will be executed to run gradle tasks.
* @type {String}
*/
get gradlewFilePath() {
return path.join(this._gradlewDirPath, isWindows ? 'gradlew.bat' : 'gradlew');
}

/**
* Gets/Sets the "appc-logger" object that gradle will output to. Can be null/undefined.
* @type {Object}
Expand Down Expand Up @@ -145,6 +153,11 @@ class GradleWrapper {
await this.run(`${subprojectName}publish --console plain`);
}

/** Stops all gradle daemon processes on the system using the same gradle version this wrapper references. */
async stopDaemon() {
await this.run('--stop --console plain');
}

/**
* Runs the "gradlew" command line tool with the given command line arguments string.
* @param {String} [argsString]
Expand All @@ -155,8 +168,7 @@ class GradleWrapper {
*/
async run(argsString) {
// Set up the "gradlew" command line string.
const gradlewFilePath = path.join(this._gradlewDirPath, isWindows ? 'gradlew.bat' : 'gradlew');
let commandLineString = `"${gradlewFilePath}"`;
let commandLineString = `"${this.gradlewFilePath}"`;
if (argsString) {
commandLineString += ' ' + argsString;
}
Expand Down Expand Up @@ -209,6 +221,42 @@ class GradleWrapper {
});
}

/**
* Determines if a "locale.properties" file exists at the gradle project's root location.
* @returns {Promise<Boolean>} Returns true if the file exists. Returns false if not.
*/
async hasLocalPropertiesFile() {
return fs.exists(path.join(this._gradlewDirPath, 'local.properties'));
}

/**
* Determines if a "settings.gradle" file exists at the gradle project's root location.
* @returns {Promise<Boolean>} Returns true if the file exists. Returns false if not.
*/
async hasSettingsGradleFile() {
return fs.exists(path.join(this._gradlewDirPath, 'settings.gradle'));
}

/**
* Determines if the gradlew wrapper files exist in the gradle project's root location.
* @returns {Promise<Boolean>} Returns true if the wrapper files exist. Returns false if not.
*/
async hasWrapperFiles() {
if (!await fs.exists(this.gradlewFilePath)) {
return false;
}

const wrapperLibraryDirPath = path.join(this._gradlewDirPath, 'gradle', 'wrapper');
if (!await fs.exists(path.join(wrapperLibraryDirPath, 'gradle-wrapper.jar'))) {
return false;
}
if (!await fs.exists(path.join(wrapperLibraryDirPath, 'gradle-wrapper.properties'))) {
return false;
}

return true;
}

/**
* Copies the "gradlew" file tree from the given "templateDirPath" to this object's assigned "directoryPath".
* This must be done before calling this object's clean(), assembleRelease(), assembleDebug(), or run() methods
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2009-2012 by Appcelerator, Inc. All Rights Reserved.
* Copyright (c) 2009-Present by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/
Expand All @@ -14,6 +14,7 @@

import ti.modules.titanium.android.AndroidModule;
import android.app.Activity;
import androidx.annotation.NonNull;

@Kroll.proxy(creatableInModule = AndroidModule.class)
public class TiActivityWindowProxy extends TiWindowProxy
Expand All @@ -35,17 +36,17 @@ public void setView(TiUIView view)
}

@Override
protected void handleClose(KrollDict options)
protected void handleClose(@NonNull KrollDict options)
{
Log.d(TAG, "handleClose", Log.DEBUG_MODE);
opened = false;
fireEvent("close", null);

if (view != null) {
((TiUIActivityWindow) view).close();
}

releaseViews();
opened = false;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,39 @@ public String makeUpperCase(String text, @Kroll.argument(optional = true) Object
return text.toUpperCase(locale);
}

@Kroll.method
public double parseDecimal(String text, @Kroll.argument(optional = true) String localeString)
{
double result = Double.NaN;
try {
// Create a number format parser using given locale if provided or current locale.
Locale locale = TiPlatformHelper.getInstance().getLocale(localeString);
NumberFormat numberFormat;
if (locale != null) {
numberFormat = NumberFormat.getInstance(locale);
} else {
numberFormat = NumberFormat.getInstance();
}

// Enable thousands separator parsing support. (ex: "1,234,567")
numberFormat.setGroupingUsed(true);

// Remove leading spaces and plus sign. Number format will fail to parse if there.
text = text.trim();
if (text.startsWith("+")) {
text = text.substring(1);
}

// Attempt to parse a decimal value from given string.
Number number = numberFormat.parse(text);
if (number != null) {
result = number.doubleValue();
}
} catch (Exception ex) {
}
return result;
}

@Kroll.method
@Kroll.setProperty
public void setLanguage(String language)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ public String getColor()
public void setColor(String color)
{
setPropertyAndFire(TiC.PROPERTY_COLOR, color);
if (rowListener != null) {
rowListener.rowChanged(this);
}
}

@Kroll.method
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,14 @@ public String getApiName()
{
return "Ti.UI.SearchBar";
}

@Kroll.getProperty(name = "focused")
public boolean isFocused()
{
TiUIView v = peekView();
if (v != null) {
return v.isFocused();
}
return false;
}
}

0 comments on commit 226f5b1

Please sign in to comment.