Add isIOS, isAndroid in platform, and fast ts watcher and transpiler

Image should not requestLayout when sized with 'exactly' spec

Update image tests

Tests will run in ios only
This commit is contained in:
Panayot Cankov
2016-05-27 14:49:22 +03:00
parent 44abf94add
commit 717b5131b1
9 changed files with 272 additions and 41 deletions

View File

@@ -3,31 +3,88 @@ var ts = require("typescript");
var fs = require("fs");
var path = require("path");
var arg1 = process.argv.length > 2 ? process.argv[2] : "";
var isTranspile = arg1.indexOf("t") >= 0;
var isIncremental = arg1.indexOf("i") >= 0;
var isWatching = arg1.indexOf("w") >= 0;
var opts = [];
if (isTranspile) {
opts.push("transpile");
}
if (isIncremental) {
console.log("incremental");
opts.push("incremental");
}
if (isWatching) {
opts.push("watch");
}
if (opts.length > 0) {
console.log("Options: " + opts.join(", "));
}
function isTS(file) {
return file.lastIndexOf(".ts") === file.length - 3;
}
function isDTS(file) {
return file.lastIndexOf(".d.ts") === file.length - 5;
}
function getJsPath(tsPath) {
return path.join(path.dirname(tsPath), path.basename(tsPath, ".ts")) + ".js";
}
function hasChanged(tsName) {
try {
var jsName = getJsPath(tsName);
var tsTime = fs.statSync(tsName).mtime.getTime();
var jsTime = fs.statSync(jsName).mtime.getTime();
return jsTime < tsTime;
}
catch (e) {
return true;
}
}
function transpile(fileNames, options) {
console.time("transpile");
var files = fileNames.filter(function (f) { return !isDTS(f); });
if (isIncremental) {
files = files.filter(hasChanged);
}
files.forEach(function (tsPath) {
var tsSource = fs.readFileSync(tsPath, { encoding: "utf8" });
var jsSource = ts.transpile(tsSource, options);
var jsPath = getJsPath(tsPath);
fs.writeFileSync(jsPath, jsSource, { flag: "w" }, function (err) { console.log(err); });
if (isIncremental) {
console.log(" - " + tsPath);
}
});
console.timeEnd("transpile");
if (isWatching) {
console.log("Watching for changes...");
fs.watch(".", { persistent: true, recursive: true, encoding: "utf8" }, function (event, file) {
try {
if (isTS(file) && !isDTS(file)) {
var tsPath = file;
var label = " - " + tsPath;
console.time(label);
var tsSource = fs.readFileSync(tsPath, { encoding: "utf8" });
var jsSource = ts.transpile(tsSource, options);
var jsPath = getJsPath(tsPath);
fs.writeFileSync(jsPath, jsSource, { flag: "w" }, function (err) { console.log(err); });
console.timeEnd(label);
}
}
catch (e) {
}
});
}
}
function compile(fileNames, options) {
console.time("program");
var program = ts.createProgram(fileNames, options);
console.timeEnd("program");
var sourceFiles = program.getSourceFiles().filter(function (f) { return f.fileName.lastIndexOf(".d.ts") !== f.fileName.length - 5; });
var sourceFiles = program.getSourceFiles().filter(function (f) { return !isDTS(f.fileName); });
var emitResults = [];
var allDiagnostics = [];
console.time("transpile");
if (isIncremental) {
sourceFiles = sourceFiles.filter(function (srcFile) {
try {
var tsName = srcFile.fileName;
var jsName = path.join(path.dirname(tsName), path.basename(tsName, ".ts")) + ".js";
var tsTime = fs.statSync(tsName).mtime.getTime();
var jsTime = fs.statSync(jsName).mtime.getTime();
return jsTime < tsTime;
}
catch (e) {
return true;
}
});
sourceFiles = sourceFiles.filter(function (srcFile) { return hasChanged(srcFile.fileName); });
sourceFiles.forEach(function (srcFile) {
console.log(" - " + srcFile.fileName);
emitResults.push(program.emit(srcFile));
@@ -54,13 +111,19 @@ function compile(fileNames, options) {
process.exit(exitCode);
}
var files = JSON.parse(fs.readFileSync("./tsconfig.json")).files;
compile(files, {
var options = {
noEmitOnError: true,
noEmitHelpers: true,
target: ts.ScriptTarget.ES5,
module: ts.ModuleKind.CommonJS,
target: 1 /* ES5 */,
module: 1 /* CommonJS */,
declaration: false,
noImplicitAny: false,
noImplicitUseStrict: true,
experimentalDecorators: true
});
};
if (isTranspile) {
transpile(files, { module: 1 /* CommonJS */ });
}
else {
compile(files, options);
}

View File

@@ -5,9 +5,89 @@ var path = require("path");
var arg1 = process.argv.length > 2 ? process.argv[2] : "";
var isTranspile = arg1.indexOf("t") >= 0;
var isIncremental = arg1.indexOf("i") >= 0;
var isWatching = arg1.indexOf("w") >= 0;
var opts = [];
if (isTranspile) {
opts.push("transpile");
}
if (isIncremental) {
console.log("incremental");
opts.push("incremental");
}
if (isWatching) {
opts.push("watch");
}
if (opts.length > 0) {
console.log("Options: " + opts.join(", "));
}
function isTS(file: string): boolean {
return file.lastIndexOf(".ts") === file.length - 3;
}
function isDTS(file: string): boolean {
return file.lastIndexOf(".d.ts") === file.length - 5;
}
function getJsPath(tsPath: string): string {
return path.join(path.dirname(tsPath), path.basename(tsPath, ".ts")) + ".js";
}
function hasChanged(tsName: string): boolean {
try {
var jsName = getJsPath(tsName);
var tsTime = fs.statSync(tsName).mtime.getTime();
var jsTime = fs.statSync(jsName).mtime.getTime();
return jsTime < tsTime;
} catch(e) {
return true;
}
}
function transpile(fileNames: string[], options: ts.CompilerOptions) {
console.time("transpile");
var files = fileNames.filter(f => !isDTS(f));
if (isIncremental) {
files = files.filter(hasChanged);
}
files.forEach(tsPath => {
var tsSource = fs.readFileSync(tsPath, { encoding: "utf8" });
var jsSource = ts.transpile(tsSource, options);
var jsPath = getJsPath(tsPath);
fs.writeFileSync(jsPath, jsSource, { flag: "w" }, function(err) { console.log(err); });
if (isIncremental) {
console.log(" - " + tsPath);
}
});
console.timeEnd("transpile");
if (isWatching) {
console.log("Watching for changes...");
fs.watch(".", { persistent: true, recursive: true, encoding: "utf8" }, (event, file) => {
try {
if (isTS(file) && !isDTS(file)) {
var tsPath = file;
var label = " - " + tsPath;
console.time(label);
var tsSource = fs.readFileSync(tsPath, { encoding: "utf8" });
var jsSource = ts.transpile(tsSource, options);
var jsPath = getJsPath(tsPath);
fs.writeFileSync(jsPath, jsSource, { flag: "w" }, function(err) { console.log(err); });
console.timeEnd(label);
}
} catch(e) {
// console.log(e);
}
});
}
}
function compile(fileNames: string[], options: ts.CompilerOptions) {
@@ -15,27 +95,14 @@ function compile(fileNames: string[], options: ts.CompilerOptions) {
var program = ts.createProgram(fileNames, options);
console.timeEnd("program");
var sourceFiles = program.getSourceFiles().filter(f => f.fileName.lastIndexOf(".d.ts") !== f.fileName.length - 5);
var sourceFiles = program.getSourceFiles().filter(f => !isDTS(f.fileName));
var emitResults = [];
var allDiagnostics = [];
console.time("transpile");
if (isIncremental) {
sourceFiles = sourceFiles.filter(srcFile => {
try {
var tsName = srcFile.fileName;
var jsName = path.join(path.dirname(tsName), path.basename(tsName, ".ts")) + ".js";
var tsTime = fs.statSync(tsName).mtime.getTime();
var jsTime = fs.statSync(jsName).mtime.getTime();
return jsTime < tsTime;
} catch(e) {
return true;
}
});
sourceFiles = sourceFiles.filter(srcFile => hasChanged(srcFile.fileName));
sourceFiles.forEach(srcFile => {
console.log(" - " + srcFile.fileName);
emitResults.push(program.emit(srcFile));
@@ -66,8 +133,7 @@ function compile(fileNames: string[], options: ts.CompilerOptions) {
}
var files = JSON.parse(fs.readFileSync("./tsconfig.json")).files;
compile(files,
{
var options: ts.CompilerOptions = {
noEmitOnError: true,
noEmitHelpers: true,
target: ts.ScriptTarget.ES5,
@@ -76,5 +142,9 @@ compile(files,
noImplicitAny: false,
noImplicitUseStrict: true,
experimentalDecorators: true
});
};
if (isTranspile) {
transpile(files, { module: ts.ModuleKind.CommonJS });
} else {
compile(files, options);
}

View File

@@ -21,5 +21,10 @@
"time-grunt": "1.3.0",
"tslint": "3.4.0",
"typescript": "1.8.2"
},
"scripts": {
"tsc-tiw": "node build/tsc-dev.js tiw",
"tsc": "tsc",
"link-tests": "cd tns-core-modules && npm link && cd ../tests && npm link tns-core-modules"
}
}

View File

@@ -1,5 +1,6 @@
import TKUnit = require("./TKUnit");
import app = require("application");
import { isIOS, isAndroid } from "platform";
// >> platform-require
import platformModule = require("platform");
@@ -29,3 +30,12 @@ export function snippet_print_all() {
console.log("Screen scale: " + platformModule.screen.mainScreen.scale);
// << platform-current
};
export function testIsIOSandIsAndroid() {
if (isIOS) {
TKUnit.assertTrue(!!NSObject, "isIOS is true-ish but common iOS APIs are not available.");
} else if (isAndroid) {
TKUnit.assertTrue(!!android, "isAndroid is true but common 'android' package is not available.");
}
}

View File

@@ -1,4 +1,11 @@
import TKUnit = require("../../TKUnit");
import {Image} from "ui/image";
import {StackLayout} from "ui/layouts/stack-layout";
import {GridLayout} from "ui/layouts/grid-layout";
import {isIOS} from "platform";
// import {target} from "../../TKUnit";
import TKUnit = require("../../TKUnit");
// >> img-require
import ImageModule = require("ui/image");
// << img-require
@@ -244,3 +251,62 @@ export var test_SettingStretch_none = function () {
helper.buildUIAndRunTest(image, testFunc);
}
function ios<T>(func: T): T {
return isIOS ? func : undefined;
}
export var test_SettingImageSourceWhenSizedToParentDoesNotRequestLayout = ios(() => {
let host = new GridLayout();
let image = new Image();
host.width = 300;
host.height = 300;
host.addChild(image);
let mainPage = helper.getCurrentPage();
mainPage.content = host;
TKUnit.waitUntilReady(() => host.isLoaded);
let called = false;
image.requestLayout = () => called = true;
image.src = "~/logo.png";
TKUnit.assertFalse(called, "image.requestLayout should not be called.");
});
export var test_SettingImageSourceWhenFixedWidthAndHeightDoesNotRequestLayout = ios(() => {
let host = new StackLayout();
let image = new Image();
image.width = 100;
image.height = 100;
host.addChild(image);
let mainPage = helper.getCurrentPage();
mainPage.content = host;
TKUnit.waitUntilReady(() => host.isLoaded);
let called = false;
image.requestLayout = () => called = true;
image.src = "~/logo.png";
TKUnit.assertFalse(called, "image.requestLayout should not be called.");
});
export var test_SettingImageSourceWhenSizedToContentShouldInvalidate = ios(() => {
let host = new StackLayout();
let image = new Image();
host.addChild(image);
let mainPage = helper.getCurrentPage();
mainPage.content = host;
TKUnit.waitUntilReady(() => host.isLoaded);
let called = false;
image.requestLayout = () => called = true;
image.src = "~/logo.png";
TKUnit.assertTrue(called, "image.requestLayout should be called.");
});

View File

@@ -133,3 +133,5 @@ export var device: definition.Device = new Device();
export module screen {
export var mainScreen = new MainScreen();
}
export var isAndroid = true;

View File

@@ -3,6 +3,16 @@
* Contains all kinds of information about the device, its operating system and software.
*/
declare module "platform" {
/**
* Gets a value indicating if the app is running on the Android platform.
*/
export var isAndroid: boolean;
/**
* Gets a value indicating if the app is running on the iOS platform.
*/
export var isIOS: boolean;
/*
* Enum holding platform names.

View File

@@ -126,3 +126,5 @@ export var device: definition.Device = new Device();
export module screen {
export var mainScreen = new MainScreen();
}
export var isIOS = true;

View File

@@ -36,6 +36,7 @@ function onImageSourcePropertyChanged(data: dependencyObservable.PropertyChangeD
export class Image extends imageCommon.Image {
private _ios: UIImageView;
private _imageSourceAffectsLayout: boolean = true;
constructor() {
super();
@@ -54,7 +55,7 @@ export class Image extends imageCommon.Image {
public _setNativeImage(nativeImage: any) {
this.ios.image = nativeImage;
if (isNaN(this.width) || isNaN(this.height)) {
if (this._imageSourceAffectsLayout) {
this.requestLayout();
}
}
@@ -77,7 +78,9 @@ export class Image extends imageCommon.Image {
var finiteWidth: boolean = widthMode !== utils.layout.UNSPECIFIED;
var finiteHeight: boolean = heightMode !== utils.layout.UNSPECIFIED;
this._imageSourceAffectsLayout = widthMode !== utils.layout.EXACTLY || heightMode !== utils.layout.EXACTLY;
if (nativeWidth !== 0 && nativeHeight !== 0 && (finiteWidth || finiteHeight)) {
var scale = Image.computeScaleFactor(width, height, finiteWidth, finiteHeight, nativeWidth, nativeHeight, this.stretch);
var resultW = Math.floor(nativeWidth * scale.width);