mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-15 19:26:42 +08:00
Merge remote-tracking branch 'origin/master' into svetoslavtsenov/merge-release
This commit is contained in:
@ -7,7 +7,9 @@
|
|||||||
<Button text="login" tap="{{ loginName }}" />
|
<Button text="login" tap="{{ loginName }}" />
|
||||||
<Button text="promptText" tap="{{ promptText }}" />
|
<Button text="promptText" tap="{{ promptText }}" />
|
||||||
<Button text="promptPass" tap="{{ promptPass }}" />
|
<Button text="promptPass" tap="{{ promptPass }}" />
|
||||||
<Button text="promptEmail" tap="{{ promptEmail }}" />
|
<Button text="promptEmail" tap="{{ promptEmail }}" />
|
||||||
|
<Button text="promptNumber" tap="{{ promptNumber }}" />
|
||||||
|
<Button text="promptPhone" tap="{{ promptPhone }}" />
|
||||||
<Button text="promptCapitalizationNone" tap="{{ promptCapitalizationNone }}" />
|
<Button text="promptCapitalizationNone" tap="{{ promptCapitalizationNone }}" />
|
||||||
<Button text="promptCapitalizationAll" tap="{{ promptCapitalizationAll }}" />
|
<Button text="promptCapitalizationAll" tap="{{ promptCapitalizationAll }}" />
|
||||||
<Button text="promptCapitalizationSentences" tap="{{ promptCapitalizationSentences }}" />
|
<Button text="promptCapitalizationSentences" tap="{{ promptCapitalizationSentences }}" />
|
||||||
|
@ -138,6 +138,46 @@ export class SettingsViewModel extends observable.Observable {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public promptNumber(args: observable.EventData) {
|
||||||
|
dialogs.prompt({
|
||||||
|
title: "Name",
|
||||||
|
message: "Enter a number:",
|
||||||
|
cancelButtonText: "Cancel",
|
||||||
|
neutralButtonText: "Ignore",
|
||||||
|
okButtonText: "OK",
|
||||||
|
defaultText: "1234",
|
||||||
|
inputType: dialogs.inputType.number
|
||||||
|
}).then((promptResult) => {
|
||||||
|
console.log("### Result: " + promptResult.result + ", Text: " + promptResult.text);
|
||||||
|
if (promptResult.result) {
|
||||||
|
this.set("name", promptResult.text);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.set("name", "1234");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public promptPhone(args: observable.EventData) {
|
||||||
|
dialogs.prompt({
|
||||||
|
title: "Name",
|
||||||
|
message: "Enter a phone:",
|
||||||
|
cancelButtonText: "Cancel",
|
||||||
|
neutralButtonText: "Ignore",
|
||||||
|
okButtonText: "OK",
|
||||||
|
defaultText: "1234",
|
||||||
|
inputType: dialogs.inputType.phone
|
||||||
|
}).then((promptResult) => {
|
||||||
|
console.log("### Result: " + promptResult.result + ", Text: " + promptResult.text);
|
||||||
|
if (promptResult.result) {
|
||||||
|
this.set("name", promptResult.text);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.set("name", "1234");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public promptCapitalizationNone(args: observable.EventData) {
|
public promptCapitalizationNone(args: observable.EventData) {
|
||||||
dialogs.prompt({
|
dialogs.prompt({
|
||||||
title: "Name",
|
title: "Name",
|
||||||
|
@ -209,8 +209,8 @@ export function waitUntilNavigatedTo(page: Page, action: Function) {
|
|||||||
TKUnit.waitUntilReady(() => completed, 5);
|
TKUnit.waitUntilReady(() => completed, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function waitUntilNavigatedFrom(action: Function) {
|
export function waitUntilNavigatedFrom(action: Function, topFrame?: frame.Frame) {
|
||||||
const currentPage = frame.topmost().currentPage;
|
const currentPage = topFrame ? topFrame.currentPage : frame.topmost().currentPage;
|
||||||
let completed = false;
|
let completed = false;
|
||||||
function navigatedFrom(args) {
|
function navigatedFrom(args) {
|
||||||
args.object.page.off("navigatedFrom", navigatedFrom);
|
args.object.page.off("navigatedFrom", navigatedFrom);
|
||||||
@ -226,19 +226,19 @@ export function waitUntilLayoutReady(view: View): void {
|
|||||||
TKUnit.waitUntilReady(() => view.isLayoutValid);
|
TKUnit.waitUntilReady(() => view.isLayoutValid);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function navigateWithEntry(entry: frame.NavigationEntry): Page {
|
export function navigateWithEntry(entry: frame.NavigationEntry, topFrame?: frame.Frame): Page {
|
||||||
const page = createViewFromEntry(entry) as Page;
|
const page = createViewFromEntry(entry) as Page;
|
||||||
entry.moduleName = null;
|
entry.moduleName = null;
|
||||||
entry.create = function () {
|
entry.create = function () {
|
||||||
return page;
|
return page;
|
||||||
};
|
};
|
||||||
|
|
||||||
waitUntilNavigatedFrom(() => frame.topmost().navigate(entry));
|
waitUntilNavigatedFrom(() => topFrame ? topFrame.navigate(entry) : frame.topmost().navigate(entry));
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function goBack() {
|
export function goBack(topFrame?: frame.Frame) {
|
||||||
waitUntilNavigatedFrom(() => frame.topmost().goBack());
|
waitUntilNavigatedFrom(() => topFrame ? topFrame.goBack() : frame.topmost().goBack());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function assertAreClose(actual: number, expected: number, message: string): void {
|
export function assertAreClose(actual: number, expected: number, message: string): void {
|
||||||
|
@ -6,6 +6,8 @@ import * as platform from "tns-core-modules/platform";
|
|||||||
import { ios as iosUtils } from "tns-core-modules/utils/utils";
|
import { ios as iosUtils } from "tns-core-modules/utils/utils";
|
||||||
import * as helper from "../helper";
|
import * as helper from "../helper";
|
||||||
import { parse } from "tns-core-modules/ui/builder";
|
import { parse } from "tns-core-modules/ui/builder";
|
||||||
|
import { Page } from "tns-core-modules/ui/page";
|
||||||
|
import { Label } from "tns-core-modules/ui/label";
|
||||||
import {
|
import {
|
||||||
dipToDp, left, top, right, bottom, height, width,
|
dipToDp, left, top, right, bottom, height, width,
|
||||||
equal, closeEnough, lessOrCloseEnough, greaterOrCloseEnough, check,
|
equal, closeEnough, lessOrCloseEnough, greaterOrCloseEnough, check,
|
||||||
@ -37,6 +39,30 @@ export class SafeAreaTests extends testModule.UITest<any> {
|
|||||||
// no operation
|
// no operation
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public test_layout_changed_event_count() {
|
||||||
|
const page = <Page>parse(`
|
||||||
|
<Page>
|
||||||
|
<GridLayout id="grid" backgroundColor="Crimson">
|
||||||
|
<Label id="label" text="label1" backgroundColor="Gold"></Label>
|
||||||
|
</GridLayout>
|
||||||
|
</Page>
|
||||||
|
`);
|
||||||
|
let gridLayoutChangedCounter = 0;
|
||||||
|
let labelLayoutChangedCounter = 0;
|
||||||
|
const grid = page.getViewById("grid");
|
||||||
|
grid.on(view.View.layoutChangedEvent, () => {
|
||||||
|
gridLayoutChangedCounter++;
|
||||||
|
});
|
||||||
|
const label = <Label>page.getViewById("label");
|
||||||
|
label.on(view.View.layoutChangedEvent, () => {
|
||||||
|
labelLayoutChangedCounter++;
|
||||||
|
});
|
||||||
|
helper.navigate(() => page);
|
||||||
|
label.height = 100;
|
||||||
|
TKUnit.waitUntilReady(() => labelLayoutChangedCounter === 2);
|
||||||
|
TKUnit.assert(gridLayoutChangedCounter === 1, `${grid} layoutChanged event count - actual:${gridLayoutChangedCounter}; expected: 1`)
|
||||||
|
}
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
private getViews(template: string) {
|
private getViews(template: string) {
|
||||||
let root = parse(template);
|
let root = parse(template);
|
||||||
|
@ -4,7 +4,7 @@ import { isIOS, isAndroid } from "tns-core-modules/platform";
|
|||||||
import { Label } from "tns-core-modules/ui/label";
|
import { Label } from "tns-core-modules/ui/label";
|
||||||
import { StackLayout } from "tns-core-modules/ui/layouts/stack-layout";
|
import { StackLayout } from "tns-core-modules/ui/layouts/stack-layout";
|
||||||
import * as frameModule from "tns-core-modules/ui/frame";
|
import * as frameModule from "tns-core-modules/ui/frame";
|
||||||
import { Page } from "tns-core-modules/ui/page";
|
import { Page, NavigatedData } from "tns-core-modules/ui/page";
|
||||||
import { ListView, ItemEventData } from "tns-core-modules/ui/list-view";
|
import { ListView, ItemEventData } from "tns-core-modules/ui/list-view";
|
||||||
import { TabView, TabViewItem } from "tns-core-modules/ui/tab-view";
|
import { TabView, TabViewItem } from "tns-core-modules/ui/tab-view";
|
||||||
import { Button } from "tns-core-modules/ui/button";
|
import { Button } from "tns-core-modules/ui/button";
|
||||||
@ -68,6 +68,56 @@ function _clickHandlerFactory(index: number) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _createFrameView(): frameModule.Frame {
|
||||||
|
const frame = new frameModule.Frame();
|
||||||
|
frame.navigate({ create: () => new Page() });
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function testBackNavigationToTabViewWithNestedFramesShouldWork() {
|
||||||
|
// https://github.com/NativeScript/NativeScript/issues/6490
|
||||||
|
const topFrame = frameModule.topmost();
|
||||||
|
|
||||||
|
let tabViewPage: Page;
|
||||||
|
let tabView: TabView;
|
||||||
|
|
||||||
|
const pageFactory = function (): Page {
|
||||||
|
tabView = _createTabView();
|
||||||
|
let items = Array<TabViewItem>();
|
||||||
|
let tabViewitem = new TabViewItem();
|
||||||
|
tabViewitem.title = "Item1";
|
||||||
|
tabViewitem.view = _createFrameView();
|
||||||
|
items.push(tabViewitem);
|
||||||
|
|
||||||
|
let tabViewitem2 = new TabViewItem();
|
||||||
|
tabViewitem2.title = "Item2";
|
||||||
|
tabViewitem2.view = _createFrameView();
|
||||||
|
items.push(tabViewitem2);
|
||||||
|
|
||||||
|
tabView.items = items;
|
||||||
|
|
||||||
|
tabViewPage = new Page();
|
||||||
|
tabViewPage.id = "tab-view-page";
|
||||||
|
tabViewPage.content = tabView;
|
||||||
|
|
||||||
|
return tabViewPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
helper.waitUntilNavigatedFrom(() => topFrame.navigate(pageFactory), topFrame);
|
||||||
|
|
||||||
|
TKUnit.waitUntilReady(() => topFrame.currentPage === tabViewPage);
|
||||||
|
TKUnit.waitUntilReady(() => tabViewIsFullyLoaded(tabView));
|
||||||
|
|
||||||
|
// navigate to a different page
|
||||||
|
helper.waitUntilNavigatedFrom(() => topFrame.navigate({ create: () => new Page(), animated: false }), topFrame);
|
||||||
|
|
||||||
|
// navigate back to the page that hold the tabview with nested frames
|
||||||
|
topFrame.goBack();
|
||||||
|
|
||||||
|
// make sure the app did not crash
|
||||||
|
TKUnit.waitUntilReady(() => topFrame.navigationQueueIsEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
export function testWhenNavigatingBackToANonCachedPageContainingATabViewWithAListViewTheListViewIsThere() {
|
export function testWhenNavigatingBackToANonCachedPageContainingATabViewWithAListViewTheListViewIsThere() {
|
||||||
var topFrame = frameModule.topmost();
|
var topFrame = frameModule.topmost();
|
||||||
|
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
"nativescript": {
|
"nativescript": {
|
||||||
"id": "org.nativescript.UnitTestApp",
|
"id": "org.nativescript.UnitTestApp",
|
||||||
"tns-ios": {
|
"tns-ios": {
|
||||||
"version": "4.2.0"
|
"version": "5.0.0"
|
||||||
},
|
},
|
||||||
"tns-android": {
|
"tns-android": {
|
||||||
"version": "4.2.0"
|
"version": "5.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "tns-core-modules",
|
"name": "tns-core-modules",
|
||||||
"description": "Telerik NativeScript Core Modules",
|
"description": "Telerik NativeScript Core Modules",
|
||||||
"version": "5.0.2",
|
"version": "5.1.0",
|
||||||
"homepage": "https://www.nativescript.org",
|
"homepage": "https://www.nativescript.org",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -26,7 +26,7 @@
|
|||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"typings": "tns-core-modules.d.ts",
|
"typings": "tns-core-modules.d.ts",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tns-core-modules-widgets": "5.0.1",
|
"tns-core-modules-widgets": "next",
|
||||||
"tslib": "^1.9.3"
|
"tslib": "^1.9.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -190,6 +190,9 @@ export class View extends ViewCommon {
|
|||||||
} else if (!this._isLaidOut) {
|
} else if (!this._isLaidOut) {
|
||||||
// Rects could be equal on the first layout and an event should be raised.
|
// Rects could be equal on the first layout and an event should be raised.
|
||||||
this._raiseLayoutChangedEvent();
|
this._raiseLayoutChangedEvent();
|
||||||
|
// But make sure event is raised only once if rects are equal on the first layout as
|
||||||
|
// this method is called twice with equal rects in landscape mode (vs only once in portrait)
|
||||||
|
this._isLaidOut = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,16 @@ export module inputType {
|
|||||||
* Email input type.
|
* Email input type.
|
||||||
*/
|
*/
|
||||||
export const email: string = "email";
|
export const email: string = "email";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number input type
|
||||||
|
*/
|
||||||
|
export const number: string = "number";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Phone input type
|
||||||
|
*/
|
||||||
|
export const phone: string = "phone";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -184,6 +184,10 @@ export function prompt(arg: any): Promise<PromptResult> {
|
|||||||
input.setInputType(android.text.InputType.TYPE_CLASS_TEXT | android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
input.setInputType(android.text.InputType.TYPE_CLASS_TEXT | android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
||||||
} else if (options.inputType === inputType.email) {
|
} else if (options.inputType === inputType.email) {
|
||||||
input.setInputType(android.text.InputType.TYPE_CLASS_TEXT | android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
|
input.setInputType(android.text.InputType.TYPE_CLASS_TEXT | android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
|
||||||
|
} else if (options.inputType === inputType.number) {
|
||||||
|
input.setInputType(android.text.InputType.TYPE_CLASS_NUMBER);
|
||||||
|
} else if (options.inputType === inputType.phone) {
|
||||||
|
input.setInputType(android.text.InputType.TYPE_CLASS_PHONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (options.capitalizationType) {
|
switch (options.capitalizationType) {
|
||||||
|
16
tns-core-modules/ui/dialogs/dialogs.d.ts
vendored
16
tns-core-modules/ui/dialogs/dialogs.d.ts
vendored
@ -21,6 +21,16 @@ export module inputType {
|
|||||||
* Email input type.
|
* Email input type.
|
||||||
*/
|
*/
|
||||||
export var email: string;
|
export var email: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number input type.
|
||||||
|
*/
|
||||||
|
export var number: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Phone input type.
|
||||||
|
*/
|
||||||
|
export var phone: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -81,7 +91,7 @@ export function prompt(message: string, defaultText?: string): Promise<PromptRes
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The prompt() method displays a dialog box that prompts the visitor for input.
|
* The prompt() method displays a dialog box that prompts the visitor for input.
|
||||||
* @param options The options for the dialog box.
|
* @param options The options for the dialog box.
|
||||||
*/
|
*/
|
||||||
export function prompt(options: PromptOptions): Promise<PromptResult>;
|
export function prompt(options: PromptOptions): Promise<PromptResult>;
|
||||||
|
|
||||||
@ -95,7 +105,7 @@ export function login(message: string, userName?: string, password?: string): Pr
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The login() method displays a login dialog box that prompts the visitor for user name and password.
|
* The login() method displays a login dialog box that prompts the visitor for user name and password.
|
||||||
* @param options The options for the dialog box.
|
* @param options The options for the dialog box.
|
||||||
*/
|
*/
|
||||||
export function login(options: LoginOptions): Promise<LoginResult>;
|
export function login(options: LoginOptions): Promise<LoginResult>;
|
||||||
|
|
||||||
@ -109,7 +119,7 @@ export function action(message: string, cancelButtonText: string, actions: Array
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The action() method displays a action box that prompts the visitor to choose some action.
|
* The action() method displays a action box that prompts the visitor to choose some action.
|
||||||
* @param options The options for the dialog box.
|
* @param options The options for the dialog box.
|
||||||
*/
|
*/
|
||||||
export function action(options: ActionOptions): Promise<string>;
|
export function action(options: ActionOptions): Promise<string>;
|
||||||
|
|
||||||
|
@ -104,6 +104,10 @@ export function prompt(arg: any): Promise<PromptResult> {
|
|||||||
|
|
||||||
if (options && options.inputType === inputType.email) {
|
if (options && options.inputType === inputType.email) {
|
||||||
arg.keyboardType = UIKeyboardType.EmailAddress;
|
arg.keyboardType = UIKeyboardType.EmailAddress;
|
||||||
|
} else if (options && options.inputType === inputType.number) {
|
||||||
|
arg.keyboardType = UIKeyboardType.NumberPad;
|
||||||
|
} else if (options && options.inputType === inputType.phone) {
|
||||||
|
arg.keyboardType = UIKeyboardType.PhonePad;
|
||||||
}
|
}
|
||||||
|
|
||||||
let color = getTextFieldColor();
|
let color = getTextFieldColor();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "tns-platform-declarations",
|
"name": "tns-platform-declarations",
|
||||||
"version": "5.0.2",
|
"version": "5.1.0",
|
||||||
"description": "Platform-specific TypeScript declarations for NativeScript for accessing native objects",
|
"description": "Platform-specific TypeScript declarations for NativeScript for accessing native objects",
|
||||||
"main": "",
|
"main": "",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
Reference in New Issue
Block a user