mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-18 05:18:39 +08:00
Merge pull request #2198 from NativeScript/cankov/image-exactly
Image should not requestLayout when measured with 'exactly' spec
This commit is contained in:
@ -3,31 +3,88 @@ var ts = require("typescript");
|
|||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
var arg1 = process.argv.length > 2 ? process.argv[2] : "";
|
var arg1 = process.argv.length > 2 ? process.argv[2] : "";
|
||||||
|
var isTranspile = arg1.indexOf("t") >= 0;
|
||||||
var isIncremental = arg1.indexOf("i") >= 0;
|
var isIncremental = arg1.indexOf("i") >= 0;
|
||||||
|
var isWatching = arg1.indexOf("w") >= 0;
|
||||||
|
var opts = [];
|
||||||
|
if (isTranspile) {
|
||||||
|
opts.push("transpile");
|
||||||
|
}
|
||||||
if (isIncremental) {
|
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) {
|
function compile(fileNames, options) {
|
||||||
console.time("program");
|
console.time("program");
|
||||||
var program = ts.createProgram(fileNames, options);
|
var program = ts.createProgram(fileNames, options);
|
||||||
console.timeEnd("program");
|
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 emitResults = [];
|
||||||
var allDiagnostics = [];
|
var allDiagnostics = [];
|
||||||
console.time("transpile");
|
console.time("transpile");
|
||||||
if (isIncremental) {
|
if (isIncremental) {
|
||||||
sourceFiles = sourceFiles.filter(function (srcFile) {
|
sourceFiles = sourceFiles.filter(function (srcFile) { return hasChanged(srcFile.fileName); });
|
||||||
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.forEach(function (srcFile) {
|
sourceFiles.forEach(function (srcFile) {
|
||||||
console.log(" - " + srcFile.fileName);
|
console.log(" - " + srcFile.fileName);
|
||||||
emitResults.push(program.emit(srcFile));
|
emitResults.push(program.emit(srcFile));
|
||||||
@ -54,13 +111,19 @@ function compile(fileNames, options) {
|
|||||||
process.exit(exitCode);
|
process.exit(exitCode);
|
||||||
}
|
}
|
||||||
var files = JSON.parse(fs.readFileSync("./tsconfig.json")).files;
|
var files = JSON.parse(fs.readFileSync("./tsconfig.json")).files;
|
||||||
compile(files, {
|
var options = {
|
||||||
noEmitOnError: true,
|
noEmitOnError: true,
|
||||||
noEmitHelpers: true,
|
noEmitHelpers: true,
|
||||||
target: ts.ScriptTarget.ES5,
|
target: 1 /* ES5 */,
|
||||||
module: ts.ModuleKind.CommonJS,
|
module: 1 /* CommonJS */,
|
||||||
declaration: false,
|
declaration: false,
|
||||||
noImplicitAny: false,
|
noImplicitAny: false,
|
||||||
noImplicitUseStrict: true,
|
noImplicitUseStrict: true,
|
||||||
experimentalDecorators: true
|
experimentalDecorators: true
|
||||||
});
|
};
|
||||||
|
if (isTranspile) {
|
||||||
|
transpile(files, { module: 1 /* CommonJS */ });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
compile(files, options);
|
||||||
|
}
|
||||||
|
110
build/tsc-dev.ts
110
build/tsc-dev.ts
@ -5,9 +5,89 @@ var path = require("path");
|
|||||||
|
|
||||||
var arg1 = process.argv.length > 2 ? process.argv[2] : "";
|
var arg1 = process.argv.length > 2 ? process.argv[2] : "";
|
||||||
|
|
||||||
|
var isTranspile = arg1.indexOf("t") >= 0;
|
||||||
var isIncremental = arg1.indexOf("i") >= 0;
|
var isIncremental = arg1.indexOf("i") >= 0;
|
||||||
|
var isWatching = arg1.indexOf("w") >= 0;
|
||||||
|
|
||||||
|
var opts = [];
|
||||||
|
|
||||||
|
if (isTranspile) {
|
||||||
|
opts.push("transpile");
|
||||||
|
}
|
||||||
|
|
||||||
if (isIncremental) {
|
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) {
|
function compile(fileNames: string[], options: ts.CompilerOptions) {
|
||||||
@ -15,27 +95,14 @@ function compile(fileNames: string[], options: ts.CompilerOptions) {
|
|||||||
var program = ts.createProgram(fileNames, options);
|
var program = ts.createProgram(fileNames, options);
|
||||||
|
|
||||||
console.timeEnd("program");
|
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 emitResults = [];
|
||||||
var allDiagnostics = [];
|
var allDiagnostics = [];
|
||||||
|
|
||||||
console.time("transpile");
|
console.time("transpile");
|
||||||
if (isIncremental) {
|
if (isIncremental) {
|
||||||
sourceFiles = sourceFiles.filter(srcFile => {
|
sourceFiles = sourceFiles.filter(srcFile => hasChanged(srcFile.fileName));
|
||||||
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.forEach(srcFile => {
|
sourceFiles.forEach(srcFile => {
|
||||||
console.log(" - " + srcFile.fileName);
|
console.log(" - " + srcFile.fileName);
|
||||||
emitResults.push(program.emit(srcFile));
|
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;
|
var files = JSON.parse(fs.readFileSync("./tsconfig.json")).files;
|
||||||
compile(files,
|
var options: ts.CompilerOptions = {
|
||||||
{
|
|
||||||
noEmitOnError: true,
|
noEmitOnError: true,
|
||||||
noEmitHelpers: true,
|
noEmitHelpers: true,
|
||||||
target: ts.ScriptTarget.ES5,
|
target: ts.ScriptTarget.ES5,
|
||||||
@ -76,5 +142,9 @@ compile(files,
|
|||||||
noImplicitAny: false,
|
noImplicitAny: false,
|
||||||
noImplicitUseStrict: true,
|
noImplicitUseStrict: true,
|
||||||
experimentalDecorators: true
|
experimentalDecorators: true
|
||||||
});
|
};
|
||||||
|
if (isTranspile) {
|
||||||
|
transpile(files, { module: ts.ModuleKind.CommonJS });
|
||||||
|
} else {
|
||||||
|
compile(files, options);
|
||||||
|
}
|
@ -21,5 +21,10 @@
|
|||||||
"time-grunt": "1.3.0",
|
"time-grunt": "1.3.0",
|
||||||
"tslint": "3.4.0",
|
"tslint": "3.4.0",
|
||||||
"typescript": "1.8.2"
|
"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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import TKUnit = require("./TKUnit");
|
import TKUnit = require("./TKUnit");
|
||||||
import app = require("application");
|
import app = require("application");
|
||||||
|
import { isIOS, isAndroid } from "platform";
|
||||||
|
|
||||||
// >> platform-require
|
// >> platform-require
|
||||||
import platformModule = require("platform");
|
import platformModule = require("platform");
|
||||||
@ -29,3 +30,12 @@ export function snippet_print_all() {
|
|||||||
console.log("Screen scale: " + platformModule.screen.mainScreen.scale);
|
console.log("Screen scale: " + platformModule.screen.mainScreen.scale);
|
||||||
// << platform-current
|
// << 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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -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
|
// >> img-require
|
||||||
import ImageModule = require("ui/image");
|
import ImageModule = require("ui/image");
|
||||||
// << img-require
|
// << img-require
|
||||||
@ -244,3 +251,62 @@ export var test_SettingStretch_none = function () {
|
|||||||
|
|
||||||
helper.buildUIAndRunTest(image, testFunc);
|
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.");
|
||||||
|
});
|
||||||
|
|
||||||
|
@ -133,3 +133,5 @@ export var device: definition.Device = new Device();
|
|||||||
export module screen {
|
export module screen {
|
||||||
export var mainScreen = new MainScreen();
|
export var mainScreen = new MainScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export var isAndroid = true;
|
10
tns-core-modules/platform/platform.d.ts
vendored
10
tns-core-modules/platform/platform.d.ts
vendored
@ -4,6 +4,16 @@
|
|||||||
*/
|
*/
|
||||||
declare module "platform" {
|
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.
|
* Enum holding platform names.
|
||||||
*/
|
*/
|
||||||
|
@ -126,3 +126,5 @@ export var device: definition.Device = new Device();
|
|||||||
export module screen {
|
export module screen {
|
||||||
export var mainScreen = new MainScreen();
|
export var mainScreen = new MainScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export var isIOS = true;
|
@ -36,6 +36,7 @@ function onImageSourcePropertyChanged(data: dependencyObservable.PropertyChangeD
|
|||||||
|
|
||||||
export class Image extends imageCommon.Image {
|
export class Image extends imageCommon.Image {
|
||||||
private _ios: UIImageView;
|
private _ios: UIImageView;
|
||||||
|
private _imageSourceAffectsLayout: boolean = true;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@ -54,7 +55,7 @@ export class Image extends imageCommon.Image {
|
|||||||
public _setNativeImage(nativeImage: any) {
|
public _setNativeImage(nativeImage: any) {
|
||||||
this.ios.image = nativeImage;
|
this.ios.image = nativeImage;
|
||||||
|
|
||||||
if (isNaN(this.width) || isNaN(this.height)) {
|
if (this._imageSourceAffectsLayout) {
|
||||||
this.requestLayout();
|
this.requestLayout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,6 +79,8 @@ export class Image extends imageCommon.Image {
|
|||||||
var finiteWidth: boolean = widthMode !== utils.layout.UNSPECIFIED;
|
var finiteWidth: boolean = widthMode !== utils.layout.UNSPECIFIED;
|
||||||
var finiteHeight: boolean = heightMode !== 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)) {
|
if (nativeWidth !== 0 && nativeHeight !== 0 && (finiteWidth || finiteHeight)) {
|
||||||
var scale = Image.computeScaleFactor(width, height, finiteWidth, finiteHeight, nativeWidth, nativeHeight, this.stretch);
|
var scale = Image.computeScaleFactor(width, height, finiteWidth, finiteHeight, nativeWidth, nativeHeight, this.stretch);
|
||||||
var resultW = Math.floor(nativeWidth * scale.width);
|
var resultW = Math.floor(nativeWidth * scale.width);
|
||||||
|
Reference in New Issue
Block a user