mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
Merged with master after the transitions feature
This commit is contained in:
@@ -83,7 +83,12 @@
|
||||
<DependentUpon>data-binding.xml</DependentUpon>
|
||||
</TypeScriptCompile>
|
||||
<TypeScriptCompile Include="apps\animations\opacity.ts" />
|
||||
<TypeScriptCompile Include="apps\perf-tests\NavigationTest\list-picker-page.ts" />
|
||||
<TypeScriptCompile Include="apps\perf-tests\custom-transition.android.ts" />
|
||||
<TypeScriptCompile Include="apps\perf-tests\custom-transition.ios.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\layouts\common-layout-tests.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\navigation\custom-transition.android.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\navigation\custom-transition.ios.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\ui\action-bar\ActionBar_NumberAsText.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\ui\page\modal-page.ts">
|
||||
<DependentUpon>modal-page.xml</DependentUpon>
|
||||
@@ -130,6 +135,7 @@
|
||||
</Content>
|
||||
<Content Include="apps\animations\bkg.png" />
|
||||
<Content Include="apps\animations\test-icon.png" />
|
||||
<Content Include="apps\perf-tests\NavigationTest\list-picker-page.xml" />
|
||||
<Content Include="apps\tests\ui\action-bar\ActionBar_BetweenTags.xml" />
|
||||
<Content Include="apps\tests\ui\action-bar\ActionBar_NumberAsText.xml" />
|
||||
<Content Include="apps\tests\ui\page\modal-page.xml">
|
||||
@@ -175,7 +181,7 @@
|
||||
</TypeScriptCompile>
|
||||
<TypeScriptCompile Include="apps\animations\model.ts" />
|
||||
<TypeScriptCompile Include="apps\orientation-demo\main-page.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\navigation-tests.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\navigation\navigation-tests.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\ui\page\page21.ts">
|
||||
<DependentUpon>page21.xml</DependentUpon>
|
||||
</TypeScriptCompile>
|
||||
@@ -209,11 +215,13 @@
|
||||
<Content Include="apps\ui-tests-app\css\decoration-transform-formattedtext.xml" />
|
||||
<Content Include="apps\ui-tests-app\css\text-decoration.xml" />
|
||||
<Content Include="apps\ui-tests-app\css\text-transform.xml" />
|
||||
<Content Include="apps\ui-tests-app\css\tab-view.xml" />
|
||||
<Content Include="apps\ui-tests-app\css\text.css" />
|
||||
<Content Include="apps\ui-tests-app\css\tab-view-more.xml" />
|
||||
<Content Include="apps\ui-tests-app\css\test.css" />
|
||||
<Content Include="apps\ui-tests-app\css\white-space.xml">
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
<Content Include="apps\ui-tests-app\font\material-icons.xml" />
|
||||
<Content Include="apps\ui-tests-app\font\tab-view.xml" />
|
||||
<Content Include="apps\ui-tests-app\html-view\html-view.xml">
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
@@ -737,6 +745,14 @@
|
||||
<TypeScriptCompile Include="ui\text-base\text-base-styler.android.ts" />
|
||||
<TypeScriptCompile Include="ui\text-base\text-base-styler.d.ts" />
|
||||
<TypeScriptCompile Include="ui\text-base\text-base-styler.ios.ts" />
|
||||
<TypeScriptCompile Include="ui\transition\flip-transition.android.ts" />
|
||||
<TypeScriptCompile Include="ui\transition\fade-transition.android.ts" />
|
||||
<TypeScriptCompile Include="ui\transition\slide-transition.ios.ts" />
|
||||
<TypeScriptCompile Include="ui\transition\slide-transition.android.ts" />
|
||||
<TypeScriptCompile Include="ui\transition\fade-transition.ios.ts" />
|
||||
<TypeScriptCompile Include="ui\transition\transition.android.ts" />
|
||||
<TypeScriptCompile Include="ui\transition\transition.d.ts" />
|
||||
<TypeScriptCompile Include="ui\transition\transition.ios.ts" />
|
||||
<TypeScriptCompile Include="ui\ui.d.ts" />
|
||||
<TypeScriptCompile Include="ui\html-view\html-view-common.ts" />
|
||||
<TypeScriptCompile Include="ui\html-view\html-view.android.ts" />
|
||||
@@ -2093,6 +2109,9 @@
|
||||
<Content Include="ui\package.json" />
|
||||
<Content Include="tsconfig.json" />
|
||||
<Content Include="ui\proxy-view-container\package.json" />
|
||||
<Content Include="ui\transition\package.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="build\tslint.json" />
|
||||
|
||||
@@ -4,13 +4,23 @@ import navPageModule = require("../nav-page");
|
||||
import trace = require("trace");
|
||||
trace.enable();
|
||||
trace.setCategories(trace.categories.concat(
|
||||
trace.categories.NativeLifecycle
|
||||
, trace.categories.Navigation
|
||||
trace.categories.NativeLifecycle,
|
||||
trace.categories.Navigation,
|
||||
//trace.categories.Animation,
|
||||
trace.categories.Transition
|
||||
));
|
||||
|
||||
application.mainEntry = {
|
||||
create: function () {
|
||||
return new navPageModule.NavPage(0);
|
||||
return new navPageModule.NavPage({
|
||||
index: 0,
|
||||
backStackVisible: true,
|
||||
clearHistory: false,
|
||||
animated: true,
|
||||
transition: 0,
|
||||
curve: 0,
|
||||
duration: 0,
|
||||
});
|
||||
}
|
||||
//backstackVisible: false,
|
||||
//clearHistory: true
|
||||
|
||||
21
apps/perf-tests/NavigationTest/list-picker-page.ts
Normal file
21
apps/perf-tests/NavigationTest/list-picker-page.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import {Page, ShownModallyData, ListPicker} from "ui";
|
||||
|
||||
var closeCallback: Function;
|
||||
var page: Page;
|
||||
var listPicker: ListPicker;
|
||||
|
||||
export function onLoaded(args) {
|
||||
page = <Page>args.object;
|
||||
listPicker = page.getViewById<ListPicker>("listPicker");
|
||||
}
|
||||
|
||||
export function onShownModally(args) {
|
||||
closeCallback = args.closeCallback;
|
||||
|
||||
listPicker.items = args.context.items;
|
||||
listPicker.selectedIndex = args.context.selectedIndex || 0;
|
||||
}
|
||||
|
||||
export function onButtonTap() {
|
||||
closeCallback(listPicker.selectedIndex);
|
||||
}
|
||||
6
apps/perf-tests/NavigationTest/list-picker-page.xml
Normal file
6
apps/perf-tests/NavigationTest/list-picker-page.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="onLoaded" shownModally="onShownModally" style.backgroundColor="lightgray">
|
||||
<StackLayout>
|
||||
<ListPicker id="listPicker"/>
|
||||
<Button text="Done" tap="onButtonTap"/>
|
||||
</StackLayout>
|
||||
</Page>
|
||||
35
apps/perf-tests/custom-transition.android.ts
Normal file
35
apps/perf-tests/custom-transition.android.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import transition = require("ui/transition");
|
||||
import platform = require("platform");
|
||||
|
||||
var floatType = java.lang.Float.class.getField("TYPE").get(null);
|
||||
|
||||
export class CustomTransition extends transition.Transition {
|
||||
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
||||
var scaleValues = java.lang.reflect.Array.newInstance(floatType, 2);
|
||||
switch (transitionType) {
|
||||
case transition.AndroidTransitionType.enter:
|
||||
case transition.AndroidTransitionType.popEnter:
|
||||
scaleValues[0] = 0;
|
||||
scaleValues[1] = 1;
|
||||
break;
|
||||
case transition.AndroidTransitionType.exit:
|
||||
case transition.AndroidTransitionType.popExit:
|
||||
scaleValues[0] = 1;
|
||||
scaleValues[1] = 0;
|
||||
break;
|
||||
}
|
||||
var objectAnimators = java.lang.reflect.Array.newInstance(android.animation.Animator.class, 2);
|
||||
objectAnimators[0] = android.animation.ObjectAnimator.ofFloat(null, "scaleX", scaleValues);
|
||||
objectAnimators[1] = android.animation.ObjectAnimator.ofFloat(null, "scaleY", scaleValues);
|
||||
var animatorSet = new android.animation.AnimatorSet();
|
||||
animatorSet.playTogether(objectAnimators);
|
||||
|
||||
var duration = this.getDuration();
|
||||
if (duration !== undefined) {
|
||||
animatorSet.setDuration(duration);
|
||||
}
|
||||
animatorSet.setInterpolator(this.getCurve());
|
||||
|
||||
return animatorSet;
|
||||
}
|
||||
}
|
||||
26
apps/perf-tests/custom-transition.ios.ts
Normal file
26
apps/perf-tests/custom-transition.ios.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import transition = require("ui/transition");
|
||||
import platform = require("platform");
|
||||
|
||||
export class CustomTransition extends transition.Transition {
|
||||
public animateIOSTransition(containerView: UIView, fromView: UIView, toView: UIView, operation: UINavigationControllerOperation, completion: (finished: boolean) => void): void {
|
||||
toView.transform = CGAffineTransformMakeScale(0, 0);
|
||||
fromView.transform = CGAffineTransformIdentity;
|
||||
|
||||
switch (operation) {
|
||||
case UINavigationControllerOperation.UINavigationControllerOperationPush:
|
||||
containerView.insertSubviewAboveSubview(toView, fromView);
|
||||
break;
|
||||
case UINavigationControllerOperation.UINavigationControllerOperationPop:
|
||||
containerView.insertSubviewBelowSubview(toView, fromView);
|
||||
break;
|
||||
}
|
||||
|
||||
var duration = this.getDuration();
|
||||
var curve = this.getCurve();
|
||||
UIView.animateWithDurationAnimationsCompletion(duration, () => {
|
||||
UIView.setAnimationCurve(curve);
|
||||
toView.transform = CGAffineTransformIdentity;
|
||||
fromView.transform = CGAffineTransformMakeScale(0, 0);
|
||||
}, completion);
|
||||
}
|
||||
}
|
||||
@@ -1,82 +1,194 @@
|
||||
import definition = require("controls-page");
|
||||
import frameModule = require("ui/frame");
|
||||
import pagesModule = require("ui/page");
|
||||
import stackLayoutModule = require("ui/layouts/stack-layout");
|
||||
import labelModule = require("ui/label");
|
||||
import buttonModule = require("ui/button");
|
||||
import textFieldModule = require("ui/text-field");
|
||||
import enums = require("ui/enums");
|
||||
import switchModule = require("ui/switch");
|
||||
import {View, Page, topmost as topmostFrame, NavigationTransition, Orientation, AnimationCurve, StackLayout, Button, Label, TextField, Switch, ListPicker, Slider} from "ui";
|
||||
import {Color} from "color";
|
||||
import platform = require("platform");
|
||||
|
||||
export class NavPage extends pagesModule.Page implements definition.ControlsPage {
|
||||
constructor(id: number) {
|
||||
var availableTransitions = ["default", "custom", "flip", "flipRight", "flipLeft", "slide", "slideLeft", "slideRight", "slideTop", "slideBottom", "fade"];
|
||||
if (platform.device.os === platform.platformNames.ios) {
|
||||
availableTransitions = availableTransitions.concat(["curl", "curlUp", "curlDown"]);
|
||||
}
|
||||
else {
|
||||
availableTransitions = availableTransitions.concat(["explode"]);
|
||||
}
|
||||
|
||||
var availableCurves = [AnimationCurve.easeInOut, AnimationCurve.easeIn, AnimationCurve.easeOut, AnimationCurve.linear];
|
||||
|
||||
export interface Context {
|
||||
index: number;
|
||||
backStackVisible: boolean;
|
||||
clearHistory: boolean;
|
||||
animated: boolean;
|
||||
transition: number;
|
||||
curve: number;
|
||||
duration: number;
|
||||
}
|
||||
|
||||
export class NavPage extends Page implements definition.ControlsPage {
|
||||
constructor(context: Context) {
|
||||
super();
|
||||
|
||||
this.id = "NavPage " + id;
|
||||
var that = this;
|
||||
that.on(View.loadedEvent, (args) => {
|
||||
console.log(`${args.object}.loadedEvent`);
|
||||
if (topmostFrame().android) {
|
||||
topmostFrame().android.cachePagesOnNavigate = true;
|
||||
}
|
||||
});
|
||||
that.on(View.unloadedEvent, (args) => {
|
||||
console.log(`${args.object}.unloadedEvent`);
|
||||
});
|
||||
that.on(Page.navigatingFromEvent, (args) => {
|
||||
console.log(`${args.object}.navigatingFromEvent`);
|
||||
});
|
||||
that.on(Page.navigatedFromEvent, (args) => {
|
||||
console.log(`${args.object}.navigatedFromEvent`);
|
||||
});
|
||||
that.on(Page.navigatingToEvent, (args) => {
|
||||
console.log(`${args.object}.navigatingToEvent`);
|
||||
});
|
||||
that.on(Page.navigatedToEvent, (args) => {
|
||||
console.log(`${args.object}.navigatedToEvent`);
|
||||
});
|
||||
|
||||
var stackLayout = new stackLayoutModule.StackLayout();
|
||||
stackLayout.orientation = enums.Orientation.vertical;
|
||||
this.id = "" + context.index;
|
||||
|
||||
var goBackButton = new buttonModule.Button();
|
||||
goBackButton.text = "<-";
|
||||
goBackButton.on(buttonModule.Button.tapEvent, function () {
|
||||
frameModule.topmost().goBack();
|
||||
var bg = new Color(255, Math.round(Math.random() * 255), Math.round(Math.random() * 255), Math.round(Math.random() * 255));
|
||||
this.style.backgroundColor = bg;
|
||||
|
||||
var stackLayout = new StackLayout();
|
||||
stackLayout.orientation = Orientation.vertical;
|
||||
|
||||
var goBackButton = new Button();
|
||||
goBackButton.text = "<=";
|
||||
goBackButton.style.fontSize = 18;
|
||||
goBackButton.on(Button.tapEvent, () => {
|
||||
topmostFrame().goBack();
|
||||
});
|
||||
stackLayout.addChild(goBackButton);
|
||||
|
||||
this.on(pagesModule.Page.navigatedToEvent, function () {
|
||||
this.on(Page.navigatedToEvent, function () {
|
||||
//console.log("Navigated to NavPage " + id + "; backStack.length: " + frameModule.topmost().backStack.length);
|
||||
goBackButton.isEnabled = frameModule.topmost().canGoBack();
|
||||
goBackButton.isEnabled = topmostFrame().canGoBack();
|
||||
});
|
||||
|
||||
var stateLabel = new labelModule.Label();
|
||||
stateLabel.text = "NavPage " + id;
|
||||
var stateLabel = new Label();
|
||||
stateLabel.text = `${this.id} (${(<any>bg)._hex})`;
|
||||
stackLayout.addChild(stateLabel);
|
||||
|
||||
var textField = new textFieldModule.TextField();
|
||||
var textField = new TextField();
|
||||
textField.text = "";
|
||||
stackLayout.addChild(textField);
|
||||
|
||||
var changeStateButton = new buttonModule.Button();
|
||||
var changeStateButton = new Button();
|
||||
changeStateButton.text = "Click me!"
|
||||
var clickCount = 0;
|
||||
changeStateButton.on(buttonModule.Button.tapEvent, () => {
|
||||
//stateLabel.text = "<<<CHANGED STATE>>>";
|
||||
//textField.text = "<<<CHANGED STATE>>>";
|
||||
changeStateButton.on(Button.tapEvent, () => {
|
||||
changeStateButton.text = (clickCount++).toString();
|
||||
});
|
||||
stackLayout.addChild(changeStateButton);
|
||||
|
||||
var optionsLayout = new stackLayoutModule.StackLayout();
|
||||
var optionsLayout = new StackLayout();
|
||||
|
||||
var addToBackStackLabel = new labelModule.Label();
|
||||
var addToBackStackLabel = new Label();
|
||||
addToBackStackLabel.text = "backStackVisible";
|
||||
optionsLayout.addChild(addToBackStackLabel);
|
||||
|
||||
var addToBackStackSwitch = new switchModule.Switch();
|
||||
addToBackStackSwitch.checked = true;
|
||||
var addToBackStackSwitch = new Switch();
|
||||
addToBackStackSwitch.checked = context.backStackVisible;
|
||||
optionsLayout.addChild(addToBackStackSwitch);
|
||||
|
||||
var clearHistoryLabel = new labelModule.Label();
|
||||
var clearHistoryLabel = new Label();
|
||||
clearHistoryLabel.text = "clearHistory";
|
||||
optionsLayout.addChild(clearHistoryLabel);
|
||||
|
||||
var clearHistorySwitch = new switchModule.Switch();
|
||||
clearHistorySwitch.checked = false;
|
||||
var clearHistorySwitch = new Switch();
|
||||
clearHistorySwitch.checked = context.clearHistory;
|
||||
optionsLayout.addChild(clearHistorySwitch);
|
||||
|
||||
var animatedLabel = new Label();
|
||||
animatedLabel.text = "animated";
|
||||
optionsLayout.addChild(animatedLabel);
|
||||
|
||||
var animatedSwitch = new Switch();
|
||||
animatedSwitch.checked = context.animated;
|
||||
optionsLayout.addChild(animatedSwitch);
|
||||
|
||||
var transitionButton = new Button();
|
||||
transitionButton.text = availableTransitions[context.transition];
|
||||
transitionButton.on("tap", () => {
|
||||
that.showModal("perf-tests/NavigationTest/list-picker-page", { items: availableTransitions, selectedIndex: context.transition }, (selectedIndex: number) => {
|
||||
context.transition = selectedIndex;
|
||||
transitionButton.text = availableTransitions[context.transition];
|
||||
}, true);
|
||||
});
|
||||
optionsLayout.addChild(transitionButton);
|
||||
|
||||
var curveButton = new Button();
|
||||
curveButton.text = availableCurves[context.curve];
|
||||
curveButton.on(Button.tapEvent, () => {
|
||||
that.showModal("perf-tests/NavigationTest/list-picker-page", { items: availableCurves, selectedIndex: context.curve }, (selectedIndex: number) => {
|
||||
context.curve = selectedIndex;
|
||||
curveButton.text = availableCurves[context.curve]
|
||||
}, true);
|
||||
});
|
||||
optionsLayout.addChild(curveButton);
|
||||
|
||||
var durationLabel = new Label();
|
||||
durationLabel.text = "Duration";
|
||||
optionsLayout.addChild(durationLabel);
|
||||
|
||||
var durationSlider = new Slider();
|
||||
durationSlider.minValue = 0;
|
||||
durationSlider.maxValue = 10000;
|
||||
durationSlider.value = context.duration;
|
||||
optionsLayout.addChild(durationSlider);
|
||||
|
||||
stackLayout.addChild(optionsLayout);
|
||||
|
||||
var forwardButton = new buttonModule.Button();
|
||||
forwardButton.text = "->";
|
||||
forwardButton.on(buttonModule.Button.tapEvent, function () {
|
||||
var forwardButton = new Button();
|
||||
forwardButton.text = "=>";
|
||||
forwardButton.style.fontSize = 18;
|
||||
forwardButton.on(Button.tapEvent, () => {
|
||||
var pageFactory = function () {
|
||||
return new NavPage(id + 1);
|
||||
return new NavPage({
|
||||
index: context.index + 1,
|
||||
backStackVisible: addToBackStackSwitch.checked,
|
||||
clearHistory: clearHistorySwitch.checked,
|
||||
animated: animatedSwitch.checked,
|
||||
transition: context.transition,
|
||||
curve: context.curve,
|
||||
duration: durationSlider.value,
|
||||
});
|
||||
};
|
||||
frameModule.topmost().navigate({
|
||||
|
||||
var navigationTransition: NavigationTransition;
|
||||
if (context.transition) {// Different from default
|
||||
var transitionName = availableTransitions[context.transition];
|
||||
var duration = durationSlider.value !== 0 ? durationSlider.value : undefined;
|
||||
var curve = context.curve ? availableCurves[context.curve] : undefined;
|
||||
|
||||
if (transitionName === "custom") {
|
||||
var customTransitionModule = require("./custom-transition");
|
||||
var customTransition = new customTransitionModule.CustomTransition(duration, curve);
|
||||
navigationTransition = {
|
||||
transition: customTransition
|
||||
};
|
||||
}
|
||||
else {
|
||||
navigationTransition = {
|
||||
transition: transitionName,
|
||||
duration: duration,
|
||||
curve: curve
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
topmostFrame().navigate({
|
||||
create: pageFactory,
|
||||
backstackVisible: addToBackStackSwitch.checked,
|
||||
clearHistory: clearHistorySwitch.checked
|
||||
clearHistory: clearHistorySwitch.checked,
|
||||
animated: animatedSwitch.checked,
|
||||
navigationTransition: navigationTransition,
|
||||
});
|
||||
});
|
||||
stackLayout.addChild(forwardButton);
|
||||
|
||||
@@ -46,7 +46,15 @@ export function createPage() {
|
||||
stackLayout.addChild(navigateToAnotherPageButton);
|
||||
navigateToAnotherPageButton.on(buttonModule.Button.tapEvent, function () {
|
||||
var pageFactory = function () {
|
||||
return new navPageModule.NavPage(0);
|
||||
return new navPageModule.NavPage({
|
||||
index: 0,
|
||||
backStackVisible: true,
|
||||
clearHistory: false,
|
||||
animated: true,
|
||||
transition: 0,
|
||||
curve: 0,
|
||||
duration: 0,
|
||||
});
|
||||
};
|
||||
frameModule.topmost().navigate(pageFactory);
|
||||
});
|
||||
|
||||
@@ -7,6 +7,7 @@ trace.addCategories(trace.categories.Test + "," + trace.categories.Error);
|
||||
|
||||
let started = false;
|
||||
let page = new Page();
|
||||
page.id = "mainPage";
|
||||
|
||||
page.on(Page.navigatedToEvent, function () {
|
||||
if (!started) {
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
import TKUnit = require("./TKUnit");
|
||||
import pageModule = require("ui/page");
|
||||
import frame = require("ui/frame");
|
||||
import { Page } from "ui/page";
|
||||
|
||||
export var test_backstackVisible = function() {
|
||||
var pageFactory = function(): pageModule.Page {
|
||||
return new pageModule.Page();
|
||||
};
|
||||
|
||||
var mainTestPage = frame.topmost().currentPage;
|
||||
frame.topmost().navigate({ create: pageFactory });
|
||||
TKUnit.waitUntilReady(() => { return frame.topmost().currentPage !== mainTestPage; });
|
||||
|
||||
// page1 should not be added to the backstack
|
||||
var page0 = frame.topmost().currentPage;
|
||||
frame.topmost().navigate({ create: pageFactory, backstackVisible: false });
|
||||
TKUnit.waitUntilReady(() => { return frame.topmost().currentPage !== page0; });
|
||||
|
||||
var page1 = frame.topmost().currentPage;
|
||||
frame.topmost().navigate({ create: pageFactory });
|
||||
TKUnit.waitUntilReady(() => { return frame.topmost().currentPage !== page1; });
|
||||
|
||||
var page2 = frame.topmost().currentPage;
|
||||
frame.topmost().goBack();
|
||||
TKUnit.waitUntilReady(() => { return frame.topmost().currentPage !== page2; });
|
||||
|
||||
// From page2 we have to go directly to page0, skipping page1.
|
||||
TKUnit.assert(frame.topmost().currentPage === page0, "Page 1 should be skipped when going back.");
|
||||
|
||||
frame.topmost().goBack();
|
||||
TKUnit.waitUntilReady(() => { return frame.topmost().currentPage === mainTestPage; });
|
||||
}
|
||||
|
||||
export var test_backToEntry = function() {
|
||||
let page = (tag) => () => {
|
||||
var p = new Page();
|
||||
p["tag"] = tag;
|
||||
return p;
|
||||
}
|
||||
let topmost = frame.topmost();
|
||||
let wait = tag => TKUnit.waitUntilReady(() => topmost.currentPage["tag"] === tag, 1);
|
||||
let navigate = tag => {
|
||||
topmost.navigate({ create: page(tag) });
|
||||
wait(tag)
|
||||
}
|
||||
let back = pages => {
|
||||
topmost.goBack(topmost.backStack[topmost.backStack.length - pages]);
|
||||
}
|
||||
let currentPageMustBe = tag => {
|
||||
wait(tag); // TODO: Add a timeout...
|
||||
TKUnit.assert(topmost.currentPage["tag"] === tag, "Expected current page to be " + tag + " it was " + topmost.currentPage["tag"] + " instead.");
|
||||
}
|
||||
|
||||
navigate("page1");
|
||||
navigate("page2");
|
||||
navigate("page3");
|
||||
navigate("page4");
|
||||
|
||||
currentPageMustBe("page4");
|
||||
back(2);
|
||||
currentPageMustBe("page2");
|
||||
back(1);
|
||||
currentPageMustBe("page1");
|
||||
navigate("page1.1");
|
||||
navigate("page1.2");
|
||||
currentPageMustBe("page1.2");
|
||||
back(1);
|
||||
currentPageMustBe("page1.1");
|
||||
back(1);
|
||||
currentPageMustBe("page1");
|
||||
back(1);
|
||||
}
|
||||
|
||||
// Clearing the history messes up the tests app.
|
||||
export var test_ClearHistory = function () {
|
||||
var pageFactory = function(): pageModule.Page {
|
||||
return new pageModule.Page();
|
||||
};
|
||||
|
||||
var mainTestPage = frame.topmost().currentPage;
|
||||
var mainPageFactory = function(): pageModule.Page {
|
||||
return mainTestPage;
|
||||
};
|
||||
|
||||
var currentPage: pageModule.Page;
|
||||
|
||||
currentPage = frame.topmost().currentPage;
|
||||
frame.topmost().navigate({ create: pageFactory });
|
||||
TKUnit.waitUntilReady(() => { return frame.topmost().currentPage !== currentPage; });
|
||||
|
||||
currentPage = frame.topmost().currentPage;
|
||||
frame.topmost().navigate({ create: pageFactory });
|
||||
TKUnit.waitUntilReady(() => { return frame.topmost().currentPage !== currentPage; });
|
||||
|
||||
currentPage = frame.topmost().currentPage;
|
||||
frame.topmost().navigate({ create: pageFactory });
|
||||
TKUnit.waitUntilReady(() => { return frame.topmost().currentPage !== currentPage; });
|
||||
|
||||
TKUnit.assert(frame.topmost().canGoBack(), "Frame should be able to go back.");
|
||||
TKUnit.assert(frame.topmost().backStack.length === 3, "Back stack should have 3 entries.");
|
||||
|
||||
// Navigate with clear history.
|
||||
currentPage = frame.topmost().currentPage;
|
||||
frame.topmost().navigate({ create: pageFactory, clearHistory: true });
|
||||
TKUnit.waitUntilReady(() => { return frame.topmost().currentPage !== currentPage; });
|
||||
|
||||
TKUnit.assert(!frame.topmost().canGoBack(), "Frame should NOT be able to go back.");
|
||||
TKUnit.assert(frame.topmost().backStack.length === 0, "Back stack should have 0 entries.");
|
||||
|
||||
frame.topmost().navigate({ create: mainPageFactory });
|
||||
TKUnit.waitUntilReady(() => { return frame.topmost().currentPage === mainTestPage; });
|
||||
}
|
||||
39
apps/tests/navigation/custom-transition.android.ts
Normal file
39
apps/tests/navigation/custom-transition.android.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import transition = require("ui/transition");
|
||||
import platform = require("platform");
|
||||
|
||||
var floatType = java.lang.Float.class.getField("TYPE").get(null);
|
||||
|
||||
export class CustomTransition extends transition.Transition {
|
||||
constructor(duration: number, curve: any) {
|
||||
super(duration, curve);
|
||||
}
|
||||
|
||||
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
||||
var scaleValues = java.lang.reflect.Array.newInstance(floatType, 2);
|
||||
switch (transitionType) {
|
||||
case transition.AndroidTransitionType.enter:
|
||||
case transition.AndroidTransitionType.popEnter:
|
||||
scaleValues[0] = 0;
|
||||
scaleValues[1] = 1;
|
||||
break;
|
||||
case transition.AndroidTransitionType.exit:
|
||||
case transition.AndroidTransitionType.popExit:
|
||||
scaleValues[0] = 1;
|
||||
scaleValues[1] = 0;
|
||||
break;
|
||||
}
|
||||
var objectAnimators = java.lang.reflect.Array.newInstance(android.animation.Animator.class, 2);
|
||||
objectAnimators[0] = android.animation.ObjectAnimator.ofFloat(null, "scaleX", scaleValues);
|
||||
objectAnimators[1] = android.animation.ObjectAnimator.ofFloat(null, "scaleY", scaleValues);
|
||||
var animatorSet = new android.animation.AnimatorSet();
|
||||
animatorSet.playTogether(objectAnimators);
|
||||
|
||||
var duration = this.getDuration();
|
||||
if (duration !== undefined) {
|
||||
animatorSet.setDuration(duration);
|
||||
}
|
||||
animatorSet.setInterpolator(this.getCurve());
|
||||
|
||||
return animatorSet;
|
||||
}
|
||||
}
|
||||
30
apps/tests/navigation/custom-transition.ios.ts
Normal file
30
apps/tests/navigation/custom-transition.ios.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import transition = require("ui/transition");
|
||||
import platform = require("platform");
|
||||
|
||||
export class CustomTransition extends transition.Transition {
|
||||
constructor(duration: number, curve: any) {
|
||||
super(duration, curve);
|
||||
}
|
||||
|
||||
public animateIOSTransition(containerView: UIView, fromView: UIView, toView: UIView, operation: UINavigationControllerOperation, completion: (finished: boolean) => void): void {
|
||||
toView.transform = CGAffineTransformMakeScale(0, 0);
|
||||
fromView.transform = CGAffineTransformIdentity;
|
||||
|
||||
switch (operation) {
|
||||
case UINavigationControllerOperation.UINavigationControllerOperationPush:
|
||||
containerView.insertSubviewAboveSubview(toView, fromView);
|
||||
break;
|
||||
case UINavigationControllerOperation.UINavigationControllerOperationPop:
|
||||
containerView.insertSubviewBelowSubview(toView, fromView);
|
||||
break;
|
||||
}
|
||||
|
||||
var duration = this.getDuration();
|
||||
var curve = this.getCurve();
|
||||
UIView.animateWithDurationAnimationsCompletion(duration, () => {
|
||||
UIView.setAnimationCurve(curve);
|
||||
toView.transform = CGAffineTransformIdentity;
|
||||
fromView.transform = CGAffineTransformMakeScale(0, 0);
|
||||
}, completion);
|
||||
}
|
||||
}
|
||||
183
apps/tests/navigation/navigation-tests.ts
Normal file
183
apps/tests/navigation/navigation-tests.ts
Normal file
@@ -0,0 +1,183 @@
|
||||
import TKUnit = require("../TKUnit");
|
||||
import platform = require("platform");
|
||||
import transitionModule = require("ui/transition");
|
||||
import {Frame, Page, topmost as topmostFrame, NavigationEntry, NavigationTransition, AnimationCurve, WrapLayout, Button} from "ui";
|
||||
import color = require("color");
|
||||
import helper = require("../ui/helper");
|
||||
import utils = require("utils/utils");
|
||||
import trace = require("trace");
|
||||
|
||||
// Creates a random colorful page full of meaningless stuff.
|
||||
var pageFactory = function(): Page {
|
||||
var page = new Page();
|
||||
page.style.backgroundColor = new color.Color(255, Math.round(Math.random() * 255), Math.round(Math.random() * 255), Math.round(Math.random() * 255));
|
||||
return page;
|
||||
};
|
||||
|
||||
function _testTransition(navigationTransition: NavigationTransition) {
|
||||
var testId = `Transition[${JSON.stringify(navigationTransition)}]`;
|
||||
trace.write(`Testing ${testId}`, trace.categories.Test);
|
||||
var navigationEntry: NavigationEntry = {
|
||||
create: function (): Page {
|
||||
var page = new Page();
|
||||
page.id = testId;
|
||||
page.style.backgroundColor = new color.Color(255, Math.round(Math.random() * 255), Math.round(Math.random() * 255), Math.round(Math.random() * 255));
|
||||
return page;
|
||||
},
|
||||
animated: true,
|
||||
navigationTransition: navigationTransition
|
||||
}
|
||||
|
||||
helper.navigateWithEntry(navigationEntry);
|
||||
TKUnit.wait(0.100);
|
||||
helper.goBack();
|
||||
TKUnit.wait(0.100);
|
||||
utils.GC();
|
||||
}
|
||||
|
||||
// Extremely slow. Run only if needed.
|
||||
export var test_Transitions = function () {
|
||||
helper.navigate(() => {
|
||||
var page = new Page();
|
||||
page.id = "TransitionsTestPage_MAIN"
|
||||
page.style.backgroundColor = new color.Color(255, Math.round(Math.random() * 255), Math.round(Math.random() * 255), Math.round(Math.random() * 255));
|
||||
return page;
|
||||
});
|
||||
|
||||
var transitions;
|
||||
if (platform.device.os === platform.platformNames.ios) {
|
||||
transitions = ["curl"];
|
||||
}
|
||||
else {
|
||||
var _sdkVersion = parseInt(platform.device.sdkVersion);
|
||||
transitions = _sdkVersion >= 21 ? ["explode"] : [];
|
||||
}
|
||||
transitions = transitions.concat(["fade", "flip", "slide"]);
|
||||
var durations = [undefined, 500];
|
||||
var curves = [undefined, AnimationCurve.easeIn];
|
||||
|
||||
// Built-in transitions
|
||||
var t, d, c;
|
||||
var tlen = transitions.length;
|
||||
var dlen = durations.length;
|
||||
var clen = curves.length;
|
||||
for (t = 0; t < tlen; t++) {
|
||||
for (d = 0; d < dlen; d++) {
|
||||
for (c = 0; c < clen; c++) {
|
||||
_testTransition({
|
||||
transition: transitions[t],
|
||||
duration: durations[d],
|
||||
curve: curves[c]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Custom transition
|
||||
var customTransitionModule = require("./custom-transition");
|
||||
var customTransition = new customTransitionModule.CustomTransition();
|
||||
_testTransition({transition: customTransition});
|
||||
|
||||
helper.goBack();
|
||||
}
|
||||
|
||||
export var test_backstackVisible = function () {
|
||||
var mainTestPage = topmostFrame().currentPage;
|
||||
topmostFrame().navigate({ create: pageFactory });
|
||||
TKUnit.waitUntilReady(() => { return topmostFrame().currentPage !== mainTestPage; });
|
||||
|
||||
// page1 should not be added to the backstack
|
||||
var page0 = topmostFrame().currentPage;
|
||||
topmostFrame().navigate({ create: pageFactory, backstackVisible: false });
|
||||
TKUnit.waitUntilReady(() => { return topmostFrame().currentPage !== page0; });
|
||||
|
||||
var page1 = topmostFrame().currentPage;
|
||||
topmostFrame().navigate({ create: pageFactory });
|
||||
TKUnit.waitUntilReady(() => { return topmostFrame().currentPage !== page1; });
|
||||
|
||||
var page2 = topmostFrame().currentPage;
|
||||
topmostFrame().goBack();
|
||||
TKUnit.waitUntilReady(() => { return topmostFrame().currentPage !== page2; });
|
||||
|
||||
// From page2 we have to go directly to page0, skipping page1.
|
||||
TKUnit.assert(topmostFrame().currentPage === page0, "Page 1 should be skipped when going back.");
|
||||
|
||||
topmostFrame().goBack();
|
||||
TKUnit.waitUntilReady(() => { return topmostFrame().currentPage === mainTestPage; });
|
||||
}
|
||||
|
||||
export var test_backToEntry = function () {
|
||||
let page = (tag) => () => {
|
||||
var p = new Page();
|
||||
p["tag"] = tag;
|
||||
return p;
|
||||
}
|
||||
let topmost = topmostFrame();
|
||||
let wait = tag => TKUnit.waitUntilReady(() => topmost.currentPage["tag"] === tag, 1);
|
||||
let navigate = tag => {
|
||||
topmost.navigate({ create: page(tag) });
|
||||
wait(tag)
|
||||
}
|
||||
let back = pages => {
|
||||
topmost.goBack(topmost.backStack[topmost.backStack.length - pages]);
|
||||
}
|
||||
let currentPageMustBe = tag => {
|
||||
wait(tag); // TODO: Add a timeout...
|
||||
TKUnit.assert(topmost.currentPage["tag"] === tag, "Expected current page to be " + tag + " it was " + topmost.currentPage["tag"] + " instead.");
|
||||
}
|
||||
|
||||
navigate("page1");
|
||||
navigate("page2");
|
||||
navigate("page3");
|
||||
navigate("page4");
|
||||
|
||||
currentPageMustBe("page4");
|
||||
back(2);
|
||||
currentPageMustBe("page2");
|
||||
back(1);
|
||||
currentPageMustBe("page1");
|
||||
navigate("page1.1");
|
||||
navigate("page1.2");
|
||||
currentPageMustBe("page1.2");
|
||||
back(1);
|
||||
currentPageMustBe("page1.1");
|
||||
back(1);
|
||||
currentPageMustBe("page1");
|
||||
back(1);
|
||||
}
|
||||
|
||||
// Clearing the history messes up the tests app.
|
||||
export var test_ClearHistory = function () {
|
||||
var mainTestPage = topmostFrame().currentPage;
|
||||
var mainPageFactory = function (): Page {
|
||||
return mainTestPage;
|
||||
};
|
||||
|
||||
var currentPage: Page;
|
||||
|
||||
currentPage = topmostFrame().currentPage;
|
||||
topmostFrame().navigate({ create: pageFactory });
|
||||
TKUnit.waitUntilReady(() => { return topmostFrame().currentPage !== currentPage; });
|
||||
|
||||
currentPage = topmostFrame().currentPage;
|
||||
topmostFrame().navigate({ create: pageFactory });
|
||||
TKUnit.waitUntilReady(() => { return topmostFrame().currentPage !== currentPage; });
|
||||
|
||||
currentPage = topmostFrame().currentPage;
|
||||
topmostFrame().navigate({ create: pageFactory });
|
||||
TKUnit.waitUntilReady(() => { return topmostFrame().currentPage !== currentPage; });
|
||||
|
||||
TKUnit.assert(topmostFrame().canGoBack(), "Frame should be able to go back.");
|
||||
TKUnit.assert(topmostFrame().backStack.length === 3, "Back stack should have 3 entries.");
|
||||
|
||||
// Navigate with clear history.
|
||||
currentPage = topmostFrame().currentPage;
|
||||
topmostFrame().navigate({ create: pageFactory, clearHistory: true });
|
||||
TKUnit.waitUntilReady(() => { return topmostFrame().currentPage !== currentPage; });
|
||||
|
||||
TKUnit.assert(!topmostFrame().canGoBack(), "Frame should NOT be able to go back.");
|
||||
TKUnit.assert(topmostFrame().backStack.length === 0, "Back stack should have 0 entries.");
|
||||
|
||||
topmostFrame().navigate({ create: mainPageFactory });
|
||||
TKUnit.waitUntilReady(() => { return topmostFrame().currentPage === mainTestPage; });
|
||||
}
|
||||
@@ -92,15 +92,16 @@ if (!isRunningOnEmulator()) {
|
||||
}
|
||||
|
||||
// Navigation tests should always be last.
|
||||
allTests["NAVIGATION"] = require("./navigation-tests");
|
||||
allTests["NAVIGATION"] = require("./navigation/navigation-tests");
|
||||
|
||||
var testsWithLongDelay = {
|
||||
test_Transitions: 3 * 60 * 1000,
|
||||
testLocation: 10000,
|
||||
testLocationOnce: 10000,
|
||||
testLocationOnceMaximumAge: 10000,
|
||||
//web-view-tests
|
||||
testLoadExistingUrl: 10000,
|
||||
testLoadInvalidUrl: 10000,
|
||||
testLoadInvalidUrl: 10000
|
||||
}
|
||||
|
||||
var running = false;
|
||||
|
||||
@@ -207,22 +207,25 @@ export function buildUIWithWeakRefAndInteract<T extends view.View>(createFunc: (
|
||||
export function navigate(pageFactory: () => page.Page, navigationContext?: any) {
|
||||
var currentPage = frame.topmost().currentPage;
|
||||
frame.topmost().navigate({ create: pageFactory, animated: false, context: navigationContext });
|
||||
TKUnit.waitUntilReady(() => { return frame.topmost().currentPage !== currentPage; });
|
||||
TKUnit.waitUntilReady(() => { return frame.topmost().currentPage !== currentPage && frame.topmost().currentPage.isLoaded && !currentPage.isLoaded; });
|
||||
}
|
||||
|
||||
export function navigateToModule(moduleName: string, context?: any) {
|
||||
var currentPage = frame.topmost().currentPage;
|
||||
frame.topmost().navigate({ moduleName: moduleName, context: context, animated: false });
|
||||
TKUnit.waitUntilReady(() => { return frame.topmost().currentPage !== currentPage; });
|
||||
TKUnit.assert(frame.topmost().currentPage.isLoaded, "Current page should be loaded!");
|
||||
TKUnit.waitUntilReady(() => { return frame.topmost().currentPage !== currentPage && frame.topmost().currentPage.isLoaded && !currentPage.isLoaded; });
|
||||
}
|
||||
|
||||
export function navigateWithEntry(navigationEntry: frame.NavigationEntry) {
|
||||
var currentPage = frame.topmost().currentPage;
|
||||
frame.topmost().navigate(navigationEntry);
|
||||
TKUnit.waitUntilReady(() => { return frame.topmost().currentPage !== currentPage && frame.topmost().currentPage.isLoaded && !currentPage.isLoaded; });
|
||||
}
|
||||
|
||||
export function goBack(): void {
|
||||
var currentPage = frame.topmost().currentPage;
|
||||
frame.topmost().goBack();
|
||||
TKUnit.waitUntilReady(() => { return frame.topmost().currentPage !== currentPage; });
|
||||
TKUnit.assert(frame.topmost().currentPage.isLoaded, "Current page should be loaded!");
|
||||
TKUnit.assert(!currentPage.isLoaded, "Previous page should be unloaded!");
|
||||
TKUnit.waitUntilReady(() => { return frame.topmost().currentPage !== currentPage && frame.topmost().currentPage.isLoaded && !currentPage.isLoaded; });
|
||||
}
|
||||
|
||||
export function assertAreClose(actual: number, expected: number, message: string): void {
|
||||
|
||||
@@ -28,6 +28,7 @@ import stackLayoutModule = require("ui/layouts/stack-layout");
|
||||
import helper = require("../helper");
|
||||
import view = require("ui/core/view");
|
||||
import platform = require("platform");
|
||||
import observable = require("data/observable");
|
||||
|
||||
export function addLabelToPage(page: PageModule.Page, text?: string) {
|
||||
var label = new LabelModule.Label();
|
||||
@@ -59,13 +60,9 @@ export function test_AfterPageLoaded_is_called_NativeInstance_is_created() {
|
||||
|
||||
helper.navigate(pageFactory);
|
||||
|
||||
try {
|
||||
TKUnit.assert(nativeInstanceCreated, "Expected: true, Actual: " + nativeInstanceCreated);
|
||||
}
|
||||
finally {
|
||||
page.off(view.View.loadedEvent, handler);
|
||||
helper.goBack();
|
||||
}
|
||||
TKUnit.assert(nativeInstanceCreated, "Expected: true, Actual: " + nativeInstanceCreated);
|
||||
page.off(view.View.loadedEvent, handler);
|
||||
helper.goBack();
|
||||
}
|
||||
|
||||
export function test_PageLoaded_is_called_once() {
|
||||
@@ -96,14 +93,10 @@ export function test_PageLoaded_is_called_once() {
|
||||
|
||||
helper.navigate(pageFactory2);
|
||||
|
||||
try {
|
||||
TKUnit.assert(loaded === 1, "Expected: 1, Actual: " + loaded);
|
||||
}
|
||||
finally {
|
||||
page2.off(view.View.loadedEvent, handler);
|
||||
helper.goBack();
|
||||
helper.goBack();
|
||||
}
|
||||
TKUnit.assert(loaded === 1, "Expected: 1, Actual: " + loaded);
|
||||
page2.off(view.View.loadedEvent, handler);
|
||||
helper.goBack();
|
||||
helper.goBack();
|
||||
}
|
||||
|
||||
export function test_NavigateToNewPage() {
|
||||
@@ -147,7 +140,15 @@ export function test_NavigateToNewPage() {
|
||||
TKUnit.assert(testPage._isAddedToNativeVisualTree === false, "Page._isAddedToNativeVisualTree should become false after navigating back");
|
||||
}
|
||||
|
||||
export function test_PageNavigation_EventSequence() {
|
||||
export function test_PageNavigation_EventSequence_WithTransition() {
|
||||
_test_PageNavigation_EventSequence(true);
|
||||
}
|
||||
|
||||
export function test_PageNavigation_EventSequence_WithoutTransition() {
|
||||
_test_PageNavigation_EventSequence(false);
|
||||
}
|
||||
|
||||
function _test_PageNavigation_EventSequence(withTransition: boolean) {
|
||||
var testPage: PageModule.Page;
|
||||
var context = { property: "this is the context" };
|
||||
var eventSequence = [];
|
||||
@@ -160,13 +161,15 @@ export function test_PageNavigation_EventSequence() {
|
||||
TKUnit.assertEqual(data.context, context, "navigatingTo: navigationContext");
|
||||
});
|
||||
|
||||
testPage.on(PageModule.Page.loadedEvent, function (data) {
|
||||
testPage.on(PageModule.Page.loadedEvent, function (data: observable.EventData) {
|
||||
eventSequence.push("loaded");
|
||||
TKUnit.assertNotEqual(FrameModule.topmost().currentPage, data.object);
|
||||
});
|
||||
|
||||
testPage.on(PageModule.Page.navigatedToEvent, function (data: PageModule.NavigatedData) {
|
||||
eventSequence.push("navigatedTo");
|
||||
TKUnit.assertEqual(data.context, context, "navigatedTo : navigationContext");
|
||||
TKUnit.assertEqual(FrameModule.topmost().currentPage, data.object);
|
||||
});
|
||||
|
||||
testPage.on(PageModule.Page.navigatingFromEvent, function (data: PageModule.NavigatedData) {
|
||||
@@ -186,7 +189,23 @@ export function test_PageNavigation_EventSequence() {
|
||||
return testPage;
|
||||
};
|
||||
|
||||
helper.navigate(pageFactory, context);
|
||||
if (withTransition) {
|
||||
var navigationTransition: FrameModule.NavigationTransition = {
|
||||
transition: "slide",
|
||||
duration: 1000,
|
||||
};
|
||||
var navigationEntry: FrameModule.NavigationEntry = {
|
||||
create: pageFactory,
|
||||
context: context,
|
||||
animated: true,
|
||||
navigationTransition: navigationTransition
|
||||
}
|
||||
helper.navigateWithEntry(navigationEntry);
|
||||
}
|
||||
else {
|
||||
helper.navigate(pageFactory, context);
|
||||
}
|
||||
|
||||
helper.goBack();
|
||||
|
||||
var expectedEventSequence = ["navigatingTo", "loaded", "navigatedTo", "navigatingFrom", "navigatedFrom", "unloaded"];
|
||||
@@ -218,13 +237,9 @@ export function test_NavigateTo_WithContext() {
|
||||
// </snippet>
|
||||
TKUnit.waitUntilReady(() => { return topFrame.currentPage !== currentPage });
|
||||
|
||||
try {
|
||||
var actualContextValue = testPage.navigationContext;
|
||||
TKUnit.assert(actualContextValue === "myContext", "Expected: myContext" + ", Actual: " + actualContextValue);
|
||||
}
|
||||
finally {
|
||||
helper.goBack();
|
||||
}
|
||||
var actualContextValue = testPage.navigationContext;
|
||||
TKUnit.assert(actualContextValue === "myContext", "Expected: myContext" + ", Actual: " + actualContextValue);
|
||||
helper.goBack();
|
||||
|
||||
TKUnit.assert(testPage.navigationContext === undefined, "Navigation context should be cleared on navigating back");
|
||||
}
|
||||
@@ -239,13 +254,9 @@ export function test_FrameBackStack_WhenNavigatingForwardAndBack() {
|
||||
helper.navigate(pageFactory);
|
||||
|
||||
var topFrame = FrameModule.topmost();
|
||||
try {
|
||||
TKUnit.assert(topFrame.backStack.length === 1, "Expected: 1, Actual: " + topFrame.backStack.length);
|
||||
TKUnit.assert(topFrame.canGoBack(), "We should can go back.");
|
||||
}
|
||||
finally {
|
||||
helper.goBack();
|
||||
}
|
||||
TKUnit.assert(topFrame.backStack.length === 1, "Expected: 1, Actual: " + topFrame.backStack.length);
|
||||
TKUnit.assert(topFrame.canGoBack(), "We should can go back.");
|
||||
helper.goBack();
|
||||
|
||||
TKUnit.assert(topFrame.backStack.length === 0, "Expected: 0, Actual: " + topFrame.backStack.length);
|
||||
TKUnit.assert(topFrame.canGoBack() === false, "canGoBack should return false.");
|
||||
@@ -253,44 +264,31 @@ export function test_FrameBackStack_WhenNavigatingForwardAndBack() {
|
||||
|
||||
export function test_LoadPageFromModule() {
|
||||
helper.navigateToModule("ui/page/test-page-module");
|
||||
try {
|
||||
var topFrame = FrameModule.topmost();
|
||||
TKUnit.assert(topFrame.currentPage.content instanceof LabelModule.Label, "Content of the test page should be a Label created within test-page-module.");
|
||||
var testLabel = <LabelModule.Label>topFrame.currentPage.content;
|
||||
TKUnit.assert(testLabel.text === "Label created within a page module.");
|
||||
}
|
||||
finally {
|
||||
helper.goBack();
|
||||
}
|
||||
var topFrame = FrameModule.topmost();
|
||||
TKUnit.assert(topFrame.currentPage.content instanceof LabelModule.Label, "Content of the test page should be a Label created within test-page-module.");
|
||||
var testLabel = <LabelModule.Label>topFrame.currentPage.content;
|
||||
TKUnit.assert(testLabel.text === "Label created within a page module.");
|
||||
helper.goBack();
|
||||
}
|
||||
|
||||
export function test_LoadPageFromDeclarativeWithCSS() {
|
||||
helper.navigateToModule("ui/page/test-page-declarative-css");
|
||||
try {
|
||||
var topFrame = FrameModule.topmost();
|
||||
TKUnit.assert(topFrame.currentPage.content instanceof LabelModule.Label, "Content of the test page should be a Label created within test-page-module-css.");
|
||||
var testLabel = <LabelModule.Label>topFrame.currentPage.content;
|
||||
TKUnit.assert(testLabel.text === "Label created within a page declarative file with css.");
|
||||
TKUnit.assert(testLabel.style.backgroundColor.hex === "#ff00ff00", "Expected: #ff00ff00, Actual: " + testLabel.style.backgroundColor.hex);
|
||||
}
|
||||
finally {
|
||||
helper.goBack();
|
||||
}
|
||||
|
||||
var topFrame = FrameModule.topmost();
|
||||
TKUnit.assert(topFrame.currentPage.content instanceof LabelModule.Label, "Content of the test page should be a Label created within test-page-module-css.");
|
||||
var testLabel = <LabelModule.Label>topFrame.currentPage.content;
|
||||
TKUnit.assert(testLabel.text === "Label created within a page declarative file with css.");
|
||||
TKUnit.assert(testLabel.style.backgroundColor.hex === "#ff00ff00", "Expected: #ff00ff00, Actual: " + testLabel.style.backgroundColor.hex);
|
||||
helper.goBack();
|
||||
}
|
||||
|
||||
export function test_LoadPageFromModuleWithCSS() {
|
||||
helper.navigateToModule("ui/page/test-page-module-css");
|
||||
try {
|
||||
var topFrame = FrameModule.topmost();
|
||||
TKUnit.assert(topFrame.currentPage.content instanceof LabelModule.Label, "Content of the test page should be a Label created within test-page-module-css.");
|
||||
var testLabel = <LabelModule.Label>topFrame.currentPage.content;
|
||||
TKUnit.assert(testLabel.text === "Label created within a page module css.");
|
||||
TKUnit.assert(testLabel.style.backgroundColor.hex === "#ff00ff00", "Expected: #ff00ff00, Actual: " + testLabel.style.backgroundColor.hex);
|
||||
}
|
||||
finally {
|
||||
helper.goBack();
|
||||
}
|
||||
var topFrame = FrameModule.topmost();
|
||||
TKUnit.assert(topFrame.currentPage.content instanceof LabelModule.Label, "Content of the test page should be a Label created within test-page-module-css.");
|
||||
var testLabel = <LabelModule.Label>topFrame.currentPage.content;
|
||||
TKUnit.assert(testLabel.text === "Label created within a page module css.");
|
||||
TKUnit.assert(testLabel.style.backgroundColor.hex === "#ff00ff00", "Expected: #ff00ff00, Actual: " + testLabel.style.backgroundColor.hex);
|
||||
helper.goBack();
|
||||
}
|
||||
|
||||
export function test_NavigateToPageCreatedWithNavigationEntry() {
|
||||
@@ -305,12 +303,8 @@ export function test_NavigateToPageCreatedWithNavigationEntry() {
|
||||
helper.navigate(pageFactory);
|
||||
|
||||
var actualContent = <LabelModule.Label>testPage.content;
|
||||
try {
|
||||
TKUnit.assert(actualContent.text === expectedText, "Expected: " + expectedText + ", Actual: " + actualContent.text);
|
||||
}
|
||||
finally {
|
||||
helper.goBack();
|
||||
}
|
||||
TKUnit.assert(actualContent.text === expectedText, "Expected: " + expectedText + ", Actual: " + actualContent.text);
|
||||
helper.goBack();
|
||||
}
|
||||
|
||||
export function test_cssShouldBeAppliedToAllNestedElements() {
|
||||
@@ -330,13 +324,9 @@ export function test_cssShouldBeAppliedToAllNestedElements() {
|
||||
helper.navigate(pageFactory);
|
||||
|
||||
var expectedText = "Some text";
|
||||
try {
|
||||
TKUnit.assert(label.style.backgroundColor.hex === "#ff00ff00", "Expected: #ff00ff00, Actual: " + label.style.backgroundColor.hex);
|
||||
TKUnit.assert(StackLayout.style.backgroundColor.hex === "#ffff0000", "Expected: #ffff0000, Actual: " + StackLayout.style.backgroundColor.hex);
|
||||
}
|
||||
finally {
|
||||
helper.goBack();
|
||||
}
|
||||
TKUnit.assert(label.style.backgroundColor.hex === "#ff00ff00", "Expected: #ff00ff00, Actual: " + label.style.backgroundColor.hex);
|
||||
TKUnit.assert(StackLayout.style.backgroundColor.hex === "#ffff0000", "Expected: #ffff0000, Actual: " + StackLayout.style.backgroundColor.hex);
|
||||
helper.goBack();
|
||||
}
|
||||
|
||||
export function test_cssShouldBeAppliedAfterChangeToAllNestedElements() {
|
||||
@@ -357,17 +347,13 @@ export function test_cssShouldBeAppliedAfterChangeToAllNestedElements() {
|
||||
helper.navigate(pageFactory);
|
||||
|
||||
var expectedText = "Some text";
|
||||
try {
|
||||
TKUnit.assert(label.style.backgroundColor.hex === "#ff00ff00", "Expected: #ff00ff00, Actual: " + label.style.backgroundColor.hex);
|
||||
TKUnit.assert(StackLayout.style.backgroundColor.hex === "#ffff0000", "Expected: #ffff0000, Actual: " + StackLayout.style.backgroundColor.hex);
|
||||
TKUnit.assert(label.style.backgroundColor.hex === "#ff00ff00", "Expected: #ff00ff00, Actual: " + label.style.backgroundColor.hex);
|
||||
TKUnit.assert(StackLayout.style.backgroundColor.hex === "#ffff0000", "Expected: #ffff0000, Actual: " + StackLayout.style.backgroundColor.hex);
|
||||
|
||||
testPage.css = "stackLayout {background-color: #ff0000ff;} label {background-color: #ffff0000;}";
|
||||
TKUnit.assert(label.style.backgroundColor.hex === "#ffff0000", "Expected: #ffff0000, Actual: " + label.style.backgroundColor.hex);
|
||||
TKUnit.assert(StackLayout.style.backgroundColor.hex === "#ff0000ff", "Expected: #ff0000ff, Actual: " + StackLayout.style.backgroundColor.hex);
|
||||
}
|
||||
finally {
|
||||
helper.goBack();
|
||||
}
|
||||
testPage.css = "stackLayout {background-color: #ff0000ff;} label {background-color: #ffff0000;}";
|
||||
TKUnit.assert(label.style.backgroundColor.hex === "#ffff0000", "Expected: #ffff0000, Actual: " + label.style.backgroundColor.hex);
|
||||
TKUnit.assert(StackLayout.style.backgroundColor.hex === "#ff0000ff", "Expected: #ff0000ff, Actual: " + StackLayout.style.backgroundColor.hex);
|
||||
helper.goBack();
|
||||
}
|
||||
|
||||
export function test_page_backgroundColor_is_white() {
|
||||
@@ -377,10 +363,10 @@ export function test_page_backgroundColor_is_white() {
|
||||
});
|
||||
}
|
||||
|
||||
export function test_WhenPageIsLoadedFrameCurrentPageIsTheSameInstance() {
|
||||
export function test_WhenPageIsLoadedFrameCurrentPageIsNotYetTheSameAsThePage() {
|
||||
var page;
|
||||
var loadedEventHandler = function (args) {
|
||||
TKUnit.assert(FrameModule.topmost().currentPage === args.object, `frame.topmost().currentPage should be equal to args.object page instance in the page.loaded event handler. Expected: ${args.object.id}; Actual: ${FrameModule.topmost().currentPage.id};`);
|
||||
TKUnit.assert(FrameModule.topmost().currentPage !== args.object, `When a page is loaded it should not yet be the current page. Loaded: ${args.object.id}; Current: ${FrameModule.topmost().currentPage.id};`);
|
||||
}
|
||||
|
||||
var pageFactory = function (): PageModule.Page {
|
||||
@@ -393,13 +379,30 @@ export function test_WhenPageIsLoadedFrameCurrentPageIsTheSameInstance() {
|
||||
return page;
|
||||
};
|
||||
|
||||
try {
|
||||
helper.navigate(pageFactory);
|
||||
page.off(view.View.loadedEvent, loadedEventHandler);
|
||||
}
|
||||
finally {
|
||||
helper.goBack();
|
||||
helper.navigate(pageFactory);
|
||||
page.off(view.View.loadedEvent, loadedEventHandler);
|
||||
helper.goBack();
|
||||
}
|
||||
|
||||
export function test_WhenPageIsNavigatedToFrameCurrentPageIsNowTheSameAsThePage() {
|
||||
var page;
|
||||
var navigatedEventHandler = function (args) {
|
||||
TKUnit.assert(FrameModule.topmost().currentPage === args.object, `frame.topmost().currentPage should be equal to args.object page instance in the page.navigatedTo event handler. Expected: ${args.object.id}; Actual: ${FrameModule.topmost().currentPage.id};`);
|
||||
}
|
||||
|
||||
var pageFactory = function (): PageModule.Page {
|
||||
page = new PageModule.Page();
|
||||
page.id = "newPage";
|
||||
page.on(PageModule.Page.navigatedToEvent, navigatedEventHandler);
|
||||
var label = new LabelModule.Label();
|
||||
label.text = "Text";
|
||||
page.content = label;
|
||||
return page;
|
||||
};
|
||||
|
||||
helper.navigate(pageFactory);
|
||||
page.off(view.View.loadedEvent, navigatedEventHandler);
|
||||
helper.goBack();
|
||||
}
|
||||
|
||||
export function test_WhenNavigatingForwardAndBack_IsBackNavigationIsCorrect() {
|
||||
@@ -407,7 +410,7 @@ export function test_WhenNavigatingForwardAndBack_IsBackNavigationIsCorrect() {
|
||||
var page2;
|
||||
var forwardCounter = 0;
|
||||
var backCounter = 0;
|
||||
var loadedEventHandler = function (args: PageModule.NavigatedData) {
|
||||
var navigatedEventHandler = function (args: PageModule.NavigatedData) {
|
||||
if (args.isBackNavigation) {
|
||||
backCounter++;
|
||||
}
|
||||
@@ -418,28 +421,24 @@ export function test_WhenNavigatingForwardAndBack_IsBackNavigationIsCorrect() {
|
||||
|
||||
var pageFactory1 = function (): PageModule.Page {
|
||||
page1 = new PageModule.Page();
|
||||
page1.on(PageModule.Page.navigatedToEvent, loadedEventHandler);
|
||||
page1.on(PageModule.Page.navigatedToEvent, navigatedEventHandler);
|
||||
return page1;
|
||||
};
|
||||
|
||||
var pageFactory2 = function (): PageModule.Page {
|
||||
page2 = new PageModule.Page();
|
||||
page2.on(PageModule.Page.navigatedToEvent, loadedEventHandler);
|
||||
page2.on(PageModule.Page.navigatedToEvent, navigatedEventHandler);
|
||||
return page2;
|
||||
};
|
||||
|
||||
try {
|
||||
helper.navigate(pageFactory1);
|
||||
helper.navigate(pageFactory2);
|
||||
helper.goBack();
|
||||
TKUnit.assertEqual(forwardCounter, 2, "Forward navigation counter should be 1");
|
||||
TKUnit.assertEqual(backCounter, 1, "Backward navigation counter should be 1");
|
||||
page1.off(PageModule.Page.navigatedToEvent, loadedEventHandler);
|
||||
page2.off(PageModule.Page.navigatedToEvent, loadedEventHandler);
|
||||
}
|
||||
finally {
|
||||
helper.goBack();
|
||||
}
|
||||
helper.navigate(pageFactory1);
|
||||
helper.navigate(pageFactory2);
|
||||
helper.goBack();
|
||||
TKUnit.assertEqual(forwardCounter, 2, "Forward navigation counter should be 1");
|
||||
TKUnit.assertEqual(backCounter, 1, "Backward navigation counter should be 1");
|
||||
page1.off(PageModule.Page.navigatedToEvent, navigatedEventHandler);
|
||||
page2.off(PageModule.Page.navigatedToEvent, navigatedEventHandler);
|
||||
helper.goBack();
|
||||
}
|
||||
|
||||
//export function test_ModalPage_Layout_is_Correct() {
|
||||
|
||||
@@ -27,7 +27,7 @@ export function test_NavigateToNewPage_InnerControl() {
|
||||
TKUnit.assert(label.isLoaded === false, "InnerControl.isLoaded should become false after navigating back");
|
||||
}
|
||||
|
||||
export function test_WhenPageIsLoadedItCanShowAnotherPageAsModal() {
|
||||
export function test_WhenPageIsNavigatedToItCanShowAnotherPageAsModal() {
|
||||
var masterPage;
|
||||
var ctx = {
|
||||
shownModally: false
|
||||
@@ -42,7 +42,7 @@ export function test_WhenPageIsLoadedItCanShowAnotherPageAsModal() {
|
||||
modalClosed = true;
|
||||
}
|
||||
|
||||
var loadedEventHandler = function (args) {
|
||||
var navigatedToEventHandler = function (args) {
|
||||
TKUnit.assert(!frame.topmost().currentPage.modal, "frame.topmost().currentPage.modal should be undefined when no modal page is shown!");
|
||||
var basePath = "ui/page/";
|
||||
args.object.showModal(basePath + "modal-page", ctx, modalCloseCallback, false);
|
||||
@@ -51,7 +51,7 @@ export function test_WhenPageIsLoadedItCanShowAnotherPageAsModal() {
|
||||
var masterPageFactory = function (): PageModule.Page {
|
||||
masterPage = new PageModule.Page();
|
||||
masterPage.id = "newPage";
|
||||
masterPage.on(view.View.loadedEvent, loadedEventHandler);
|
||||
masterPage.on(PageModule.Page.navigatedToEvent, navigatedToEventHandler);
|
||||
var label = new LabelModule.Label();
|
||||
label.text = "Text";
|
||||
masterPage.content = label;
|
||||
@@ -61,7 +61,7 @@ export function test_WhenPageIsLoadedItCanShowAnotherPageAsModal() {
|
||||
try {
|
||||
helper.navigate(masterPageFactory);
|
||||
TKUnit.waitUntilReady(() => { return modalClosed; });
|
||||
masterPage.off(view.View.loadedEvent, loadedEventHandler);
|
||||
masterPage.off(view.View.loadedEvent, navigatedToEventHandler);
|
||||
}
|
||||
finally {
|
||||
helper.goBack();
|
||||
@@ -77,7 +77,7 @@ export function test_WhenShowingModalPageUnloadedIsNotFiredForTheMasterPage() {
|
||||
modalClosed = true;
|
||||
}
|
||||
|
||||
var loadedEventHandler = function (args) {
|
||||
var navigatedToEventHandler = function (args) {
|
||||
var basePath = "ui/page/";
|
||||
args.object.showModal(basePath + "modal-page", null, modalCloseCallback, false);
|
||||
};
|
||||
@@ -89,7 +89,7 @@ export function test_WhenShowingModalPageUnloadedIsNotFiredForTheMasterPage() {
|
||||
var masterPageFactory = function (): PageModule.Page {
|
||||
masterPage = new PageModule.Page();
|
||||
masterPage.id = "master-page";
|
||||
masterPage.on(view.View.loadedEvent, loadedEventHandler);
|
||||
masterPage.on(PageModule.Page.navigatedToEvent, navigatedToEventHandler);
|
||||
masterPage.on(view.View.unloadedEvent, unloadedEventHandler);
|
||||
var label = new LabelModule.Label();
|
||||
label.text = "Modal Page";
|
||||
@@ -101,8 +101,8 @@ export function test_WhenShowingModalPageUnloadedIsNotFiredForTheMasterPage() {
|
||||
helper.navigate(masterPageFactory);
|
||||
TKUnit.waitUntilReady(() => { return modalClosed; });
|
||||
TKUnit.assert(!masterPageUnloaded, "Master page should not raise 'unloaded' when showing modal!");
|
||||
masterPage.off(view.View.loadedEvent, loadedEventHandler);
|
||||
masterPage.off(view.View.unloadedEvent, loadedEventHandler);
|
||||
masterPage.off(view.View.loadedEvent, navigatedToEventHandler);
|
||||
masterPage.off(view.View.unloadedEvent, unloadedEventHandler);
|
||||
}
|
||||
finally {
|
||||
helper.goBack();
|
||||
|
||||
@@ -124,6 +124,7 @@ export var test_XMLHttpRequest_contentSentAndReceivedProperly = function (done)
|
||||
// <hide>
|
||||
try {
|
||||
TKUnit.assert(result["json"]["MyVariableOne"] === "ValueOne" && result["json"]["MyVariableTwo"] === "ValueTwo", "Content not sent/received properly!");
|
||||
TKUnit.assert(xhr.response.json.MyVariableOne === "ValueOne" && xhr.response.json.MyVariableTwo === "ValueTwo", "Response content not parsed properly!");
|
||||
done(null);
|
||||
}
|
||||
catch (err) {
|
||||
@@ -255,6 +256,44 @@ export function test_xhr_events() {
|
||||
TKUnit.assertEqual(errorEventData, 'error data');
|
||||
}
|
||||
|
||||
export function test_xhr_responseType_text() {
|
||||
const xhr = <any>new XMLHttpRequest();
|
||||
const response = {
|
||||
statusCode: 200,
|
||||
content: {
|
||||
toString: function(){ return this.raw },
|
||||
raw: 'response body'
|
||||
},
|
||||
headers: {
|
||||
"Content-Type": "text/plain"
|
||||
}
|
||||
|
||||
}
|
||||
xhr._loadResponse(response);
|
||||
|
||||
TKUnit.assertEqual(xhr.responseType, "text");
|
||||
TKUnit.assertEqual(xhr.response, 'response body');
|
||||
}
|
||||
|
||||
export function test_xhr_responseType_switched_to_JSON_if_header_present() {
|
||||
const xhr = <any>new XMLHttpRequest();
|
||||
const response = {
|
||||
statusCode: 200,
|
||||
content: {
|
||||
toString: function(){ return this.raw },
|
||||
raw: '{"data": 42}'
|
||||
},
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
}
|
||||
xhr._loadResponse(response);
|
||||
|
||||
TKUnit.assertEqual(xhr.responseType, "json");
|
||||
TKUnit.assertEqual(xhr.response.data, 42);
|
||||
}
|
||||
|
||||
export function test_sets_status_and_statusText(done) {
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = () => {
|
||||
|
||||
@@ -21,7 +21,13 @@ export function createPage() {
|
||||
buttonOneWay.id = "buttonOneWay";
|
||||
buttonTwoWay.id = "buttonTwoWay";
|
||||
|
||||
targetOneWay.automationText = "textFieldOneWay";
|
||||
targetTwoWay.automationText = "textFieldTwoWay";
|
||||
buttonOneWay.automationText = "buttonOneWay";
|
||||
buttonTwoWay.automationText = "buttonTwoWay";
|
||||
|
||||
buttonSetText.id = "buttonSetText";
|
||||
buttonSetText.automationText = "buttonSetText";
|
||||
buttonSetText.text = "SetText";
|
||||
buttonSetText.on(buttonModule.Button.tapEvent, function () {
|
||||
targetOneWay.text = "Test";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Page cssFile="~/css/text.css">
|
||||
<Page cssFile="~/css/test.css">
|
||||
<TabView>
|
||||
<TabView.items>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<Page xmlns="http://schemas.nativescript.org/tns.xsd">
|
||||
<StackLayout>
|
||||
<Label text="" style="font-family: Material-Design-Iconic-Font" />
|
||||
<Label text="" style="font-family: Material-Design-Iconic-Font" /> <!--Moved to tab-view.xml-->
|
||||
</StackLayout>
|
||||
</Page>
|
||||
@@ -3,12 +3,12 @@
|
||||
<TabView.items>
|
||||
<TabViewItem ios:title="Tab 1 " android:title="Tab 1 ">
|
||||
<TabViewItem.view>
|
||||
<Label text="Tab 1" />
|
||||
<Label text="Tab 1 " style="font-family: Material-Design-Iconic-Font" />
|
||||
</TabViewItem.view>
|
||||
</TabViewItem>
|
||||
<TabViewItem ios:title="Tab 2 " android:title="Tab 2 ">
|
||||
<TabViewItem.view>
|
||||
<Label text="Tab 2" />
|
||||
<Label text="Tab 2 " style="font-family: Material-Design-Iconic-Font" />
|
||||
</TabViewItem.view>
|
||||
</TabViewItem>
|
||||
</TabView.items>
|
||||
|
||||
@@ -48,11 +48,14 @@ examples.set("whitespace", "css/white-space");
|
||||
examples.set("radius", "css/radius");
|
||||
examples.set("styles", "css/styles");
|
||||
examples.set("switch", "css/views");
|
||||
examples.set("tabmore", "css/tab-view-more");
|
||||
|
||||
examples.set("dialogs", "dialogs/dialogs");
|
||||
|
||||
examples.set("fontbtn", "font/button");
|
||||
examples.set("fontlbl", "font/label");
|
||||
examples.set("material", "font/material-icons");
|
||||
examples.set("tabfont", "font/tab-view");
|
||||
examples.set("fontfield", "font/text-field");
|
||||
examples.set("fontview", "font/text-view");
|
||||
|
||||
|
||||
@@ -628,13 +628,13 @@ module.exports = function(grunt) {
|
||||
//alias just-build for backwards compatibility
|
||||
grunt.registerTask("just-build", ["build-all"]);
|
||||
|
||||
grunt.registerTask("build-all", (skipTsLint ? [] : ["tslint:build"]).concat([
|
||||
grunt.registerTask("build-all", [
|
||||
"pack-modules",
|
||||
|
||||
"collect-apps-raw-files",
|
||||
"distribute-apps-files",
|
||||
"distribute-ts-apps-files",
|
||||
]));
|
||||
]);
|
||||
|
||||
grunt.registerTask("node-tests", [
|
||||
"clean:nodeTests",
|
||||
|
||||
1
trace/trace.d.ts
vendored
1
trace/trace.d.ts
vendored
@@ -76,6 +76,7 @@ declare module "trace" {
|
||||
export var Binding: string;
|
||||
export var Error: string;
|
||||
export var Animation: string;
|
||||
export var Transition: string;
|
||||
|
||||
export var All: string;
|
||||
|
||||
|
||||
@@ -111,7 +111,8 @@ export module categories {
|
||||
export var Binding = "Binding";
|
||||
export var Error = "Error";
|
||||
export var Animation = "Animation";
|
||||
export var All = VisualTreeEvents + "," + Layout + "," + Style + "," + ViewHierarchy + "," + NativeLifecycle + "," + Debug + "," + Navigation + "," + Test + "," + Binding + "," + Error + "," + Animation;
|
||||
export var Transition = "Transition";
|
||||
export var All = VisualTreeEvents + "," + Layout + "," + Style + "," + ViewHierarchy + "," + NativeLifecycle + "," + Debug + "," + Navigation + "," + Test + "," + Binding + "," + Error + "," + Animation + "," + Transition;
|
||||
|
||||
export var separator = ",";
|
||||
|
||||
|
||||
@@ -89,10 +89,16 @@
|
||||
"apps/perf-tests/ApplicationLoadTimeAndFPS/mainPage.ts",
|
||||
"apps/perf-tests/ApplicationSize/app.ts",
|
||||
"apps/perf-tests/ApplicationSize/mainPage.ts",
|
||||
"apps/perf-tests/common.d.ts",
|
||||
"apps/perf-tests/common.ts",
|
||||
"apps/perf-tests/ComplexObjectGraphMemoryTest/app.ts",
|
||||
"apps/perf-tests/ComplexObjectGraphMemoryTest/mainPage.ts",
|
||||
"apps/perf-tests/ControlCreationSpeedTest/app.ts",
|
||||
"apps/perf-tests/ControlCreationSpeedTest/mainPage.ts",
|
||||
"apps/perf-tests/controls-page.d.ts",
|
||||
"apps/perf-tests/controls-page.ts",
|
||||
"apps/perf-tests/custom-transition.android.ts",
|
||||
"apps/perf-tests/custom-transition.ios.ts",
|
||||
"apps/perf-tests/LargeObjectArrayMemoryLeakTest/app.ts",
|
||||
"apps/perf-tests/LargeObjectArrayMemoryLeakTest/mainPage.ts",
|
||||
"apps/perf-tests/LargeObjectArrayMemoryLeakTest/native-calls-wrapper.android.ts",
|
||||
@@ -100,10 +106,13 @@
|
||||
"apps/perf-tests/LargeObjectArrayMemoryLeakTest/native-calls-wrapper.ios.ts",
|
||||
"apps/perf-tests/LargeObjectArrayMemoryTest/app.ts",
|
||||
"apps/perf-tests/LargeObjectArrayMemoryTest/mainPage.ts",
|
||||
"apps/perf-tests/nav-page.d.ts",
|
||||
"apps/perf-tests/nav-page.ts",
|
||||
"apps/perf-tests/NavigationMemoryLeakTest/app.ts",
|
||||
"apps/perf-tests/NavigationMemoryLeakTest/mainPage.ts",
|
||||
"apps/perf-tests/NavigationTest/app.ts",
|
||||
"apps/perf-tests/NavigationTest/details-page.ts",
|
||||
"apps/perf-tests/NavigationTest/list-picker-page.ts",
|
||||
"apps/perf-tests/NavigationTest/master-page.ts",
|
||||
"apps/perf-tests/NavigationTest/page1.ts",
|
||||
"apps/perf-tests/NavigationTest/page2.ts",
|
||||
@@ -116,12 +125,6 @@
|
||||
"apps/perf-tests/SpeedTests/tests-native.ios.ts",
|
||||
"apps/perf-tests/SpeedTests/tests.d.ts",
|
||||
"apps/perf-tests/SpeedTests/tests.ts",
|
||||
"apps/perf-tests/common.d.ts",
|
||||
"apps/perf-tests/common.ts",
|
||||
"apps/perf-tests/controls-page.d.ts",
|
||||
"apps/perf-tests/controls-page.ts",
|
||||
"apps/perf-tests/nav-page.d.ts",
|
||||
"apps/perf-tests/nav-page.ts",
|
||||
"apps/pickers-demo/app.ts",
|
||||
"apps/pickers-demo/main-page.ts",
|
||||
"apps/pickers-demo/model.ts",
|
||||
@@ -144,7 +147,6 @@
|
||||
"apps/template-settings/view-model.ts",
|
||||
"apps/template-tab-navigation/app.ts",
|
||||
"apps/template-tab-navigation/main-page.ts",
|
||||
"apps/tests/TKUnit.ts",
|
||||
"apps/tests/app/app.ts",
|
||||
"apps/tests/app/location-example.ts",
|
||||
"apps/tests/app/mainPage.ts",
|
||||
@@ -179,7 +181,9 @@
|
||||
"apps/tests/layouts/stack-layout-tests.ts",
|
||||
"apps/tests/layouts/wrap-layout-tests.ts",
|
||||
"apps/tests/location-tests.ts",
|
||||
"apps/tests/navigation-tests.ts",
|
||||
"apps/tests/navigation/custom-transition.android.ts",
|
||||
"apps/tests/navigation/custom-transition.ios.ts",
|
||||
"apps/tests/navigation/navigation-tests.ts",
|
||||
"apps/tests/observable-array-tests.ts",
|
||||
"apps/tests/observable-tests.ts",
|
||||
"apps/tests/pages/app.ts",
|
||||
@@ -219,12 +223,13 @@
|
||||
"apps/tests/testRunner.ts",
|
||||
"apps/tests/text/formatted-string-tests.ts",
|
||||
"apps/tests/timer-tests.ts",
|
||||
"apps/tests/TKUnit.ts",
|
||||
"apps/tests/trace-tests.ts",
|
||||
"apps/tests/ui-test.ts",
|
||||
"apps/tests/ui/action-bar/ActionBar_NumberAsText.ts",
|
||||
"apps/tests/ui/action-bar/action-bar-tests-common.ts",
|
||||
"apps/tests/ui/action-bar/action-bar-tests.android.ts",
|
||||
"apps/tests/ui/action-bar/action-bar-tests.ios.ts",
|
||||
"apps/tests/ui/action-bar/ActionBar_NumberAsText.ts",
|
||||
"apps/tests/ui/activity-indicator/activity-indicator-tests.ts",
|
||||
"apps/tests/ui/animation/animation-tests.ts",
|
||||
"apps/tests/ui/bindable-tests.ts",
|
||||
@@ -663,6 +668,14 @@
|
||||
"ui/time-picker/time-picker.android.ts",
|
||||
"ui/time-picker/time-picker.d.ts",
|
||||
"ui/time-picker/time-picker.ios.ts",
|
||||
"ui/transition/fade-transition.android.ts",
|
||||
"ui/transition/fade-transition.ios.ts",
|
||||
"ui/transition/flip-transition.android.ts",
|
||||
"ui/transition/slide-transition.android.ts",
|
||||
"ui/transition/slide-transition.ios.ts",
|
||||
"ui/transition/transition.android.ts",
|
||||
"ui/transition/transition.d.ts",
|
||||
"ui/transition/transition.ios.ts",
|
||||
"ui/ui.d.ts",
|
||||
"ui/ui.ts",
|
||||
"ui/utils.d.ts",
|
||||
@@ -685,5 +698,8 @@
|
||||
"xhr/xhr.ts",
|
||||
"xml/xml.d.ts",
|
||||
"xml/xml.ts"
|
||||
]
|
||||
}
|
||||
],
|
||||
"atom": {
|
||||
"rewriteTsconfig": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ export class Animation implements definition.Animation {
|
||||
var i = 0;
|
||||
var length = animationDefinitions.length;
|
||||
for (; i < length; i++) {
|
||||
animationDefinitions[i].curve = this._resolveAnimationCurve(animationDefinitions[i].curve);
|
||||
animationDefinitions[i].curve = definition._resolveAnimationCurve(animationDefinitions[i].curve);
|
||||
this._propertyAnimations = this._propertyAnimations.concat(Animation._createPropertyAnimations(animationDefinitions[i]));
|
||||
}
|
||||
|
||||
@@ -92,10 +92,6 @@ export class Animation implements definition.Animation {
|
||||
this._reject(new Error("Animation cancelled."));
|
||||
}
|
||||
|
||||
_resolveAnimationCurve(curve: any): any {
|
||||
//
|
||||
}
|
||||
|
||||
private static _createPropertyAnimations(animationDefinition: definition.AnimationDefinition): Array<PropertyAnimation> {
|
||||
if (!animationDefinition.target) {
|
||||
throw new Error("No animation target specified.");
|
||||
|
||||
@@ -298,27 +298,31 @@ export class Animation extends common.Animation implements definition.Animation
|
||||
this._propertyResetCallbacks = this._propertyResetCallbacks.concat(propertyResetCallbacks);
|
||||
}
|
||||
|
||||
_resolveAnimationCurve(curve: any): any {
|
||||
switch (curve) {
|
||||
case enums.AnimationCurve.easeIn:
|
||||
trace.write("Animation curve resolved to android.view.animation.AccelerateInterpolator(1).", trace.categories.Animation);
|
||||
return new android.view.animation.AccelerateInterpolator(1);
|
||||
case enums.AnimationCurve.easeOut:
|
||||
trace.write("Animation curve resolved to android.view.animation.DecelerateInterpolator(1).", trace.categories.Animation);
|
||||
return new android.view.animation.DecelerateInterpolator(1);
|
||||
case enums.AnimationCurve.easeInOut:
|
||||
trace.write("Animation curve resolved to android.view.animation.AccelerateDecelerateInterpolator().", trace.categories.Animation);
|
||||
return new android.view.animation.AccelerateDecelerateInterpolator();
|
||||
case enums.AnimationCurve.linear:
|
||||
trace.write("Animation curve resolved to android.view.animation.LinearInterpolator().", trace.categories.Animation);
|
||||
return new android.view.animation.LinearInterpolator();
|
||||
default:
|
||||
trace.write("Animation curve resolved to original: " + curve, trace.categories.Animation);
|
||||
return curve;
|
||||
}
|
||||
}
|
||||
|
||||
private static _getAndroidRepeatCount(iterations: number): number {
|
||||
return (iterations === Number.POSITIVE_INFINITY) ? android.view.animation.Animation.INFINITE : iterations - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var easeIn = new android.view.animation.AccelerateInterpolator(1);
|
||||
var easeOut = new android.view.animation.DecelerateInterpolator(1);
|
||||
var easeInOut = new android.view.animation.AccelerateDecelerateInterpolator();
|
||||
var linear = new android.view.animation.LinearInterpolator();
|
||||
export function _resolveAnimationCurve(curve: any): any {
|
||||
switch (curve) {
|
||||
case enums.AnimationCurve.easeIn:
|
||||
trace.write("Animation curve resolved to android.view.animation.AccelerateInterpolator(1).", trace.categories.Animation);
|
||||
return easeIn;
|
||||
case enums.AnimationCurve.easeOut:
|
||||
trace.write("Animation curve resolved to android.view.animation.DecelerateInterpolator(1).", trace.categories.Animation);
|
||||
return easeOut;
|
||||
case enums.AnimationCurve.easeInOut:
|
||||
trace.write("Animation curve resolved to android.view.animation.AccelerateDecelerateInterpolator().", trace.categories.Animation);
|
||||
return easeInOut;
|
||||
case enums.AnimationCurve.linear:
|
||||
trace.write("Animation curve resolved to android.view.animation.LinearInterpolator().", trace.categories.Animation);
|
||||
return linear;
|
||||
default:
|
||||
trace.write("Animation curve resolved to original: " + curve, trace.categories.Animation);
|
||||
return curve;
|
||||
}
|
||||
}
|
||||
|
||||
7
ui/animation/animation.d.ts
vendored
7
ui/animation/animation.d.ts
vendored
@@ -76,8 +76,9 @@
|
||||
public play: () => Promise<void>;
|
||||
public cancel: () => void;
|
||||
public isPlaying: boolean;
|
||||
//@private
|
||||
_resolveAnimationCurve(curve: any): any
|
||||
//@endprivate
|
||||
}
|
||||
|
||||
//@private
|
||||
export function _resolveAnimationCurve(curve: any): any;
|
||||
//@endprivate
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import styleScope = require("../styling/style-scope");
|
||||
import enums = require("ui/enums");
|
||||
import utils = require("utils/utils");
|
||||
import color = require("color");
|
||||
import animationModule = require("ui/animation");
|
||||
import observable = require("data/observable");
|
||||
import {PropertyMetadata, ProxyObject} from "ui/core/proxy";
|
||||
import {PropertyMetadataSettings, PropertyChangeData, Property, ValueSource, PropertyMetadata as doPropertyMetadata} from "ui/core/dependency-observable";
|
||||
@@ -17,6 +16,7 @@ import {CommonLayoutParams, nativeLayoutParamsProperty} from "ui/styling/style";
|
||||
import * as visualStateConstants from "ui/styling/visual-state-constants";
|
||||
import * as bindableModule from "ui/core/bindable";
|
||||
import * as visualStateModule from "../styling/visual-state";
|
||||
import * as animModule from "ui/animation";
|
||||
|
||||
var bindable: typeof bindableModule;
|
||||
function ensureBindable() {
|
||||
@@ -1139,11 +1139,12 @@ export class View extends ProxyObject implements definition.View {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public animate(animation: animationModule.AnimationDefinition): Promise<void> {
|
||||
public animate(animation: any): Promise<void> {
|
||||
return this.createAnimation(animation).play();
|
||||
}
|
||||
|
||||
public createAnimation(animation: animationModule.AnimationDefinition): animationModule.Animation {
|
||||
public createAnimation(animation: any): any {
|
||||
var animationModule: typeof animModule = require("ui/animation");
|
||||
var that = this;
|
||||
animation.target = that;
|
||||
return new animationModule.Animation([animation]);
|
||||
|
||||
@@ -403,10 +403,14 @@ function showUIAlertController(alertController: UIAlertController) {
|
||||
|
||||
var lblColor = dialogsCommon.getLabelColor();
|
||||
if (lblColor) {
|
||||
var title = NSAttributedString.alloc().initWithStringAttributes(alertController.title, <any>{ [NSForegroundColorAttributeName]: lblColor.ios });
|
||||
alertController.setValueForKey(title, "attributedTitle");
|
||||
var message = NSAttributedString.alloc().initWithStringAttributes(alertController.message, <any>{ [NSForegroundColorAttributeName]: lblColor.ios });
|
||||
alertController.setValueForKey(message, "attributedMessage");
|
||||
if (alertController.title) {
|
||||
var title = NSAttributedString.alloc().initWithStringAttributes(alertController.title, <any>{ [NSForegroundColorAttributeName]: lblColor.ios });
|
||||
alertController.setValueForKey(title, "attributedTitle");
|
||||
}
|
||||
if (alertController.message) {
|
||||
var message = NSAttributedString.alloc().initWithStringAttributes(alertController.message, <any>{ [NSForegroundColorAttributeName]: lblColor.ios });
|
||||
alertController.setValueForKey(message, "attributedMessage");
|
||||
}
|
||||
}
|
||||
|
||||
viewController.presentModalViewControllerAnimated(alertController, true);
|
||||
|
||||
@@ -138,9 +138,11 @@ export class Frame extends CustomLayoutView implements definition.Frame {
|
||||
private _backStack: Array<definition.BackstackEntry>;
|
||||
public _currentEntry: definition.BackstackEntry;
|
||||
private _animated: boolean;
|
||||
private _navigationTransition: definition.NavigationTransition;
|
||||
|
||||
public _isInFrameStack = false;
|
||||
public static defaultAnimatedNavigation = true;
|
||||
public static defaultNavigationTransition: definition.NavigationTransition;
|
||||
|
||||
// TODO: Currently our navigation will not be synchronized in case users directly call native navigation methods like Activity.startActivity.
|
||||
|
||||
@@ -160,7 +162,7 @@ export class Frame extends CustomLayoutView implements definition.Frame {
|
||||
* @param to The backstack entry to navigate back to.
|
||||
*/
|
||||
public goBack(backstackEntry?: definition.BackstackEntry) {
|
||||
trace.write(this._getTraceId() + ".goBack();", trace.categories.Navigation);
|
||||
trace.write(`GO BACK`, trace.categories.Navigation);
|
||||
if (!this.canGoBack()) {
|
||||
// TODO: Do we need to throw an error?
|
||||
return;
|
||||
@@ -187,12 +189,12 @@ export class Frame extends CustomLayoutView implements definition.Frame {
|
||||
this._processNavigationContext(navigationContext);
|
||||
}
|
||||
else {
|
||||
trace.write(this._getTraceId() + ".goBack scheduled;", trace.categories.Navigation);
|
||||
trace.write(`Going back scheduled`, trace.categories.Navigation);
|
||||
}
|
||||
}
|
||||
|
||||
public navigate(param: any) {
|
||||
trace.write(this._getTraceId() + ".navigate();", trace.categories.Navigation);
|
||||
trace.write(`NAVIGATE`, trace.categories.Navigation);
|
||||
|
||||
var entry = buildEntryFromArgs(param);
|
||||
var page = resolvePageFromEntry(entry);
|
||||
@@ -215,7 +217,7 @@ export class Frame extends CustomLayoutView implements definition.Frame {
|
||||
this._processNavigationContext(navigationContext);
|
||||
}
|
||||
else {
|
||||
trace.write(this._getTraceId() + ".navigation scheduled;", trace.categories.Navigation);
|
||||
trace.write(`Navigation scheduled`, trace.categories.Navigation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,7 +260,7 @@ export class Frame extends CustomLayoutView implements definition.Frame {
|
||||
}
|
||||
|
||||
public _updateActionBar(page?: Page) {
|
||||
trace.write("calling _updateActionBar on Frame", trace.categories.Navigation);
|
||||
//trace.write("calling _updateActionBar on Frame", trace.categories.Navigation);
|
||||
}
|
||||
|
||||
private _processNavigationContext(navigationContext: NavigationContext) {
|
||||
@@ -318,10 +320,19 @@ export class Frame extends CustomLayoutView implements definition.Frame {
|
||||
public get animated(): boolean {
|
||||
return this._animated;
|
||||
}
|
||||
|
||||
public set animated(value: boolean) {
|
||||
this._animated = value;
|
||||
}
|
||||
|
||||
public get navigationTransition(): definition.NavigationTransition {
|
||||
return this._navigationTransition;
|
||||
}
|
||||
|
||||
public set navigationTransition(value: definition.NavigationTransition) {
|
||||
this._navigationTransition = value;
|
||||
}
|
||||
|
||||
get backStack(): Array<definition.BackstackEntry> {
|
||||
return this._backStack.slice();
|
||||
}
|
||||
@@ -375,7 +386,7 @@ export class Frame extends CustomLayoutView implements definition.Frame {
|
||||
}
|
||||
}
|
||||
|
||||
public _getIsAnimatedNavigation(entry: definition.NavigationEntry) {
|
||||
public _getIsAnimatedNavigation(entry: definition.NavigationEntry): boolean {
|
||||
if (entry && isDefined(entry.animated)) {
|
||||
return entry.animated;
|
||||
}
|
||||
@@ -387,8 +398,16 @@ export class Frame extends CustomLayoutView implements definition.Frame {
|
||||
return Frame.defaultAnimatedNavigation;
|
||||
}
|
||||
|
||||
private _getTraceId(): string {
|
||||
return "Frame<" + this._domId + ">";
|
||||
public _getNavigationTransition(entry: definition.NavigationEntry): definition.NavigationTransition {
|
||||
if (entry && isDefined(entry.navigationTransition)) {
|
||||
return entry.navigationTransition;
|
||||
}
|
||||
|
||||
if (isDefined(this.navigationTransition)) {
|
||||
return this.navigationTransition;
|
||||
}
|
||||
|
||||
return Frame.defaultNavigationTransition;
|
||||
}
|
||||
|
||||
public get navigationBarHeight(): number {
|
||||
|
||||
@@ -6,6 +6,7 @@ import observable = require("data/observable");
|
||||
import application = require("application");
|
||||
import * as types from "utils/types";
|
||||
import * as utilsModule from "utils/utils";
|
||||
import transitionModule = require("ui/transition");
|
||||
|
||||
global.moduleMerge(frameCommon, exports);
|
||||
|
||||
@@ -15,6 +16,7 @@ var HIDDEN = "_hidden";
|
||||
var INTENT_EXTRA = "com.tns.activity";
|
||||
var ANDROID_FRAME = "android_frame";
|
||||
var BACKSTACK_TAG = "_backstackTag";
|
||||
var IS_BACK = "_isBack";
|
||||
var NAV_DEPTH = "_navDepth";
|
||||
var CLEARING_HISTORY = "_clearingHistory";
|
||||
var activityInitialized = false;
|
||||
@@ -28,67 +30,78 @@ function ensureFragmentClass() {
|
||||
}
|
||||
|
||||
FragmentClass = (<any>android.app.Fragment).extend({
|
||||
|
||||
onCreate: function (savedInstanceState: android.os.Bundle) {
|
||||
trace.write(`${this.getTag()}.onCreate(${savedInstanceState})`, trace.categories.NativeLifecycle);
|
||||
this.super.onCreate(savedInstanceState);
|
||||
this.super.setHasOptionsMenu(true);
|
||||
},
|
||||
|
||||
onCreate: function (savedInstanceState: android.os.Bundle) {
|
||||
trace.write(`PageFragmentBody.onCreate(${savedInstanceState})`, trace.categories.NativeLifecycle);
|
||||
this.super.onCreate(savedInstanceState);
|
||||
this.super.setHasOptionsMenu(true);
|
||||
},
|
||||
|
||||
onCreateView: function (inflater: android.view.LayoutInflater, container: android.view.ViewGroup, savedInstanceState: android.os.Bundle): android.view.View {
|
||||
var entry = this.entry;
|
||||
var page = entry.resolvedPage;
|
||||
trace.write(`PageFragmentBody.onCreateView(${inflater}, ${page}, ${savedInstanceState})`, trace.categories.NativeLifecycle);
|
||||
if (savedInstanceState && savedInstanceState.getBoolean(HIDDEN, false)) {
|
||||
this.super.getFragmentManager().beginTransaction().hide(this).commit();
|
||||
page._onAttached(this.getActivity());
|
||||
}
|
||||
else {
|
||||
onFragmentShown(this);
|
||||
}
|
||||
return page._nativeView;
|
||||
},
|
||||
|
||||
onHiddenChanged: function (hidden: boolean) {
|
||||
trace.write(`PageFragmentBody.onHiddenChanged(${hidden})`, trace.categories.NativeLifecycle);
|
||||
this.super.onHiddenChanged(hidden);
|
||||
if (hidden) {
|
||||
onFragmentHidden(this);
|
||||
}
|
||||
else {
|
||||
onFragmentShown(this);
|
||||
}
|
||||
},
|
||||
|
||||
onSaveInstanceState: function (outState: android.os.Bundle) {
|
||||
trace.write(`PageFragmentBody.onSaveInstanceState(${outState})`, trace.categories.NativeLifecycle);
|
||||
this.super.onSaveInstanceState(outState);
|
||||
if (this.isHidden()) {
|
||||
outState.putBoolean(HIDDEN, true);
|
||||
}
|
||||
},
|
||||
|
||||
onDestroyView: function () {
|
||||
trace.write(`PageFragmentBody.onDestroyView()`, trace.categories.NativeLifecycle);
|
||||
this.super.onDestroyView();
|
||||
onFragmentHidden(this);
|
||||
},
|
||||
|
||||
onDestroy: function () {
|
||||
trace.write(`PageFragmentBody.onDestroy()`, trace.categories.NativeLifecycle);
|
||||
this.super.onDestroy();
|
||||
|
||||
var utils: typeof utilsModule = require("utils/utils");
|
||||
|
||||
utils.GC();
|
||||
onCreateView: function (inflater: android.view.LayoutInflater, container: android.view.ViewGroup, savedInstanceState: android.os.Bundle): android.view.View {
|
||||
trace.write(`${this.getTag()}.onCreateView(inflater, container, ${savedInstanceState})`, trace.categories.NativeLifecycle);
|
||||
var entry = this.entry;
|
||||
var page = entry.resolvedPage;
|
||||
if (savedInstanceState && savedInstanceState.getBoolean(HIDDEN, false)) {
|
||||
this.super.getFragmentManager().beginTransaction().hide(this).commit();
|
||||
page._onAttached(this.getActivity());
|
||||
}
|
||||
});
|
||||
else {
|
||||
onFragmentShown(this);
|
||||
}
|
||||
return page._nativeView;
|
||||
},
|
||||
|
||||
onHiddenChanged: function (hidden: boolean) {
|
||||
trace.write(`${this.getTag()}.onHiddenChanged(${hidden})`, trace.categories.NativeLifecycle);
|
||||
this.super.onHiddenChanged(hidden);
|
||||
if (hidden) {
|
||||
onFragmentHidden(this);
|
||||
}
|
||||
else {
|
||||
onFragmentShown(this);
|
||||
}
|
||||
},
|
||||
|
||||
onSaveInstanceState: function (outState: android.os.Bundle) {
|
||||
trace.write(`${this.getTag()}.onSaveInstanceState(${outState})`, trace.categories.NativeLifecycle);
|
||||
this.super.onSaveInstanceState(outState);
|
||||
if (this.isHidden()) {
|
||||
outState.putBoolean(HIDDEN, true);
|
||||
}
|
||||
},
|
||||
|
||||
onDestroyView: function () {
|
||||
trace.write(`${this.getTag()}.onDestroyView()`, trace.categories.NativeLifecycle);
|
||||
this.super.onDestroyView();
|
||||
onFragmentHidden(this);
|
||||
},
|
||||
|
||||
onDestroy: function () {
|
||||
trace.write(`${this.getTag()}.onDestroy()`, trace.categories.NativeLifecycle);
|
||||
this.super.onDestroy();
|
||||
|
||||
var utils: typeof utilsModule = require("utils/utils");
|
||||
|
||||
utils.GC();
|
||||
},
|
||||
|
||||
onCreateAnimator: function (transit: number, enter: boolean, nextAnim: number): android.animation.Animator {
|
||||
var animator = transitionModule._onFragmentCreateAnimator(this, nextAnim);
|
||||
|
||||
if (!animator) {
|
||||
animator = this.super.onCreateAnimator(transit, enter, nextAnim);
|
||||
}
|
||||
|
||||
trace.write(`${this.getTag() }.onCreateAnimator(${transit}, ${enter}, ${nextAnim}): ${animator}`, trace.categories.NativeLifecycle);
|
||||
return animator;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onFragmentShown(fragment) {
|
||||
trace.write(`onFragmentShown(${fragment.toString()})`, trace.categories.NativeLifecycle);
|
||||
trace.write(`SHOWN ${fragment.getTag()}`, trace.categories.NativeLifecycle);
|
||||
if (fragment[CLEARING_HISTORY]) {
|
||||
trace.write(`${fragment.toString() } has been shown, but we are currently clearing history. Returning.`, trace.categories.NativeLifecycle);
|
||||
trace.write(`${fragment.getTag()} has been shown, but we are currently clearing history. Returning.`, trace.categories.NativeLifecycle);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -99,7 +112,7 @@ function onFragmentShown(fragment) {
|
||||
var page: pages.Page = entry.resolvedPage;
|
||||
|
||||
let currentNavigationContext;
|
||||
let navigationQueue = (<any>frame)._navigationQueue;
|
||||
let navigationQueue = frame._navigationQueue;
|
||||
for (let i = 0; i < navigationQueue.length; i++) {
|
||||
if (navigationQueue[i].entry === entry) {
|
||||
currentNavigationContext = navigationQueue[i];
|
||||
@@ -108,34 +121,33 @@ function onFragmentShown(fragment) {
|
||||
}
|
||||
|
||||
var isBack = currentNavigationContext ? currentNavigationContext.isBackNavigation : false;
|
||||
|
||||
frame._currentEntry = entry;
|
||||
|
||||
frame._addView(page);
|
||||
|
||||
// onFragmentShown is called before NativeActivity.start where we call frame.onLoaded
|
||||
// We need to call frame.onLoaded() here so that the call to frame._addView(page) will emit the page.loaded event
|
||||
// before the page.navigatedTo event making the two platforms identical.
|
||||
if (!frame.isLoaded) {
|
||||
frame._currentEntry = entry;
|
||||
frame.onLoaded();
|
||||
}
|
||||
page.onNavigatedTo(isBack);
|
||||
frame._processNavigationQueue(page);
|
||||
|
||||
// Handle page transitions.
|
||||
transitionModule._onFragmentShown(fragment, isBack);
|
||||
}
|
||||
|
||||
function onFragmentHidden(fragment) {
|
||||
trace.write(`onFragmentHidden(${fragment.toString()})`, trace.categories.NativeLifecycle);
|
||||
trace.write(`HIDDEN ${fragment.getTag()}`, trace.categories.NativeLifecycle);
|
||||
|
||||
if (fragment[CLEARING_HISTORY]) {
|
||||
trace.write(`${fragment.toString() } has been hidden, but we are currently clearing history. Returning.`, trace.categories.NativeLifecycle);
|
||||
trace.write(`${fragment.getTag()} has been hidden, but we are currently clearing history. Returning.`, trace.categories.NativeLifecycle);
|
||||
return null;
|
||||
}
|
||||
|
||||
var entry: definition.BackstackEntry = fragment.entry;
|
||||
var page: pages.Page = entry.resolvedPage;
|
||||
// This might be a second call if the fragment is hidden and then destroyed.
|
||||
if (page && page.frame) {
|
||||
var frame = page.frame;
|
||||
frame._removeView(page);
|
||||
}
|
||||
var isBack = fragment.entry[IS_BACK];
|
||||
fragment.entry[IS_BACK] = undefined;
|
||||
|
||||
// Handle page transitions.
|
||||
transitionModule._onFragmentHidden(fragment, isBack);
|
||||
}
|
||||
|
||||
export class Frame extends frameCommon.Frame {
|
||||
@@ -157,6 +169,13 @@ export class Frame extends frameCommon.Frame {
|
||||
frameCommon.Frame.defaultAnimatedNavigation = value;
|
||||
}
|
||||
|
||||
public static get defaultNavigationTransition(): definition.NavigationTransition {
|
||||
return frameCommon.Frame.defaultNavigationTransition;
|
||||
}
|
||||
public static set defaultNavigationTransition(value: definition.NavigationTransition) {
|
||||
frameCommon.Frame.defaultNavigationTransition = value;
|
||||
}
|
||||
|
||||
get containerViewId(): number {
|
||||
return this._containerViewId;
|
||||
}
|
||||
@@ -170,7 +189,7 @@ export class Frame extends frameCommon.Frame {
|
||||
}
|
||||
|
||||
public _navigateCore(backstackEntry: definition.BackstackEntry) {
|
||||
trace.write(`_navigateCore; id: ${backstackEntry.resolvedPage.id}; backstackVisible: ${this._isEntryBackstackVisible(backstackEntry)}; clearHistory: ${backstackEntry.entry.clearHistory};`, trace.categories.Navigation);
|
||||
trace.write(`${this}._navigateCore(page: ${backstackEntry.resolvedPage}, backstackVisible: ${this._isEntryBackstackVisible(backstackEntry)}, clearHistory: ${backstackEntry.entry.clearHistory}), navDepth: ${navDepth}`, trace.categories.Navigation);
|
||||
|
||||
var activity = this._android.activity;
|
||||
if (!activity) {
|
||||
@@ -195,7 +214,7 @@ export class Frame extends frameCommon.Frame {
|
||||
var fragment: android.app.Fragment;
|
||||
while (i >= 0) {
|
||||
fragment = manager.findFragmentByTag(manager.getBackStackEntryAt(i--).getName());
|
||||
trace.write(`${fragment.toString()}[CLEARING_HISTORY] = true;`, trace.categories.NativeLifecycle);
|
||||
trace.write(`${fragment.getTag()}[CLEARING_HISTORY] = true;`, trace.categories.NativeLifecycle);
|
||||
fragment[CLEARING_HISTORY] = true;
|
||||
}
|
||||
|
||||
@@ -204,7 +223,7 @@ export class Frame extends frameCommon.Frame {
|
||||
fragment = manager.findFragmentByTag(this.currentPage[TAG]);
|
||||
if (fragment) {
|
||||
fragment[CLEARING_HISTORY] = true;
|
||||
trace.write(`${fragment.toString() }[CLEARING_HISTORY] = true;`, trace.categories.NativeLifecycle);
|
||||
trace.write(`${fragment.getTag()}[CLEARING_HISTORY] = true;`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,10 +240,27 @@ export class Frame extends frameCommon.Frame {
|
||||
|
||||
var fragmentTransaction = manager.beginTransaction();
|
||||
|
||||
var currentFragmentTag: string;
|
||||
var currentFragment: android.app.Fragment;
|
||||
if (this.currentPage) {
|
||||
currentFragmentTag = this.currentPage[TAG];
|
||||
currentFragment = manager.findFragmentByTag(currentFragmentTag);
|
||||
}
|
||||
|
||||
var newFragmentTag = "fragment" + navDepth;
|
||||
ensureFragmentClass();
|
||||
var newFragment = new FragmentClass();
|
||||
|
||||
var animated = this._getIsAnimatedNavigation(backstackEntry.entry);
|
||||
var navigationTransition = this._getNavigationTransition(backstackEntry.entry);
|
||||
if (currentFragment) {
|
||||
// There might be transitions left over from previous forward navigations from the current page.
|
||||
transitionModule._clearForwardTransitions(currentFragment);
|
||||
}
|
||||
if (animated && navigationTransition) {
|
||||
transitionModule._setAndroidFragmentTransitions(navigationTransition, currentFragment, newFragment, fragmentTransaction);
|
||||
}
|
||||
|
||||
newFragment.frame = this;
|
||||
newFragment.entry = backstackEntry;
|
||||
|
||||
@@ -233,31 +269,27 @@ export class Frame extends frameCommon.Frame {
|
||||
|
||||
// remember the fragment tag at page level so that we can retrieve the fragment associated with a Page instance
|
||||
backstackEntry.resolvedPage[TAG] = newFragmentTag;
|
||||
|
||||
trace.write("Frame<" + this._domId + ">.fragmentTransaction PUSH depth = " + navDepth, trace.categories.Navigation);
|
||||
|
||||
if (this._isFirstNavigation) {
|
||||
fragmentTransaction.add(this.containerViewId, newFragment, newFragmentTag);
|
||||
trace.write("fragmentTransaction.add(" + this.containerViewId + ", " + newFragment + ", " + newFragmentTag + ");", trace.categories.NativeLifecycle);
|
||||
trace.write(`fragmentTransaction.add(${newFragmentTag});`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
else {
|
||||
if (this.android.cachePagesOnNavigate && !backstackEntry.entry.clearHistory) {
|
||||
var currentFragmentTag = this.currentPage[TAG];
|
||||
var currentFragment = manager.findFragmentByTag(currentFragmentTag);
|
||||
if (currentFragment) {
|
||||
fragmentTransaction.hide(currentFragment);
|
||||
trace.write("fragmentTransaction.hide(" + currentFragment + ");", trace.categories.NativeLifecycle);
|
||||
trace.write(`fragmentTransaction.hide(${currentFragmentTag});`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
else {
|
||||
trace.write("Could not find " + currentFragmentTag + " to hide", trace.categories.NativeLifecycle);
|
||||
trace.write(`Could not find ${currentFragmentTag} to hide.`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
|
||||
fragmentTransaction.add(this.containerViewId, newFragment, newFragmentTag);
|
||||
trace.write("fragmentTransaction.add(" + this.containerViewId + ", " + newFragment + ", " + newFragmentTag + ");", trace.categories.NativeLifecycle);
|
||||
trace.write(`fragmentTransaction.add(${newFragmentTag});`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
else {
|
||||
fragmentTransaction.replace(this.containerViewId, newFragment, newFragmentTag);
|
||||
trace.write("fragmentTransaction.replace(" + this.containerViewId + ", " + newFragment + ", " + newFragmentTag + ");", trace.categories.NativeLifecycle);
|
||||
trace.write(`fragmentTransaction.replace(${newFragmentTag});`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
|
||||
// Add to backStack if needed.
|
||||
@@ -265,13 +297,11 @@ export class Frame extends frameCommon.Frame {
|
||||
// We add each entry in the backstack to avoid the "Stack corrupted" mismatch
|
||||
var backstackTag = this._currentEntry[BACKSTACK_TAG];
|
||||
fragmentTransaction.addToBackStack(backstackTag);
|
||||
trace.write("fragmentTransaction.addToBackStack(" + backstackTag + ");", trace.categories.NativeLifecycle);
|
||||
trace.write(`fragmentTransaction.addToBackStack(${backstackTag});`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
}
|
||||
|
||||
if (!this._isFirstNavigation) {
|
||||
var animated = this._getIsAnimatedNavigation(backstackEntry.entry);
|
||||
|
||||
if (this.android.cachePagesOnNavigate) {
|
||||
// Apparently, there is an Android bug with when hiding fragments with animation.
|
||||
// https://code.google.com/p/android/issues/detail?id=32405
|
||||
@@ -279,18 +309,24 @@ export class Frame extends frameCommon.Frame {
|
||||
fragmentTransaction.setTransition(android.app.FragmentTransaction.TRANSIT_NONE);
|
||||
}
|
||||
else {
|
||||
var transition = animated ? android.app.FragmentTransaction.TRANSIT_FRAGMENT_OPEN : android.app.FragmentTransaction.TRANSIT_NONE;
|
||||
fragmentTransaction.setTransition(transition);
|
||||
var transit = animated ? android.app.FragmentTransaction.TRANSIT_FRAGMENT_OPEN : android.app.FragmentTransaction.TRANSIT_NONE;
|
||||
fragmentTransaction.setTransition(transit);
|
||||
}
|
||||
}
|
||||
|
||||
fragmentTransaction.commit();
|
||||
trace.write("fragmentTransaction.commit();", trace.categories.NativeLifecycle);
|
||||
trace.write(`fragmentTransaction.commit();`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
|
||||
public _goBackCore(backstackEntry: definition.BackstackEntry) {
|
||||
navDepth = backstackEntry[NAV_DEPTH];
|
||||
trace.write("Frame<" + this._domId + ">.fragmentTransaction POP depth = " + navDepth, trace.categories.Navigation);
|
||||
|
||||
if (this._currentEntry) {
|
||||
// We need this information inside onFragmentHidden
|
||||
this._currentEntry[IS_BACK] = true;
|
||||
}
|
||||
|
||||
trace.write(`${this}._goBackCore(pageId: ${backstackEntry.resolvedPage.id}, backstackVisible: ${this._isEntryBackstackVisible(backstackEntry) }, clearHistory: ${backstackEntry.entry.clearHistory}), navDepth: ${navDepth}`, trace.categories.Navigation);
|
||||
|
||||
var manager = this._android.activity.getFragmentManager();
|
||||
if (manager.getBackStackEntryCount() > 0) {
|
||||
@@ -350,7 +386,7 @@ export class Frame extends frameCommon.Frame {
|
||||
console.log("Fragment Manager Back Stack (" + length + ")");
|
||||
while (i >= 0) {
|
||||
var fragment = <any>manager.findFragmentByTag(manager.getBackStackEntryAt(i--).getName());
|
||||
console.log("[ " + fragment.toString() + " ]");
|
||||
console.log("[ " + fragment.getTag() + " ]");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,7 +428,7 @@ var NativeActivity = {
|
||||
},
|
||||
|
||||
onCreate: function (savedInstanceState: android.os.Bundle) {
|
||||
trace.write("NativeScriptActivity.onCreate(); savedInstanceState: " + savedInstanceState, trace.categories.NativeLifecycle);
|
||||
trace.write(`NativeActivity.onCreate(${savedInstanceState})`, trace.categories.NativeLifecycle);
|
||||
|
||||
// Find the frame for this activity.
|
||||
var frameId = this.getIntent().getExtras().getInt(INTENT_EXTRA);
|
||||
@@ -433,7 +469,7 @@ var NativeActivity = {
|
||||
|
||||
onActivityResult: function (requestCode: number, resultCode: number, data: android.content.Intent) {
|
||||
this.super.onActivityResult(requestCode, resultCode, data);
|
||||
trace.write("NativeScriptActivity.onActivityResult();", trace.categories.NativeLifecycle);
|
||||
trace.write(`NativeActivity.onActivityResult(${requestCode}, ${resultCode}, ${data})`, trace.categories.NativeLifecycle);
|
||||
|
||||
var result = application.android.onActivityResult;
|
||||
if (result) {
|
||||
@@ -451,7 +487,7 @@ var NativeActivity = {
|
||||
},
|
||||
|
||||
onAttachFragment: function (fragment: android.app.Fragment) {
|
||||
trace.write("NativeScriptActivity.onAttachFragment() : " + fragment.getTag(), trace.categories.NativeLifecycle);
|
||||
trace.write(`NativeActivity.onAttachFragment(${fragment.getTag()})`, trace.categories.NativeLifecycle);
|
||||
this.super.onAttachFragment(fragment);
|
||||
|
||||
if (!(<any>fragment).entry) {
|
||||
@@ -463,7 +499,7 @@ var NativeActivity = {
|
||||
|
||||
onStart: function () {
|
||||
this.super.onStart();
|
||||
trace.write("NativeScriptActivity.onStart();", trace.categories.NativeLifecycle);
|
||||
trace.write("NativeActivity.onStart()", trace.categories.NativeLifecycle);
|
||||
if (!this.frame.isLoaded) {
|
||||
this.frame.onLoaded();
|
||||
}
|
||||
@@ -471,11 +507,12 @@ var NativeActivity = {
|
||||
|
||||
onStop: function () {
|
||||
this.super.onStop();
|
||||
trace.write("NativeScriptActivity.onStop();", trace.categories.NativeLifecycle);
|
||||
trace.write("NativeActivity.onStop()", trace.categories.NativeLifecycle);
|
||||
this.frame.onUnloaded();
|
||||
},
|
||||
|
||||
onDestroy: function () {
|
||||
trace.write("NativeActivity.onDestroy()", trace.categories.NativeLifecycle);
|
||||
// TODO: Implement uninitialized(detached) routine
|
||||
var frame = this.frame;
|
||||
frame._onDetached(true);
|
||||
@@ -488,10 +525,10 @@ var NativeActivity = {
|
||||
this.androidFrame.reset();
|
||||
|
||||
this.super.onDestroy();
|
||||
trace.write("NativeScriptActivity.onDestroy();", trace.categories.NativeLifecycle);
|
||||
},
|
||||
|
||||
onOptionsItemSelected: function (menuItem: android.view.IMenuItem) {
|
||||
trace.write(`NativeActivity.onOptionsItemSelected(${menuItem})`, trace.categories.NativeLifecycle);
|
||||
if (!this.androidFrame.hasListeners(frameCommon.Frame.androidOptionSelectedEvent)) {
|
||||
return false;
|
||||
}
|
||||
@@ -508,7 +545,7 @@ var NativeActivity = {
|
||||
},
|
||||
|
||||
onBackPressed: function () {
|
||||
trace.write("NativeScriptActivity.onBackPressed;", trace.categories.NativeLifecycle);
|
||||
trace.write("NativeActivity.onBackPressed()", trace.categories.NativeLifecycle);
|
||||
|
||||
var args = <application.AndroidActivityBackPressedEventData>{
|
||||
eventName: "activityBackPressed",
|
||||
@@ -528,6 +565,7 @@ var NativeActivity = {
|
||||
},
|
||||
|
||||
onLowMemory: function () {
|
||||
trace.write("NativeActivity.onLowMemory()", trace.categories.NativeLifecycle);
|
||||
gc();
|
||||
java.lang.System.gc();
|
||||
this.super.onLowMemory();
|
||||
@@ -536,6 +574,7 @@ var NativeActivity = {
|
||||
},
|
||||
|
||||
onTrimMemory: function (level: number) {
|
||||
trace.write(`NativeActivity.onTrimMemory(${level})`, trace.categories.NativeLifecycle);
|
||||
gc();
|
||||
java.lang.System.gc();
|
||||
this.super.onTrimMemory(level);
|
||||
@@ -688,26 +727,31 @@ function findPageForFragment(fragment: android.app.Fragment, frame: Frame) {
|
||||
var page: pages.Page;
|
||||
var entry: definition.BackstackEntry;
|
||||
|
||||
trace.write("Attached fragment with no page: " + fragmentTag, trace.categories.NativeLifecycle);
|
||||
trace.write(`Finding page for ${fragmentTag}.`, trace.categories.NativeLifecycle);
|
||||
if (fragmentTag === (<any>pages).DIALOG_FRAGMENT_TAG) {
|
||||
trace.write(`No need to find page for dialog fragment.`, trace.categories.NativeLifecycle);
|
||||
return;
|
||||
}
|
||||
|
||||
if (frame.currentPage && frame.currentPage[TAG] === fragmentTag) {
|
||||
page = frame.currentPage;
|
||||
entry = frame._currentEntry;
|
||||
trace.write("Current page matches fragment: " + fragmentTag, trace.categories.NativeLifecycle);
|
||||
trace.write(`Current page matches fragment ${fragmentTag}.`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
else {
|
||||
var backStack = frame.backStack;
|
||||
for (var i = 0; i < backStack.length; i++) {
|
||||
entry = backStack[i];
|
||||
if (backStack[i].resolvedPage[TAG] === fragmentTag) {
|
||||
entry = backStack[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (entry) {
|
||||
trace.write("Found entry:" + entry + " for fragment: " + fragmentTag, trace.categories.NativeLifecycle);
|
||||
page = entry.resolvedPage;
|
||||
trace.write(`Found ${page} for ${fragmentTag}`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
}
|
||||
|
||||
if (page) {
|
||||
(<any>fragment).frame = frame;
|
||||
(<any>fragment).entry = entry;
|
||||
@@ -715,7 +759,7 @@ function findPageForFragment(fragment: android.app.Fragment, frame: Frame) {
|
||||
page[TAG] = fragmentTag;
|
||||
}
|
||||
else {
|
||||
//throw new Error("Could not find Page for Fragment.");
|
||||
//throw new Error(`Could not find a page for ${fragmentTag}.`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
36
ui/frame/frame.d.ts
vendored
36
ui/frame/frame.d.ts
vendored
@@ -73,11 +73,21 @@ declare module "ui/frame" {
|
||||
*/
|
||||
animated: boolean;
|
||||
|
||||
/**
|
||||
* Gets or sets the default navigation transition for this frame.
|
||||
*/
|
||||
navigationTransition: NavigationTransition;
|
||||
|
||||
/**
|
||||
* Gets or sets if navigation transitions should be animated globally.
|
||||
*/
|
||||
static defaultAnimatedNavigation: boolean;
|
||||
|
||||
/**
|
||||
* Gets or sets the default NavigationTransition for all frames across the app.
|
||||
*/
|
||||
static defaultNavigationTransition: NavigationTransition;
|
||||
|
||||
/**
|
||||
* Gets the AndroidFrame object that represents the Android-specific APIs for this Frame. Valid when running on Android OS.
|
||||
*/
|
||||
@@ -149,6 +159,11 @@ declare module "ui/frame" {
|
||||
*/
|
||||
animated?: boolean;
|
||||
|
||||
/**
|
||||
* Specifies an optional navigation transition. If not specified, the default platform transition will be used.
|
||||
*/
|
||||
navigationTransition?: NavigationTransition;
|
||||
|
||||
/**
|
||||
* True to record the navigation in the backstack, false otherwise.
|
||||
* If the parameter is set to false then the Page will be displayed but once navigated from it will not be able to be navigated back to.
|
||||
@@ -161,6 +176,27 @@ declare module "ui/frame" {
|
||||
clearHistory?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an object specifying a page navigation transition.
|
||||
*/
|
||||
export interface NavigationTransition {
|
||||
/**
|
||||
* Either a string specifying one of the built-in transitions or an user-defined instance of the "ui/transition".Transition class.
|
||||
*/
|
||||
transition: any;
|
||||
|
||||
/**
|
||||
* The length of the transition in milliseconds. If you do not specify this, the default platform transition duration will be used.
|
||||
*/
|
||||
duration?: number;
|
||||
|
||||
/**
|
||||
* An optional transition animation curve. Possible values are contained in the [AnimationCurve enumeration](../enums/AnimationCurve/README.md).
|
||||
* Alternatively, you can pass an instance of type UIViewAnimationCurve for iOS or android.animation.TimeInterpolator for Android.
|
||||
*/
|
||||
curve?: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an entry in the back stack of a Frame object.
|
||||
*/
|
||||
|
||||
@@ -7,12 +7,14 @@ import utils = require("utils/utils");
|
||||
import view = require("ui/core/view");
|
||||
import uiUtils = require("ui/utils");
|
||||
import * as types from "utils/types";
|
||||
import * as animationModule from "ui/animation";
|
||||
import * as transitionModule from "ui/transition";
|
||||
|
||||
global.moduleMerge(frameCommon, exports);
|
||||
|
||||
var ENTRY = "_entry";
|
||||
var NAV_DEPTH = "_navDepth";
|
||||
|
||||
var TRANSITION = "_transition";
|
||||
var navDepth = -1;
|
||||
|
||||
export class Frame extends frameCommon.Frame {
|
||||
@@ -50,6 +52,7 @@ export class Frame extends frameCommon.Frame {
|
||||
}
|
||||
|
||||
public _navigateCore(backstackEntry: definition.BackstackEntry) {
|
||||
trace.write(`${this}._navigateCore(pageId: ${backstackEntry.resolvedPage.id}, backstackVisible: ${this._isEntryBackstackVisible(backstackEntry) }, clearHistory: ${backstackEntry.entry.clearHistory}), navDepth: ${navDepth}`, trace.categories.Navigation);
|
||||
var viewController: UIViewController = backstackEntry.resolvedPage.ios;
|
||||
if (!viewController) {
|
||||
throw new Error("Required page does not have a viewController created.");
|
||||
@@ -57,9 +60,10 @@ export class Frame extends frameCommon.Frame {
|
||||
|
||||
navDepth++;
|
||||
|
||||
var animated = false;
|
||||
if (this.currentPage) {
|
||||
animated = this._getIsAnimatedNavigation(backstackEntry.entry);
|
||||
var animated = this.currentPage ? this._getIsAnimatedNavigation(backstackEntry.entry) : false;
|
||||
var navigationTransition = this._getNavigationTransition(backstackEntry.entry);
|
||||
if (animated && navigationTransition) {
|
||||
viewController[TRANSITION] = navigationTransition;
|
||||
}
|
||||
|
||||
backstackEntry[NAV_DEPTH] = navDepth;
|
||||
@@ -70,7 +74,7 @@ export class Frame extends frameCommon.Frame {
|
||||
// First navigation.
|
||||
if (!this._currentEntry) {
|
||||
this._ios.controller.pushViewControllerAnimated(viewController, animated);
|
||||
trace.write("Frame<" + this._domId + ">.pushViewControllerAnimated(newController) depth = " + navDepth, trace.categories.Navigation);
|
||||
trace.write(`${this}.pushViewControllerAnimated(${viewController}, ${animated}); depth = ${navDepth}`, trace.categories.Navigation);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -80,7 +84,7 @@ export class Frame extends frameCommon.Frame {
|
||||
var newControllers = NSMutableArray.alloc().initWithCapacity(1);
|
||||
newControllers.addObject(viewController);
|
||||
this._ios.controller.setViewControllersAnimated(newControllers, animated);
|
||||
trace.write("Frame<" + this._domId + ">.setViewControllersAnimated([newController]) depth = " + navDepth, trace.categories.Navigation);
|
||||
trace.write(`${this}.setViewControllersAnimated([${viewController}], ${animated}); depth = ${navDepth}`, trace.categories.Navigation);
|
||||
return;
|
||||
|
||||
}
|
||||
@@ -102,24 +106,25 @@ export class Frame extends frameCommon.Frame {
|
||||
|
||||
// replace the controllers instead of pushing directly
|
||||
this._ios.controller.setViewControllersAnimated(newControllers, animated);
|
||||
trace.write("Frame<" + this._domId + ">.setViewControllersAnimated([originalControllers - lastController + newController]) depth = " + navDepth, trace.categories.Navigation);
|
||||
trace.write(`${this}.setViewControllersAnimated([originalControllers - lastController + ${viewController}], ${animated}); depth = ${navDepth}`, trace.categories.Navigation);
|
||||
return;
|
||||
}
|
||||
|
||||
// General case.
|
||||
this._ios.controller.pushViewControllerAnimated(viewController, animated);
|
||||
trace.write("Frame<" + this._domId + ">.pushViewControllerAnimated(newController) depth = " + navDepth, trace.categories.Navigation);
|
||||
trace.write(`${this}.pushViewControllerAnimated(${viewController}, ${animated}); depth = ${navDepth}`, trace.categories.Navigation);
|
||||
}
|
||||
|
||||
public _goBackCore(backstackEntry: definition.BackstackEntry) {
|
||||
navDepth = backstackEntry[NAV_DEPTH];
|
||||
trace.write("Frame<" + this._domId + ">.popViewControllerAnimated depth = " + navDepth, trace.categories.Navigation);
|
||||
trace.write(`${this}._goBackCore(pageId: ${backstackEntry.resolvedPage.id}, backstackVisible: ${this._isEntryBackstackVisible(backstackEntry) }, clearHistory: ${backstackEntry.entry.clearHistory}), navDepth: ${navDepth}`, trace.categories.Navigation);
|
||||
|
||||
if (!this._shouldSkipNativePop) {
|
||||
var controller = backstackEntry.resolvedPage.ios;
|
||||
var animated = this._getIsAnimatedNavigation(backstackEntry.entry);
|
||||
var animated = this._currentEntry ? this._getIsAnimatedNavigation(this._currentEntry.entry) : false;
|
||||
|
||||
this._updateActionBar(backstackEntry.resolvedPage);
|
||||
trace.write(`${this}.popToViewControllerAnimated(${controller}, ${animated}); depth = ${navDepth}`, trace.categories.Navigation);
|
||||
this._ios.controller.popToViewControllerAnimated(controller, animated);
|
||||
}
|
||||
}
|
||||
@@ -174,6 +179,13 @@ export class Frame extends frameCommon.Frame {
|
||||
frameCommon.Frame.defaultAnimatedNavigation = value;
|
||||
}
|
||||
|
||||
public static get defaultNavigationTransition(): definition.NavigationTransition {
|
||||
return frameCommon.Frame.defaultNavigationTransition;
|
||||
}
|
||||
public static set defaultNavigationTransition(value: definition.NavigationTransition) {
|
||||
frameCommon.Frame.defaultNavigationTransition = value;
|
||||
}
|
||||
|
||||
public requestLayout(): void {
|
||||
super.requestLayout();
|
||||
// Invalidate our Window so that layout is triggered again.
|
||||
@@ -265,14 +277,58 @@ export class Frame extends frameCommon.Frame {
|
||||
}
|
||||
}
|
||||
|
||||
class TransitionDelegate extends NSObject {
|
||||
static new(): TransitionDelegate {
|
||||
return <TransitionDelegate>super.new();
|
||||
}
|
||||
|
||||
private _owner: UINavigationControllerImpl;
|
||||
private _id: string;
|
||||
|
||||
public initWithOwnerId(owner: UINavigationControllerImpl, id: string): TransitionDelegate {
|
||||
this._owner = owner;
|
||||
this._owner.transitionDelegates.push(this);
|
||||
this._id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public animationWillStart(animationID: string, context: any): void {
|
||||
trace.write(`START ${this._id}`, trace.categories.Transition);
|
||||
}
|
||||
|
||||
public animationDidStop(animationID: string, finished: boolean, context: any): void {
|
||||
if (finished) {
|
||||
trace.write(`END ${this._id}`, trace.categories.Transition);
|
||||
}
|
||||
else {
|
||||
trace.write(`CANCEL ${this._id}`, trace.categories.Transition);
|
||||
}
|
||||
|
||||
if (this._owner) {
|
||||
var index = this._owner.transitionDelegates.indexOf(this);
|
||||
if (index > -1) {
|
||||
this._owner.transitionDelegates.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ObjCExposedMethods = {
|
||||
"animationWillStart": { returns: interop.types.void, params: [NSString, NSObject] },
|
||||
"animationDidStop": { returns: interop.types.void, params: [NSString, NSNumber, NSObject] }
|
||||
};
|
||||
}
|
||||
|
||||
var _defaultTransitionDuration = 0.35;
|
||||
class UINavigationControllerImpl extends UINavigationController implements UINavigationControllerDelegate {
|
||||
public static ObjCProtocols = [UINavigationControllerDelegate];
|
||||
|
||||
private _owner: WeakRef<Frame>;
|
||||
private _transitionDelegates: Array<TransitionDelegate>;
|
||||
|
||||
public static initWithOwner(owner: WeakRef<Frame>): UINavigationControllerImpl {
|
||||
var controller = <UINavigationControllerImpl>UINavigationControllerImpl.new();
|
||||
controller._owner = owner;
|
||||
controller._transitionDelegates = new Array<TransitionDelegate>();
|
||||
return controller;
|
||||
}
|
||||
|
||||
@@ -280,6 +336,10 @@ class UINavigationControllerImpl extends UINavigationController implements UINav
|
||||
return this._owner.get();
|
||||
}
|
||||
|
||||
get transitionDelegates(): Array<TransitionDelegate> {
|
||||
return this._transitionDelegates;
|
||||
}
|
||||
|
||||
public viewDidLoad(): void {
|
||||
let owner = this._owner.get();
|
||||
if (owner) {
|
||||
@@ -332,15 +392,9 @@ class UINavigationControllerImpl extends UINavigationController implements UINav
|
||||
let newEntry: definition.BackstackEntry = viewController[ENTRY];
|
||||
let newPage = newEntry.resolvedPage;
|
||||
|
||||
// For some reason iOS calls navigationControllerDidShowViewControllerAnimated twice for the
|
||||
// main-page resulting in double 'loaded' and 'navigatedTo' events being fired.
|
||||
if (!(<any>newPage)._delayLoadedEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
let backStack = frame.backStack;
|
||||
let currentEntry = backStack.length > 0 ? backStack[backStack.length - 1] : null;
|
||||
|
||||
|
||||
// This code check if navigation happened through UI (e.g. back button or swipe gesture).
|
||||
// When calling goBack on frame isBack will be false.
|
||||
let isBack: boolean = currentEntry && newEntry === currentEntry;
|
||||
@@ -374,14 +428,6 @@ class UINavigationControllerImpl extends UINavigationController implements UINav
|
||||
frame._navigateToEntry = null;
|
||||
frame._currentEntry = newEntry;
|
||||
frame.remeasureFrame();
|
||||
|
||||
// In iOS we intentionally delay the raising of the 'loaded' event so both platforms behave identically.
|
||||
// The loaded event must be raised AFTER the page is part of the windows hierarchy and
|
||||
// frame.topmost().currentPage is set to the page instance.
|
||||
// https://github.com/NativeScript/NativeScript/issues/779
|
||||
(<any>newPage)._delayLoadedEvent = false;
|
||||
newPage._emit(view.View.loadedEvent);
|
||||
|
||||
frame._updateActionBar(newPage);
|
||||
|
||||
// notify the page
|
||||
@@ -392,6 +438,202 @@ class UINavigationControllerImpl extends UINavigationController implements UINav
|
||||
public supportedInterfaceOrientation(): number {
|
||||
return UIInterfaceOrientationMask.UIInterfaceOrientationMaskAll;
|
||||
}
|
||||
|
||||
public pushViewControllerAnimated(viewController: UIViewController, animated: boolean): void {
|
||||
var navigationTransition = <definition.NavigationTransition>viewController[TRANSITION];
|
||||
trace.write(`UINavigationControllerImpl.pushViewControllerAnimated(${viewController}, ${animated}); transition: ${JSON.stringify(navigationTransition)}`, trace.categories.NativeLifecycle);
|
||||
|
||||
if (!animated || !navigationTransition) {
|
||||
super.pushViewControllerAnimated(viewController, animated);
|
||||
return;
|
||||
}
|
||||
|
||||
var nativeTransition = _getNativeTransition(navigationTransition, true);
|
||||
if (!nativeTransition) {
|
||||
super.pushViewControllerAnimated(viewController, animated);
|
||||
return;
|
||||
}
|
||||
|
||||
var duration = navigationTransition.duration ? navigationTransition.duration / 1000 : _defaultTransitionDuration;
|
||||
var curve = _getNativeCurve(navigationTransition);
|
||||
var id = _getTransitionId(nativeTransition, "push");
|
||||
var transitionDelegate = TransitionDelegate.new().initWithOwnerId(this, id);
|
||||
UIView.animateWithDurationAnimations(duration, () => {
|
||||
UIView.setAnimationDelegate(transitionDelegate);
|
||||
UIView.setAnimationWillStartSelector("animationWillStart");
|
||||
UIView.setAnimationDidStopSelector("animationDidStop");
|
||||
UIView.setAnimationCurve(curve);
|
||||
super.pushViewControllerAnimated(viewController, false);
|
||||
UIView.setAnimationTransitionForViewCache(nativeTransition, this.view, true);
|
||||
});
|
||||
}
|
||||
|
||||
public setViewControllersAnimated(viewControllers: NSArray, animated: boolean): void {
|
||||
var viewController = viewControllers.lastObject;
|
||||
var navigationTransition = <definition.NavigationTransition>viewController[TRANSITION];
|
||||
trace.write(`UINavigationControllerImpl.setViewControllersAnimated(${viewControllers}, ${animated}); transition: ${JSON.stringify(navigationTransition)}`, trace.categories.NativeLifecycle);
|
||||
|
||||
if (!animated || !navigationTransition) {
|
||||
super.setViewControllersAnimated(viewControllers, animated);
|
||||
return;
|
||||
}
|
||||
|
||||
var nativeTransition = _getNativeTransition(navigationTransition, true);
|
||||
if (!nativeTransition) {
|
||||
super.setViewControllersAnimated(viewControllers, animated);
|
||||
return;
|
||||
}
|
||||
|
||||
var duration = navigationTransition.duration ? navigationTransition.duration / 1000 : _defaultTransitionDuration;
|
||||
var curve = _getNativeCurve(navigationTransition);
|
||||
var id = _getTransitionId(nativeTransition, "set");
|
||||
var transitionDelegate = TransitionDelegate.new().initWithOwnerId(this, id);
|
||||
UIView.animateWithDurationAnimations(duration, () => {
|
||||
UIView.setAnimationDelegate(transitionDelegate);
|
||||
UIView.setAnimationWillStartSelector("animationWillStart");
|
||||
UIView.setAnimationDidStopSelector("animationDidStop");
|
||||
UIView.setAnimationCurve(curve);
|
||||
super.setViewControllersAnimated(viewControllers, false);
|
||||
UIView.setAnimationTransitionForViewCache(nativeTransition, this.view, true);
|
||||
});
|
||||
}
|
||||
|
||||
public popViewControllerAnimated(animated: boolean): UIViewController {
|
||||
var lastViewController = this.viewControllers.lastObject;
|
||||
var navigationTransition = <definition.NavigationTransition>lastViewController[TRANSITION];
|
||||
trace.write(`UINavigationControllerImpl.popViewControllerAnimated(${animated}); transition: ${JSON.stringify(navigationTransition)}`, trace.categories.NativeLifecycle);
|
||||
|
||||
if (!animated || !navigationTransition) {
|
||||
return super.popViewControllerAnimated(animated);
|
||||
}
|
||||
|
||||
var nativeTransition = _getNativeTransition(navigationTransition, false);
|
||||
if (!nativeTransition) {
|
||||
return super.popViewControllerAnimated(animated);
|
||||
}
|
||||
|
||||
var duration = navigationTransition.duration ? navigationTransition.duration / 1000 : _defaultTransitionDuration;
|
||||
var curve = _getNativeCurve(navigationTransition);
|
||||
var id = _getTransitionId(nativeTransition, "pop");
|
||||
var transitionDelegate = TransitionDelegate.new().initWithOwnerId(this, id);
|
||||
UIView.animateWithDurationAnimations(duration, () => {
|
||||
UIView.setAnimationDelegate(transitionDelegate);
|
||||
UIView.setAnimationWillStartSelector("animationWillStart");
|
||||
UIView.setAnimationDidStopSelector("animationDidStop");
|
||||
UIView.setAnimationCurve(curve);
|
||||
super.popViewControllerAnimated(false);
|
||||
UIView.setAnimationTransitionForViewCache(nativeTransition, this.view, true);
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
public popToViewControllerAnimated(viewController: UIViewController, animated: boolean): NSArray {
|
||||
var lastViewController = this.viewControllers.lastObject;
|
||||
var navigationTransition = <definition.NavigationTransition>lastViewController[TRANSITION];
|
||||
trace.write(`UINavigationControllerImpl.popToViewControllerAnimated(${viewController}, ${animated}); transition: ${JSON.stringify(navigationTransition)}`, trace.categories.NativeLifecycle);
|
||||
if (!animated || !navigationTransition) {
|
||||
return super.popToViewControllerAnimated(viewController, animated);
|
||||
}
|
||||
|
||||
var nativeTransition = _getNativeTransition(navigationTransition, false);
|
||||
if (!nativeTransition) {
|
||||
return super.popToViewControllerAnimated(viewController, animated);
|
||||
}
|
||||
|
||||
var duration = navigationTransition.duration ? navigationTransition.duration / 1000 : _defaultTransitionDuration;
|
||||
var curve = _getNativeCurve(navigationTransition);
|
||||
var id = _getTransitionId(nativeTransition, "popTo");
|
||||
var transitionDelegate = TransitionDelegate.new().initWithOwnerId(this, id);
|
||||
UIView.animateWithDurationAnimations(duration, () => {
|
||||
UIView.setAnimationDelegate(transitionDelegate);
|
||||
UIView.setAnimationWillStartSelector("animationWillStart");
|
||||
UIView.setAnimationDidStopSelector("animationDidStop");
|
||||
UIView.setAnimationCurve(curve);
|
||||
super.popToViewControllerAnimated(viewController, false);
|
||||
UIView.setAnimationTransitionForViewCache(nativeTransition, this.view, true);
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
public navigationControllerAnimationControllerForOperationFromViewControllerToViewController(navigationController: UINavigationController, operation: number, fromVC: UIViewController, toVC: UIViewController): UIViewControllerAnimatedTransitioning {
|
||||
var viewController: UIViewController;
|
||||
switch (operation) {
|
||||
case UINavigationControllerOperation.UINavigationControllerOperationPush:
|
||||
viewController = toVC;
|
||||
break;
|
||||
case UINavigationControllerOperation.UINavigationControllerOperationPop:
|
||||
viewController = fromVC;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!viewController) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var navigationTransition = <definition.NavigationTransition>viewController[TRANSITION];
|
||||
if (!navigationTransition) {
|
||||
return null;
|
||||
}
|
||||
|
||||
trace.write(`UINavigationControllerImpl.navigationControllerAnimationControllerForOperationFromViewControllerToViewController(${operation}, ${fromVC}, ${toVC}), transition: ${JSON.stringify(navigationTransition)}`, trace.categories.NativeLifecycle);
|
||||
var _transitionModule: typeof transitionModule = require("ui/transition");
|
||||
return _transitionModule._createIOSAnimatedTransitioning(navigationTransition, operation, fromVC, toVC);
|
||||
}
|
||||
}
|
||||
|
||||
function _getTransitionId(nativeTransition: UIViewAnimationTransition, transitionType: string): string {
|
||||
var name;
|
||||
switch (nativeTransition) {
|
||||
case UIViewAnimationTransition.UIViewAnimationTransitionCurlDown: name = "CurlDown"; break;
|
||||
case UIViewAnimationTransition.UIViewAnimationTransitionCurlUp: name = "CurlUp"; break;
|
||||
case UIViewAnimationTransition.UIViewAnimationTransitionFlipFromLeft: name = "FlipFromLeft"; break;
|
||||
case UIViewAnimationTransition.UIViewAnimationTransitionFlipFromRight: name = "FlipFromRight"; break;
|
||||
case UIViewAnimationTransition.UIViewAnimationTransitionNone: name = "None"; break;
|
||||
}
|
||||
|
||||
return `${name} ${transitionType}`;
|
||||
}
|
||||
|
||||
function _getNativeTransition(navigationTransition: definition.NavigationTransition, push: boolean): UIViewAnimationTransition {
|
||||
if (types.isString(navigationTransition.transition)) {
|
||||
switch (navigationTransition.transition.toLowerCase()) {
|
||||
case "flip":
|
||||
case "flipright":
|
||||
return push ? UIViewAnimationTransition.UIViewAnimationTransitionFlipFromRight : UIViewAnimationTransition.UIViewAnimationTransitionFlipFromLeft;
|
||||
case "flipleft":
|
||||
return push ? UIViewAnimationTransition.UIViewAnimationTransitionFlipFromLeft : UIViewAnimationTransition.UIViewAnimationTransitionFlipFromRight;
|
||||
case "curl":
|
||||
case "curlup":
|
||||
return push ? UIViewAnimationTransition.UIViewAnimationTransitionCurlUp : UIViewAnimationTransition.UIViewAnimationTransitionCurlDown;
|
||||
case "curldown":
|
||||
return push ? UIViewAnimationTransition.UIViewAnimationTransitionCurlDown : UIViewAnimationTransition.UIViewAnimationTransitionCurlUp;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function _getNativeCurve(transition: definition.NavigationTransition) : UIViewAnimationCurve{
|
||||
if (transition.curve) {
|
||||
switch (transition.curve) {
|
||||
case enums.AnimationCurve.easeIn:
|
||||
trace.write("Transition curve resolved to UIViewAnimationCurve.UIViewAnimationCurveEaseIn.", trace.categories.Transition);
|
||||
return UIViewAnimationCurve.UIViewAnimationCurveEaseIn;
|
||||
case enums.AnimationCurve.easeOut:
|
||||
trace.write("Transition curve resolved to UIViewAnimationCurve.UIViewAnimationCurveEaseOut.", trace.categories.Transition);
|
||||
return UIViewAnimationCurve.UIViewAnimationCurveEaseOut;
|
||||
case enums.AnimationCurve.easeInOut:
|
||||
trace.write("Transition curve resolved to UIViewAnimationCurve.UIViewAnimationCurveEaseInOut.", trace.categories.Transition);
|
||||
return UIViewAnimationCurve.UIViewAnimationCurveEaseInOut;
|
||||
case enums.AnimationCurve.linear:
|
||||
trace.write("Transition curve resolved to UIViewAnimationCurve.UIViewAnimationCurveLinear.", trace.categories.Transition);
|
||||
return UIViewAnimationCurve.UIViewAnimationCurveLinear;
|
||||
default:
|
||||
trace.write("Transition curve resolved to original: " + transition.curve, trace.categories.Transition);
|
||||
return transition.curve;
|
||||
}
|
||||
}
|
||||
|
||||
return UIViewAnimationCurve.UIViewAnimationCurveEaseInOut;
|
||||
}
|
||||
|
||||
/* tslint:disable */
|
||||
|
||||
@@ -23,6 +23,8 @@ function ensureColor() {
|
||||
}
|
||||
}
|
||||
|
||||
export var DIALOG_FRAGMENT_TAG = "dialog";
|
||||
|
||||
var DialogFragmentClass;
|
||||
function ensureDialogFragmentClass() {
|
||||
if (DialogFragmentClass) {
|
||||
@@ -120,7 +122,7 @@ export class Page extends pageCommon.Page {
|
||||
if (skipDetached) {
|
||||
ensureTrace();
|
||||
// Do not detach the context and android reference.
|
||||
trace.write("Caching Page " + this._domId, trace.categories.NativeLifecycle);
|
||||
trace.write(`Caching ${this}`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
else {
|
||||
super._onDetached();
|
||||
@@ -153,7 +155,7 @@ export class Page extends pageCommon.Page {
|
||||
});
|
||||
|
||||
super._raiseShowingModallyEvent();
|
||||
this._dialogFragment.show(parent.frame.android.activity.getFragmentManager(), "dialog");
|
||||
this._dialogFragment.show(parent.frame.android.activity.getFragmentManager(), DIALOG_FRAGMENT_TAG);
|
||||
super._raiseShownModallyEvent(parent, context, closeCallback);
|
||||
}
|
||||
|
||||
|
||||
@@ -98,15 +98,6 @@ class UIViewControllerImpl extends UIViewController {
|
||||
|
||||
//https://github.com/NativeScript/NativeScript/issues/1201
|
||||
owner._viewWillDisappear = false;
|
||||
|
||||
// In iOS we intentionally delay the raising of the 'loaded' event so both platforms behave identically.
|
||||
// The loaded event must be raised AFTER the page is part of the windows hierarchy and
|
||||
// frame.topmost().currentPage is set to the page instance.
|
||||
// https://github.com/NativeScript/NativeScript/issues/779
|
||||
if (!owner._isModal) {
|
||||
owner._delayLoadedEvent = true;
|
||||
}
|
||||
|
||||
owner.onLoaded();
|
||||
owner._enableLoadedEvents = false;
|
||||
}
|
||||
@@ -145,7 +136,6 @@ export class Page extends pageCommon.Page {
|
||||
public _enableLoadedEvents: boolean;
|
||||
public _isModal: boolean;
|
||||
public _UIModalPresentationFormSheet: boolean;
|
||||
public _delayLoadedEvent: boolean;
|
||||
public _viewWillDisappear: boolean;
|
||||
|
||||
constructor(options?: definition.Options) {
|
||||
@@ -174,18 +164,6 @@ export class Page extends pageCommon.Page {
|
||||
this._updateActionBar(false);
|
||||
}
|
||||
|
||||
public notify<T extends observable.EventData>(data: T) {
|
||||
// In iOS we intentionally delay the raising of the 'loaded' event so both platforms behave identically.
|
||||
// The loaded event must be raised AFTER the page is part of the windows hierarchy and
|
||||
// frame.topmost().currentPage is set to the page instance.
|
||||
// https://github.com/NativeScript/NativeScript/issues/779
|
||||
if (data.eventName === View.loadedEvent && this._delayLoadedEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.notify(data);
|
||||
}
|
||||
|
||||
public onUnloaded() {
|
||||
// loaded/unloaded events are handled in page viewWillAppear/viewDidDisappear
|
||||
if (this._enableLoadedEvents) {
|
||||
|
||||
29
ui/transition/fade-transition.android.ts
Normal file
29
ui/transition/fade-transition.android.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import transition = require("ui/transition");
|
||||
import platform = require("platform");
|
||||
|
||||
var floatType = java.lang.Float.class.getField("TYPE").get(null);
|
||||
|
||||
export class FadeTransition extends transition.Transition {
|
||||
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
||||
var alphaValues = java.lang.reflect.Array.newInstance(floatType, 2);
|
||||
switch (transitionType) {
|
||||
case transition.AndroidTransitionType.enter:
|
||||
case transition.AndroidTransitionType.popEnter:
|
||||
alphaValues[0] = 0;
|
||||
alphaValues[1] = 1;
|
||||
break;
|
||||
case transition.AndroidTransitionType.exit:
|
||||
case transition.AndroidTransitionType.popExit:
|
||||
alphaValues[0] = 1;
|
||||
alphaValues[1] = 0;
|
||||
break;
|
||||
}
|
||||
var animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", alphaValues);
|
||||
var duration = this.getDuration();
|
||||
if (duration !== undefined) {
|
||||
animator.setDuration(duration);
|
||||
}
|
||||
animator.setInterpolator(this.getCurve());
|
||||
return animator;
|
||||
}
|
||||
}
|
||||
25
ui/transition/fade-transition.ios.ts
Normal file
25
ui/transition/fade-transition.ios.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import transition = require("ui/transition");
|
||||
|
||||
export class FadeTransition extends transition.Transition {
|
||||
public animateIOSTransition(containerView: UIView, fromView: UIView, toView: UIView, operation: UINavigationControllerOperation, completion: (finished: boolean) => void): void {
|
||||
toView.alpha = 0.0;
|
||||
fromView.alpha = 1.0;
|
||||
|
||||
switch (operation) {
|
||||
case UINavigationControllerOperation.UINavigationControllerOperationPush:
|
||||
containerView.insertSubviewAboveSubview(toView, fromView);
|
||||
break;
|
||||
case UINavigationControllerOperation.UINavigationControllerOperationPop:
|
||||
containerView.insertSubviewBelowSubview(toView, fromView);
|
||||
break;
|
||||
}
|
||||
|
||||
var duration = this.getDuration();
|
||||
var curve = this.getCurve();
|
||||
UIView.animateWithDurationAnimationsCompletion(duration, () => {
|
||||
UIView.setAnimationCurve(curve);
|
||||
toView.alpha = 1.0;
|
||||
fromView.alpha = 0.0;
|
||||
}, completion);
|
||||
}
|
||||
}
|
||||
120
ui/transition/flip-transition.android.ts
Normal file
120
ui/transition/flip-transition.android.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
import transition = require("ui/transition");
|
||||
import platform = require("platform");
|
||||
|
||||
var floatType = java.lang.Float.class.getField("TYPE").get(null);
|
||||
|
||||
//http://developer.android.com/training/animation/cardflip.html
|
||||
export class FlipTransition extends transition.Transition {
|
||||
private _direction: string;
|
||||
|
||||
constructor(direction: string, duration: number, curve: any) {
|
||||
super(duration, curve);
|
||||
this._direction = direction;
|
||||
}
|
||||
|
||||
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
||||
var objectAnimators;
|
||||
var values;
|
||||
var animator: android.animation.ObjectAnimator;
|
||||
var animatorSet = new android.animation.AnimatorSet();
|
||||
var fullDuration = this.getDuration() || 300;
|
||||
var interpolator = this.getCurve();
|
||||
var rotationY = this._direction === "right" ? 180 : -180;
|
||||
|
||||
switch (transitionType) {
|
||||
case transition.AndroidTransitionType.enter: // card_flip_right_in
|
||||
objectAnimators = java.lang.reflect.Array.newInstance(android.animation.Animator.class, 3);
|
||||
|
||||
values = java.lang.reflect.Array.newInstance(floatType, 2);
|
||||
values[0] = 1.0;
|
||||
values[1] = 0.0;
|
||||
animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", values);
|
||||
animator.setDuration(0);
|
||||
objectAnimators[0] = animator;
|
||||
|
||||
values = java.lang.reflect.Array.newInstance(floatType, 2);
|
||||
values[0] = rotationY;
|
||||
values[1] = 0.0;
|
||||
animator = android.animation.ObjectAnimator.ofFloat(null, "rotationY", values);
|
||||
animator.setInterpolator(interpolator);
|
||||
animator.setDuration(fullDuration);
|
||||
objectAnimators[1] = animator;
|
||||
|
||||
values = java.lang.reflect.Array.newInstance(floatType, 2);
|
||||
values[0] = 0.0;
|
||||
values[1] = 1.0;
|
||||
animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", values);
|
||||
animator.setStartDelay(fullDuration / 2);
|
||||
animator.setDuration(1);
|
||||
objectAnimators[2] = animator;
|
||||
break;
|
||||
case transition.AndroidTransitionType.exit: // card_flip_right_out
|
||||
objectAnimators = java.lang.reflect.Array.newInstance(android.animation.Animator.class, 2);
|
||||
|
||||
values = java.lang.reflect.Array.newInstance(floatType, 2);
|
||||
values[0] = 0.0;
|
||||
values[1] = -rotationY;
|
||||
animator = android.animation.ObjectAnimator.ofFloat(null, "rotationY", values);
|
||||
animator.setInterpolator(interpolator);
|
||||
animator.setDuration(fullDuration);
|
||||
objectAnimators[0] = animator;
|
||||
|
||||
values = java.lang.reflect.Array.newInstance(floatType, 2);
|
||||
values[0] = 1.0;
|
||||
values[1] = 0.0;
|
||||
animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", values);
|
||||
animator.setStartDelay(fullDuration / 2);
|
||||
animator.setDuration(1);
|
||||
objectAnimators[1] = animator;
|
||||
break;
|
||||
case transition.AndroidTransitionType.popEnter: // card_flip_left_in
|
||||
objectAnimators = java.lang.reflect.Array.newInstance(android.animation.Animator.class, 3);
|
||||
|
||||
values = java.lang.reflect.Array.newInstance(floatType, 2);
|
||||
values[0] = 1.0;
|
||||
values[1] = 0.0;
|
||||
animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", values);
|
||||
animator.setDuration(0);
|
||||
objectAnimators[0] = animator;
|
||||
|
||||
values = java.lang.reflect.Array.newInstance(floatType, 2);
|
||||
values[0] = -rotationY;
|
||||
values[1] = 0.0;
|
||||
animator = android.animation.ObjectAnimator.ofFloat(null, "rotationY", values);
|
||||
animator.setInterpolator(interpolator);
|
||||
animator.setDuration(fullDuration);
|
||||
objectAnimators[1] = animator;
|
||||
|
||||
values = java.lang.reflect.Array.newInstance(floatType, 2);
|
||||
values[0] = 0.0;
|
||||
values[1] = 1.0;
|
||||
animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", values);
|
||||
animator.setStartDelay(fullDuration / 2);
|
||||
animator.setDuration(1);
|
||||
objectAnimators[2] = animator;
|
||||
break;
|
||||
case transition.AndroidTransitionType.popExit: // card_flip_left_out
|
||||
objectAnimators = java.lang.reflect.Array.newInstance(android.animation.Animator.class, 2);
|
||||
|
||||
values = java.lang.reflect.Array.newInstance(floatType, 2);
|
||||
values[0] = 0.0;
|
||||
values[1] = rotationY;
|
||||
animator = android.animation.ObjectAnimator.ofFloat(null, "rotationY", values);
|
||||
animator.setInterpolator(interpolator);
|
||||
animator.setDuration(fullDuration);
|
||||
objectAnimators[0] = animator;
|
||||
|
||||
values = java.lang.reflect.Array.newInstance(floatType, 2);
|
||||
values[0] = 1.0;
|
||||
values[1] = 0.0;
|
||||
animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", values);
|
||||
animator.setStartDelay(fullDuration / 2);
|
||||
animator.setDuration(1);
|
||||
objectAnimators[1] = animator;
|
||||
break;
|
||||
}
|
||||
|
||||
animatorSet.playTogether(objectAnimators);
|
||||
return animatorSet;
|
||||
}
|
||||
}
|
||||
2
ui/transition/package.json
Normal file
2
ui/transition/package.json
Normal file
@@ -0,0 +1,2 @@
|
||||
{ "name" : "transition",
|
||||
"main" : "transition.js" }
|
||||
116
ui/transition/slide-transition.android.ts
Normal file
116
ui/transition/slide-transition.android.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
import transition = require("ui/transition");
|
||||
import platform = require("platform");
|
||||
|
||||
var floatType = java.lang.Float.class.getField("TYPE").get(null);
|
||||
var screenWidth = platform.screen.mainScreen.widthPixels;
|
||||
var screenHeight = platform.screen.mainScreen.heightPixels;
|
||||
|
||||
export class SlideTransition extends transition.Transition {
|
||||
private _direction: string;
|
||||
|
||||
constructor(direction: string, duration: number, curve: any) {
|
||||
super(duration, curve);
|
||||
this._direction = direction;
|
||||
}
|
||||
|
||||
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
||||
var translationValues = java.lang.reflect.Array.newInstance(floatType, 2);
|
||||
switch (this._direction) {
|
||||
case "left":
|
||||
switch (transitionType) {
|
||||
case transition.AndroidTransitionType.enter:
|
||||
translationValues[0] = screenWidth;
|
||||
translationValues[1] = 0;
|
||||
break;
|
||||
case transition.AndroidTransitionType.exit:
|
||||
translationValues[0] = 0;
|
||||
translationValues[1] = -screenWidth;
|
||||
break;
|
||||
case transition.AndroidTransitionType.popEnter:
|
||||
translationValues[0] = -screenWidth;
|
||||
translationValues[1] = 0;
|
||||
break;
|
||||
case transition.AndroidTransitionType.popExit:
|
||||
translationValues[0] = 0;
|
||||
translationValues[1] = screenWidth;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "right":
|
||||
switch (transitionType) {
|
||||
case transition.AndroidTransitionType.enter:
|
||||
translationValues[0] = -screenWidth;
|
||||
translationValues[1] = 0;
|
||||
break;
|
||||
case transition.AndroidTransitionType.exit:
|
||||
translationValues[0] = 0;
|
||||
translationValues[1] = screenWidth;
|
||||
break;
|
||||
case transition.AndroidTransitionType.popEnter:
|
||||
translationValues[0] = screenWidth;
|
||||
translationValues[1] = 0;
|
||||
break;
|
||||
case transition.AndroidTransitionType.popExit:
|
||||
translationValues[0] = 0;
|
||||
translationValues[1] = -screenWidth;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "top":
|
||||
switch (transitionType) {
|
||||
case transition.AndroidTransitionType.enter:
|
||||
translationValues[0] = screenHeight;
|
||||
translationValues[1] = 0;
|
||||
break;
|
||||
case transition.AndroidTransitionType.exit:
|
||||
translationValues[0] = 0;
|
||||
translationValues[1] = -screenHeight;
|
||||
break;
|
||||
case transition.AndroidTransitionType.popEnter:
|
||||
translationValues[0] = -screenHeight;
|
||||
translationValues[1] = 0;
|
||||
break;
|
||||
case transition.AndroidTransitionType.popExit:
|
||||
translationValues[0] = 0;
|
||||
translationValues[1] = screenHeight;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "bottom":
|
||||
switch (transitionType) {
|
||||
case transition.AndroidTransitionType.enter:
|
||||
translationValues[0] = -screenHeight;
|
||||
translationValues[1] = 0;
|
||||
break;
|
||||
case transition.AndroidTransitionType.exit:
|
||||
translationValues[0] = 0;
|
||||
translationValues[1] = screenHeight;
|
||||
break;
|
||||
case transition.AndroidTransitionType.popEnter:
|
||||
translationValues[0] = screenHeight;
|
||||
translationValues[1] = 0;
|
||||
break;
|
||||
case transition.AndroidTransitionType.popExit:
|
||||
translationValues[0] = 0;
|
||||
translationValues[1] = -screenHeight;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
var prop;
|
||||
if (this._direction === "left" || this._direction === "right") {
|
||||
prop = "translationX";
|
||||
}
|
||||
else {
|
||||
prop = "translationY";
|
||||
}
|
||||
|
||||
var animator = android.animation.ObjectAnimator.ofFloat(null, prop, translationValues);
|
||||
var duration = this.getDuration();
|
||||
if (duration !== undefined) {
|
||||
animator.setDuration(duration);
|
||||
}
|
||||
animator.setInterpolator(this.getCurve());
|
||||
return animator;
|
||||
}
|
||||
}
|
||||
64
ui/transition/slide-transition.ios.ts
Normal file
64
ui/transition/slide-transition.ios.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import transition = require("ui/transition");
|
||||
import platform = require("platform");
|
||||
|
||||
var screenWidth = platform.screen.mainScreen.widthDIPs;
|
||||
var screenHeight = platform.screen.mainScreen.heightDIPs;
|
||||
var leftEdge = CGAffineTransformMakeTranslation(-screenWidth, 0);
|
||||
var rightEdge = CGAffineTransformMakeTranslation(screenWidth, 0);
|
||||
var topEdge = CGAffineTransformMakeTranslation(0, -screenHeight);
|
||||
var bottomEdge = CGAffineTransformMakeTranslation(0, screenHeight);
|
||||
|
||||
export class SlideTransition extends transition.Transition {
|
||||
private _direction: string;
|
||||
|
||||
constructor(direction: string, duration: number, curve: any) {
|
||||
super(duration, curve);
|
||||
this._direction = direction;
|
||||
}
|
||||
|
||||
public animateIOSTransition(containerView: UIView, fromView: UIView, toView: UIView, operation: UINavigationControllerOperation, completion: (finished: boolean) => void): void {
|
||||
var fromViewEndTransform: CGAffineTransform;
|
||||
var toViewBeginTransform: CGAffineTransform;
|
||||
var push = (operation === UINavigationControllerOperation.UINavigationControllerOperationPush);
|
||||
|
||||
switch (this._direction) {
|
||||
case "left":
|
||||
toViewBeginTransform = push ? rightEdge : leftEdge;
|
||||
fromViewEndTransform = push ? leftEdge : rightEdge;
|
||||
break;
|
||||
case "right":
|
||||
toViewBeginTransform = push ? leftEdge : rightEdge;
|
||||
fromViewEndTransform = push ? rightEdge : leftEdge;
|
||||
break;
|
||||
case "top":
|
||||
toViewBeginTransform = push ? bottomEdge : topEdge;
|
||||
fromViewEndTransform = push ? topEdge : bottomEdge;
|
||||
break;
|
||||
case "bottom":
|
||||
toViewBeginTransform = push ? topEdge : bottomEdge;
|
||||
fromViewEndTransform = push ? bottomEdge : topEdge;
|
||||
break;
|
||||
}
|
||||
|
||||
var originalToViewTransform = toView.transform;
|
||||
toView.transform = toViewBeginTransform;
|
||||
//fromView.transform = CGAffineTransformIdentity;
|
||||
|
||||
switch (operation) {
|
||||
case UINavigationControllerOperation.UINavigationControllerOperationPush:
|
||||
containerView.insertSubviewAboveSubview(toView, fromView);
|
||||
break;
|
||||
case UINavigationControllerOperation.UINavigationControllerOperationPop:
|
||||
containerView.insertSubviewBelowSubview(toView, fromView);
|
||||
break;
|
||||
}
|
||||
|
||||
var duration = this.getDuration();
|
||||
var curve = this.getCurve();
|
||||
UIView.animateWithDurationAnimationsCompletion(duration, () => {
|
||||
UIView.setAnimationCurve(curve);
|
||||
toView.transform = originalToViewTransform;
|
||||
fromView.transform = fromViewEndTransform;
|
||||
}, completion);
|
||||
}
|
||||
}
|
||||
395
ui/transition/transition.android.ts
Normal file
395
ui/transition/transition.android.ts
Normal file
@@ -0,0 +1,395 @@
|
||||
import definition = require("ui/transition");
|
||||
import platform = require("platform");
|
||||
import frameModule = require("ui/frame");
|
||||
import pageModule = require("ui/page");
|
||||
import * as animationModule from "ui/animation";
|
||||
import types = require("utils/types");
|
||||
import trace = require("trace");
|
||||
|
||||
var _sdkVersion = parseInt(platform.device.sdkVersion);
|
||||
var _defaultInterpolator = new android.view.animation.AccelerateDecelerateInterpolator();
|
||||
|
||||
var ENTER_POPEXIT_TRANSITION = "ENTER_POPEXIT_TRANSITION";
|
||||
var EXIT_POPENTER_TRANSITION = "EXIT_POPENTER_TRANSITION";
|
||||
var COMPLETE_PAGE_ADDITION_WHEN_TRANSITION_ENDS = "COMPLETE_PAGE_ADDITION_WHEN_TRANSITION_ENDS";
|
||||
var COMPLETE_PAGE_REMOVAL_WHEN_TRANSITION_ENDS = "COMPLETE_PAGE_REMOVAL_WHEN_TRANSITION_ENDS";
|
||||
var enterFakeResourceId = -10;
|
||||
var exitFakeResourceId = -20;
|
||||
var popEnterFakeResourceId = -30;
|
||||
var popExitFakeResourceId = -40;
|
||||
|
||||
export module AndroidTransitionType {
|
||||
export var enter: string = "enter";
|
||||
export var exit: string = "exit";
|
||||
export var popEnter: string = "popEnter";
|
||||
export var popExit: string = "popExit";
|
||||
}
|
||||
|
||||
export function _clearForwardTransitions(fragment: any): void {
|
||||
if (fragment[EXIT_POPENTER_TRANSITION]) {
|
||||
trace.write(`Cleared EXIT_POPENTER_TRANSITION ${fragment[EXIT_POPENTER_TRANSITION]} for ${fragment.getTag()}`, trace.categories.Transition);
|
||||
fragment[EXIT_POPENTER_TRANSITION] = undefined;
|
||||
}
|
||||
|
||||
if (_sdkVersion >= 21) {
|
||||
var exitTransition = (<any>fragment).getExitTransition();
|
||||
if (exitTransition) {
|
||||
trace.write(`Cleared Exit ${exitTransition.getClass().getSimpleName()} transition for ${fragment.getTag()}`, trace.categories.Transition);
|
||||
(<any>fragment).setExitTransition(null);//exit
|
||||
}
|
||||
var reenterTransition = (<any>fragment).getReenterTransition();
|
||||
if (reenterTransition) {
|
||||
trace.write(`Cleared Pop Enter ${reenterTransition.getClass().getSimpleName()} transition for ${fragment.getTag()}`, trace.categories.Transition);
|
||||
(<any>fragment).setReenterTransition(null);//popEnter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function _setAndroidFragmentTransitions(navigationTransition: frameModule.NavigationTransition, currentFragment: any, newFragment: any, fragmentTransaction: any): void {
|
||||
var name;
|
||||
if (types.isString(navigationTransition.transition)) {
|
||||
name = navigationTransition.transition.toLowerCase();
|
||||
}
|
||||
|
||||
var useLollipopTransition = name && (name.indexOf("slide") === 0 || name === "fade" || name === "explode") && _sdkVersion >= 21;
|
||||
if (useLollipopTransition) {
|
||||
// setEnterTransition: Enter
|
||||
// setExitTransition: Exit
|
||||
// setReenterTransition: Pop Enter, same as Exit if not specified
|
||||
// setReturnTransition: Pop Exit, same as Enter if not specified
|
||||
|
||||
newFragment.setAllowEnterTransitionOverlap(true);
|
||||
newFragment.setAllowReturnTransitionOverlap(true);
|
||||
if (currentFragment) {
|
||||
currentFragment.setAllowEnterTransitionOverlap(true);
|
||||
currentFragment.setAllowReturnTransitionOverlap(true);
|
||||
}
|
||||
|
||||
if (name.indexOf("slide") === 0) {
|
||||
var direction = name.substr("slide".length) || "left"; //Extract the direction from the string
|
||||
switch (direction) {
|
||||
case "left":
|
||||
let rightEdge = new (<any>android).transition.Slide((<any>android).view.Gravity.RIGHT);
|
||||
_setUpNativeTransition(navigationTransition, rightEdge);
|
||||
_addNativeTransitionListener(newFragment, rightEdge);
|
||||
newFragment.setEnterTransition(rightEdge);
|
||||
if (currentFragment) {
|
||||
let leftEdge = new (<any>android).transition.Slide((<any>android).view.Gravity.LEFT);
|
||||
_setUpNativeTransition(navigationTransition, leftEdge);
|
||||
_addNativeTransitionListener(currentFragment, leftEdge);
|
||||
currentFragment.setExitTransition(leftEdge);
|
||||
}
|
||||
break;
|
||||
case "right":
|
||||
let leftEdge = new (<any>android).transition.Slide((<any>android).view.Gravity.LEFT);
|
||||
_setUpNativeTransition(navigationTransition, leftEdge);
|
||||
_addNativeTransitionListener(newFragment, leftEdge);
|
||||
newFragment.setEnterTransition(leftEdge);
|
||||
if (currentFragment) {
|
||||
let rightEdge = new (<any>android).transition.Slide((<any>android).view.Gravity.RIGHT);
|
||||
_setUpNativeTransition(navigationTransition, rightEdge);
|
||||
_addNativeTransitionListener(currentFragment, rightEdge);
|
||||
currentFragment.setExitTransition(rightEdge);
|
||||
}
|
||||
break;
|
||||
case "top":
|
||||
let bottomEdge = new (<any>android).transition.Slide((<any>android).view.Gravity.BOTTOM);
|
||||
_setUpNativeTransition(navigationTransition, bottomEdge);
|
||||
_addNativeTransitionListener(newFragment, bottomEdge);
|
||||
newFragment.setEnterTransition(bottomEdge);
|
||||
if (currentFragment) {
|
||||
let topEdge = new (<any>android).transition.Slide((<any>android).view.Gravity.TOP);
|
||||
_setUpNativeTransition(navigationTransition, topEdge);
|
||||
_addNativeTransitionListener(currentFragment, topEdge);
|
||||
currentFragment.setExitTransition(topEdge);
|
||||
}
|
||||
break;
|
||||
case "bottom":
|
||||
let topEdge = new (<any>android).transition.Slide((<any>android).view.Gravity.TOP);
|
||||
_setUpNativeTransition(navigationTransition, topEdge);
|
||||
_addNativeTransitionListener(newFragment, topEdge);
|
||||
newFragment.setEnterTransition(topEdge);
|
||||
if (currentFragment) {
|
||||
let bottomEdge = new (<any>android).transition.Slide((<any>android).view.Gravity.BOTTOM);
|
||||
_setUpNativeTransition(navigationTransition, bottomEdge);
|
||||
_addNativeTransitionListener(currentFragment, bottomEdge);
|
||||
currentFragment.setExitTransition(bottomEdge);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (name === "fade") {
|
||||
let fadeEnter = new (<any>android).transition.Fade((<any>android).transition.Fade.IN);
|
||||
_setUpNativeTransition(navigationTransition, fadeEnter);
|
||||
_addNativeTransitionListener(newFragment, fadeEnter);
|
||||
newFragment.setEnterTransition(fadeEnter);
|
||||
let fadeReturn = new (<any>android).transition.Fade((<any>android).transition.Fade.OUT);
|
||||
_setUpNativeTransition(navigationTransition, fadeReturn);
|
||||
_addNativeTransitionListener(newFragment, fadeReturn);
|
||||
newFragment.setReturnTransition(fadeReturn);
|
||||
if (currentFragment) {
|
||||
let fadeExit = new (<any>android).transition.Fade((<any>android).transition.Fade.OUT);
|
||||
_setUpNativeTransition(navigationTransition, fadeExit);
|
||||
_addNativeTransitionListener(currentFragment, fadeExit);
|
||||
currentFragment.setExitTransition(fadeExit);
|
||||
let fadeReenter = new (<any>android).transition.Fade((<any>android).transition.Fade.IN);
|
||||
_setUpNativeTransition(navigationTransition, fadeReenter);
|
||||
_addNativeTransitionListener(currentFragment, fadeReenter);
|
||||
currentFragment.setReenterTransition(fadeReenter);
|
||||
}
|
||||
}
|
||||
else if (name === "explode") {
|
||||
let explodeEnter = new (<any>android).transition.Explode();
|
||||
_setUpNativeTransition(navigationTransition, explodeEnter);
|
||||
_addNativeTransitionListener(newFragment, explodeEnter);
|
||||
newFragment.setEnterTransition(explodeEnter);
|
||||
if (currentFragment) {
|
||||
let explodeExit = new (<any>android).transition.Explode();
|
||||
_setUpNativeTransition(navigationTransition, explodeExit);
|
||||
_addNativeTransitionListener(currentFragment, explodeExit);
|
||||
currentFragment.setExitTransition(explodeExit);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var transition: Transition;
|
||||
if (name) {
|
||||
if (name.indexOf("slide") === 0) {
|
||||
var slideTransitionModule = require("./slide-transition");
|
||||
var direction = name.substr("slide".length) || "left"; //Extract the direction from the string
|
||||
transition = new slideTransitionModule.SlideTransition(direction, navigationTransition.duration, navigationTransition.curve);
|
||||
}
|
||||
else if (name === "fade") {
|
||||
var fadeTransitionModule = require("./fade-transition");
|
||||
transition = new fadeTransitionModule.FadeTransition(navigationTransition.duration, navigationTransition.curve);
|
||||
}
|
||||
else if (name.indexOf("flip") === 0) {
|
||||
var flipTransitionModule = require("./flip-transition");
|
||||
var direction = name.substr("flip".length) || "right"; //Extract the direction from the string
|
||||
transition = new flipTransitionModule.FlipTransition(direction, navigationTransition.duration, navigationTransition.curve);
|
||||
}
|
||||
}
|
||||
else {
|
||||
transition = navigationTransition.transition; // User-defined instance of Transition
|
||||
}
|
||||
|
||||
if (transition) {
|
||||
newFragment[ENTER_POPEXIT_TRANSITION] = transition;
|
||||
if (currentFragment) {
|
||||
currentFragment[EXIT_POPENTER_TRANSITION] = transition;
|
||||
}
|
||||
fragmentTransaction.setCustomAnimations(enterFakeResourceId, exitFakeResourceId, popEnterFakeResourceId, popExitFakeResourceId);
|
||||
}
|
||||
}
|
||||
|
||||
function _setUpNativeTransition(navigationTransition: frameModule.NavigationTransition, nativeTransition: any/*android.transition.Transition*/) {
|
||||
if (navigationTransition.duration) {
|
||||
nativeTransition.setDuration(navigationTransition.duration);
|
||||
}
|
||||
|
||||
if (navigationTransition.curve) {
|
||||
var animation: typeof animationModule = require("ui/animation");
|
||||
var interpolator = animation._resolveAnimationCurve(navigationTransition.curve);
|
||||
nativeTransition.setInterpolator(interpolator);
|
||||
}
|
||||
else {
|
||||
nativeTransition.setInterpolator(_defaultInterpolator);
|
||||
}
|
||||
}
|
||||
|
||||
export function _onFragmentShown(fragment: android.app.Fragment, isBack: boolean): void {
|
||||
var transitionType = isBack ? "Pop Enter" : "Enter";
|
||||
var relevantTransition = isBack ? EXIT_POPENTER_TRANSITION : ENTER_POPEXIT_TRANSITION;
|
||||
if (fragment[relevantTransition]) {
|
||||
trace.write(`${fragment.getTag()} has been shown when going ${isBack ? "back" : "forward"}, but there is ${transitionType} ${fragment[relevantTransition]}. Will complete page addition when transition ends.`, trace.categories.Transition);
|
||||
fragment[COMPLETE_PAGE_ADDITION_WHEN_TRANSITION_ENDS] = { isBack: isBack };
|
||||
}
|
||||
else if (_sdkVersion >= 21) {
|
||||
var nativeTransition = isBack ? (<any>fragment).getReenterTransition() : (<any>fragment).getEnterTransition();
|
||||
if (nativeTransition) {
|
||||
trace.write(`${fragment.getTag() } has been shown when going ${isBack ? "back" : "forward"}, but there is ${transitionType} ${nativeTransition.getClass().getSimpleName()} transition. Will complete page addition when transition ends.`, trace.categories.Transition);
|
||||
fragment[COMPLETE_PAGE_ADDITION_WHEN_TRANSITION_ENDS] = { isBack: isBack };
|
||||
}
|
||||
}
|
||||
|
||||
if (fragment[COMPLETE_PAGE_ADDITION_WHEN_TRANSITION_ENDS] === undefined) {
|
||||
_completePageAddition(fragment, isBack, true);
|
||||
}
|
||||
}
|
||||
|
||||
export function _onFragmentHidden(fragment: android.app.Fragment, isBack: boolean) {
|
||||
var transitionType = isBack ? "Pop Exit" : "Exit";
|
||||
var relevantTransition = isBack ? ENTER_POPEXIT_TRANSITION : EXIT_POPENTER_TRANSITION;
|
||||
if (fragment[relevantTransition]) {
|
||||
trace.write(`${fragment.getTag()} has been hidden when going ${isBack ? "back" : "forward"}, but there is ${transitionType} ${fragment[relevantTransition]}. Will complete page removal when transition ends.`, trace.categories.Transition);
|
||||
fragment[COMPLETE_PAGE_REMOVAL_WHEN_TRANSITION_ENDS] = true;
|
||||
}
|
||||
else if (_sdkVersion >= 21) {
|
||||
var nativeTransition = isBack ? (<any>fragment).getReturnTransition() : (<any>fragment).getExitTransition();
|
||||
if (nativeTransition) {
|
||||
trace.write(`${fragment.getTag()} has been hidden when going ${isBack ? "back" : "forward"}, but there is ${transitionType} ${nativeTransition.getClass().getSimpleName()} transition. Will complete page removal when transition ends.`, trace.categories.Transition);
|
||||
fragment[COMPLETE_PAGE_REMOVAL_WHEN_TRANSITION_ENDS] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (fragment[COMPLETE_PAGE_REMOVAL_WHEN_TRANSITION_ENDS] === undefined) {
|
||||
// This might be a second call if the fragment is hidden and then destroyed.
|
||||
_completePageRemoval(fragment, true);
|
||||
}
|
||||
}
|
||||
|
||||
function _completePageAddition(fragment: android.app.Fragment, isBack: boolean, force?: boolean) {
|
||||
if (fragment[COMPLETE_PAGE_ADDITION_WHEN_TRANSITION_ENDS] || force) {
|
||||
fragment[COMPLETE_PAGE_ADDITION_WHEN_TRANSITION_ENDS] = undefined;
|
||||
var frame = (<any>fragment).frame;
|
||||
var entry: frameModule.BackstackEntry = (<any>fragment).entry;
|
||||
var page: pageModule.Page = entry.resolvedPage;
|
||||
// The original code that was once in Frame onFragmentShown
|
||||
frame._currentEntry = entry;
|
||||
page.onNavigatedTo(isBack);
|
||||
frame._processNavigationQueue(page);
|
||||
trace.write(`ADDITION of ${page} completed`, trace.categories.Transition);
|
||||
}
|
||||
}
|
||||
|
||||
function _completePageRemoval(fragment: android.app.Fragment, force?: boolean) {
|
||||
if (fragment[COMPLETE_PAGE_REMOVAL_WHEN_TRANSITION_ENDS] || force) {
|
||||
fragment[COMPLETE_PAGE_REMOVAL_WHEN_TRANSITION_ENDS] = undefined;
|
||||
var frame = (<any>fragment).frame;
|
||||
var entry: frameModule.BackstackEntry = (<any>fragment).entry;
|
||||
var page: pageModule.Page = entry.resolvedPage;
|
||||
if (page.frame) {
|
||||
frame._removeView(page);
|
||||
}
|
||||
trace.write(`REMOVAL of ${page} completed`, trace.categories.Transition);
|
||||
}
|
||||
}
|
||||
|
||||
function _addNativeTransitionListener(fragment: android.app.Fragment, nativeTransition: any/*android.transition.Transition*/) {
|
||||
var transitionListener = new (<any>android).transition.Transition.TransitionListener({
|
||||
onTransitionCancel: function (transition: any): void {
|
||||
trace.write(`CANCEL ${nativeTransition} transition for ${fragment}`, trace.categories.Transition);
|
||||
if (fragment[COMPLETE_PAGE_REMOVAL_WHEN_TRANSITION_ENDS]) {
|
||||
_completePageRemoval(fragment);
|
||||
}
|
||||
if (fragment[COMPLETE_PAGE_ADDITION_WHEN_TRANSITION_ENDS]) {
|
||||
_completePageAddition(fragment, fragment[COMPLETE_PAGE_ADDITION_WHEN_TRANSITION_ENDS].isBack);
|
||||
}
|
||||
},
|
||||
onTransitionEnd: function (transition: any): void {
|
||||
trace.write(`END ${nativeTransition} transition for ${fragment}`, trace.categories.Transition);
|
||||
if (fragment[COMPLETE_PAGE_REMOVAL_WHEN_TRANSITION_ENDS]) {
|
||||
_completePageRemoval(fragment);
|
||||
}
|
||||
if (fragment[COMPLETE_PAGE_ADDITION_WHEN_TRANSITION_ENDS]) {
|
||||
_completePageAddition(fragment, fragment[COMPLETE_PAGE_ADDITION_WHEN_TRANSITION_ENDS].isBack);
|
||||
}
|
||||
},
|
||||
onTransitionPause: function (transition: any): void {
|
||||
trace.write(`PAUSE ${nativeTransition} transition for ${fragment}`, trace.categories.Transition);
|
||||
},
|
||||
onTransitionResume: function (transition: any): void {
|
||||
trace.write(`RESUME ${nativeTransition} transition for ${fragment}`, trace.categories.Transition);
|
||||
},
|
||||
onTransitionStart: function (transition: any): void {
|
||||
trace.write(`START ${nativeTransition} transition for ${fragment}`, trace.categories.Transition);
|
||||
}
|
||||
});
|
||||
nativeTransition.addListener(transitionListener);
|
||||
}
|
||||
|
||||
export function _onFragmentCreateAnimator(fragment: android.app.Fragment, nextAnim: number): android.animation.Animator {
|
||||
var transitionType;
|
||||
switch (nextAnim) {
|
||||
case enterFakeResourceId: transitionType = AndroidTransitionType.enter; break;
|
||||
case exitFakeResourceId: transitionType = AndroidTransitionType.exit; break;
|
||||
case popEnterFakeResourceId: transitionType = AndroidTransitionType.popEnter; break;
|
||||
case popExitFakeResourceId: transitionType = AndroidTransitionType.popExit; break;
|
||||
}
|
||||
|
||||
var transition;
|
||||
switch (transitionType) {
|
||||
case AndroidTransitionType.enter:
|
||||
case AndroidTransitionType.popExit:
|
||||
transition = <Transition>fragment[ENTER_POPEXIT_TRANSITION];
|
||||
break;
|
||||
case AndroidTransitionType.exit:
|
||||
case AndroidTransitionType.popEnter:
|
||||
transition = <Transition>fragment[EXIT_POPENTER_TRANSITION];
|
||||
break;
|
||||
}
|
||||
|
||||
var animator: android.animation.Animator;
|
||||
if (transition) {
|
||||
animator = <android.animation.Animator>transition.createAndroidAnimator(transitionType);
|
||||
var transitionListener = new android.animation.Animator.AnimatorListener({
|
||||
onAnimationStart: function (animator: android.animation.Animator): void {
|
||||
trace.write(`START ${transitionType} ${transition} for ${fragment.getTag()}`, trace.categories.Transition);
|
||||
},
|
||||
onAnimationRepeat: function (animator: android.animation.Animator): void {
|
||||
trace.write(`REPEAT ${transitionType} ${transition} for ${fragment.getTag()}`, trace.categories.Transition);
|
||||
},
|
||||
onAnimationEnd: function (animator: android.animation.Animator): void {
|
||||
trace.write(`END ${transitionType} ${transition}`, trace.categories.Transition);
|
||||
if (fragment[COMPLETE_PAGE_REMOVAL_WHEN_TRANSITION_ENDS]) {
|
||||
_completePageRemoval(fragment);
|
||||
}
|
||||
if (fragment[COMPLETE_PAGE_ADDITION_WHEN_TRANSITION_ENDS]) {
|
||||
_completePageAddition(fragment, fragment[COMPLETE_PAGE_ADDITION_WHEN_TRANSITION_ENDS].isBack);
|
||||
}
|
||||
},
|
||||
onAnimationCancel: function (animator: android.animation.Animator): void {
|
||||
trace.write(`CANCEL ${transitionType} ${transition} for ${fragment.getTag()}`, trace.categories.Transition);
|
||||
if (fragment[COMPLETE_PAGE_REMOVAL_WHEN_TRANSITION_ENDS]) {
|
||||
_completePageRemoval(fragment);
|
||||
}
|
||||
if (fragment[COMPLETE_PAGE_ADDITION_WHEN_TRANSITION_ENDS]) {
|
||||
_completePageAddition(fragment, fragment[COMPLETE_PAGE_ADDITION_WHEN_TRANSITION_ENDS].isBack);
|
||||
}
|
||||
}
|
||||
});
|
||||
animator.addListener(transitionListener);
|
||||
}
|
||||
|
||||
return animator;
|
||||
}
|
||||
|
||||
var transitionId = 0;
|
||||
export class Transition implements definition.Transition {
|
||||
private _duration: number;
|
||||
private _interpolator: android.view.animation.Interpolator;
|
||||
private _id: number;
|
||||
|
||||
constructor(duration: number, curve: any) {
|
||||
this._duration = duration;
|
||||
if (curve) {
|
||||
var animation: typeof animationModule = require("ui/animation");
|
||||
this._interpolator = animation._resolveAnimationCurve(curve);
|
||||
}
|
||||
else {
|
||||
this._interpolator = _defaultInterpolator;
|
||||
}
|
||||
this._id = transitionId++;
|
||||
}
|
||||
|
||||
public getDuration(): number {
|
||||
return this._duration;
|
||||
}
|
||||
|
||||
public getCurve(): android.view.animation.Interpolator {
|
||||
return this._interpolator;
|
||||
}
|
||||
|
||||
public animateIOSTransition(containerView: any, fromView: any, toView: any, operation: any, completion: (finished: boolean) => void): void {
|
||||
throw new Error("Abstract method call");
|
||||
}
|
||||
|
||||
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
||||
throw new Error("Abstract method call");
|
||||
}
|
||||
|
||||
public toString(): string {
|
||||
return `${types.getClass(this)}@${this._id}`;
|
||||
}
|
||||
}
|
||||
29
ui/transition/transition.d.ts
vendored
Normal file
29
ui/transition/transition.d.ts
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
declare module "ui/transition" {
|
||||
import frame = require("ui/frame");
|
||||
|
||||
export module AndroidTransitionType {
|
||||
export var enter: string;
|
||||
export var exit: string;
|
||||
export var popEnter: string;
|
||||
export var popExit: string;
|
||||
}
|
||||
|
||||
export class Transition {
|
||||
constructor(duration: number, curve: any);
|
||||
public getDuration(): number;
|
||||
public getCurve(): any;
|
||||
public animateIOSTransition(containerView: any, fromView: any, toView: any, operation: any, completion: (finished: boolean) => void): void;
|
||||
public createAndroidAnimator(transitionType: string): any;
|
||||
public toString(): string;
|
||||
}
|
||||
|
||||
//@private
|
||||
export function _clearForwardTransitions(fragment: any): void;
|
||||
export function _setAndroidFragmentTransitions(navigationTransition: frame.NavigationTransition, currentFragment: any, newFragment: any, fragmentTransaction: any): void;
|
||||
export function _onFragmentCreateAnimator(fragment: any, nextAnim: number): any;
|
||||
export function _onFragmentShown(fragment: any, isBack: boolean): void;
|
||||
export function _onFragmentHidden(fragment: any, isBack: boolean): void;
|
||||
|
||||
export function _createIOSAnimatedTransitioning(navigationTransition: frame.NavigationTransition, operation: number, fromVC: any, toVC: any): any;
|
||||
//@endprivate
|
||||
}
|
||||
113
ui/transition/transition.ios.ts
Normal file
113
ui/transition/transition.ios.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
import definition = require("ui/transition");
|
||||
import frame = require("ui/frame");
|
||||
import types = require("utils/types");
|
||||
import trace = require("trace");
|
||||
|
||||
class AnimatedTransitioning extends NSObject implements UIViewControllerAnimatedTransitioning {
|
||||
public static ObjCProtocols = [UIViewControllerAnimatedTransitioning];
|
||||
|
||||
private _transition: Transition;
|
||||
private _operation: UINavigationControllerOperation;
|
||||
private _fromVC: UIViewController;
|
||||
private _toVC: UIViewController;
|
||||
private _transitionType: string;
|
||||
|
||||
public static init(transition: Transition, operation: UINavigationControllerOperation, fromVC: UIViewController, toVC: UIViewController): AnimatedTransitioning {
|
||||
var impl = <AnimatedTransitioning>AnimatedTransitioning.new();
|
||||
impl._transition = transition;
|
||||
impl._operation = operation;
|
||||
impl._fromVC = fromVC;
|
||||
impl._toVC = toVC;
|
||||
return impl;
|
||||
}
|
||||
|
||||
public animateTransition(transitionContext: any): void {
|
||||
let containerView = transitionContext.performSelector("containerView");
|
||||
var completion = (finished: boolean) => {
|
||||
transitionContext.performSelectorWithObject("completeTransition:", finished);
|
||||
}
|
||||
switch (this._operation) {
|
||||
case UINavigationControllerOperation.UINavigationControllerOperationPush: this._transitionType = "push"; break;
|
||||
case UINavigationControllerOperation.UINavigationControllerOperationPop: this._transitionType = "pop"; break;
|
||||
case UINavigationControllerOperation.UINavigationControllerOperationNone: this._transitionType = "none"; break;
|
||||
}
|
||||
trace.write(`START ${this._transition} ${this._transitionType}`, trace.categories.Transition);
|
||||
this._transition.animateIOSTransition(containerView, this._fromVC.view, this._toVC.view, this._operation, completion);
|
||||
}
|
||||
|
||||
public transitionDuration(transitionContext: UIViewControllerContextTransitioning): number {
|
||||
return this._transition.getDuration();
|
||||
}
|
||||
|
||||
public animationEnded(transitionCompleted: boolean): void {
|
||||
if (transitionCompleted) {
|
||||
trace.write(`END ${this._transition} ${this._transitionType}`, trace.categories.Transition);
|
||||
}
|
||||
else {
|
||||
trace.write(`CANCEL ${this._transition} ${this._transitionType}`, trace.categories.Transition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var transitionId = 0;
|
||||
export class Transition implements definition.Transition {
|
||||
private _duration: number;
|
||||
private _curve: UIViewAnimationCurve;
|
||||
private _id: number;
|
||||
|
||||
constructor(duration: number, curve: any) {
|
||||
this._duration = duration ? (duration / 1000) : 0.35;
|
||||
if (curve) {
|
||||
this._curve = (<any>frame)._getNativeCurve(curve);
|
||||
}
|
||||
else {
|
||||
this._curve = UIViewAnimationCurve.UIViewAnimationCurveEaseInOut;
|
||||
}
|
||||
}
|
||||
|
||||
public getDuration(): number {
|
||||
return this._duration;
|
||||
}
|
||||
|
||||
public getCurve(): UIViewAnimationCurve {
|
||||
return this._curve;
|
||||
}
|
||||
|
||||
public animateIOSTransition(containerView: UIView, fromView: UIView, toView: UIView, operation: UINavigationControllerOperation, completion: (finished: boolean) => void): void {
|
||||
throw new Error("Abstract method call");
|
||||
}
|
||||
|
||||
public createAndroidAnimator(transitionType: string): any {
|
||||
throw new Error("Abstract method call");
|
||||
}
|
||||
|
||||
public toString(): string {
|
||||
return `${types.getClass(this)}@${this._id}`;
|
||||
}
|
||||
}
|
||||
|
||||
export function _createIOSAnimatedTransitioning(navigationTransition: frame.NavigationTransition, operation: UINavigationControllerOperation, fromVC: UIViewController, toVC: UIViewController): UIViewControllerAnimatedTransitioning {
|
||||
var transition: Transition;
|
||||
|
||||
if (types.isString(navigationTransition.transition)) {
|
||||
var name = navigationTransition.transition.toLowerCase();
|
||||
if (name.indexOf("slide") === 0) {
|
||||
var slideTransitionModule = require("./slide-transition");
|
||||
var direction = name.substr("slide".length) || "left"; //Extract the direction from the string
|
||||
transition = new slideTransitionModule.SlideTransition(direction, navigationTransition.duration, navigationTransition.curve);
|
||||
}
|
||||
else if (name === "fade") {
|
||||
var fadeTransitionModule = require("./fade-transition");
|
||||
transition = new fadeTransitionModule.FadeTransition(navigationTransition.duration, navigationTransition.curve);
|
||||
}
|
||||
}
|
||||
else {
|
||||
transition = navigationTransition.transition;
|
||||
}
|
||||
|
||||
if (transition) {
|
||||
return AnimatedTransitioning.init(transition, operation, fromVC, toVC);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
1
ui/ui.d.ts
vendored
1
ui/ui.d.ts
vendored
@@ -4,6 +4,7 @@
|
||||
declare module "ui" {
|
||||
export * from "ui/action-bar";
|
||||
export * from "ui/activity-indicator";
|
||||
export * from "ui/animation";
|
||||
export * from "ui/builder";
|
||||
export * from "ui/button";
|
||||
export * from "ui/content-view";
|
||||
|
||||
58
xhr/xhr.ts
58
xhr/xhr.ts
@@ -21,7 +21,7 @@ export class XMLHttpRequest {
|
||||
private _readyState: number;
|
||||
private _status: number;
|
||||
private _response: any;
|
||||
private _responseText: Function;
|
||||
private _responseTextReader: Function;
|
||||
private _headers: any;
|
||||
private _errorFlag: boolean;
|
||||
private _responseType: string = "";
|
||||
@@ -53,7 +53,7 @@ export class XMLHttpRequest {
|
||||
this._errorFlag = true;
|
||||
|
||||
this._response = null;
|
||||
this._responseText = null;
|
||||
this._responseTextReader = null;
|
||||
this._headers = null;
|
||||
this._status = null;
|
||||
|
||||
@@ -67,7 +67,7 @@ export class XMLHttpRequest {
|
||||
public send(data?: any) {
|
||||
this._errorFlag = false;
|
||||
this._response = null;
|
||||
this._responseText = null;
|
||||
this._responseTextReader = null;
|
||||
this._headers = null;
|
||||
this._status = null;
|
||||
|
||||
@@ -83,21 +83,7 @@ export class XMLHttpRequest {
|
||||
|
||||
http.request(this._options).then(r=> {
|
||||
if (!this._errorFlag) {
|
||||
this._status = r.statusCode;
|
||||
this._response = r.content.raw;
|
||||
|
||||
this._headers = r.headers;
|
||||
this._setReadyState(this.HEADERS_RECEIVED);
|
||||
|
||||
this._setReadyState(this.LOADING);
|
||||
|
||||
if (this.responseType === XMLHttpRequestResponseType.empty ||
|
||||
this.responseType === XMLHttpRequestResponseType.text ||
|
||||
this.responseType === XMLHttpRequestResponseType.json) {
|
||||
this._responseText = r.content.toString;
|
||||
}
|
||||
|
||||
this._setReadyState(this.DONE);
|
||||
this._loadResponse(r);
|
||||
}
|
||||
|
||||
}).catch(e => {
|
||||
@@ -107,6 +93,38 @@ export class XMLHttpRequest {
|
||||
}
|
||||
}
|
||||
|
||||
private _loadResponse(r) {
|
||||
this._status = r.statusCode;
|
||||
this._response = r.content.raw;
|
||||
|
||||
this._headers = r.headers;
|
||||
this._setReadyState(this.HEADERS_RECEIVED);
|
||||
|
||||
this._setReadyState(this.LOADING);
|
||||
|
||||
this._setResponseType();
|
||||
|
||||
if (this.responseType === XMLHttpRequestResponseType.json) {
|
||||
this._responseTextReader = () => r.content.toString();
|
||||
this._response = JSON.parse(this.responseText);
|
||||
} else if (this.responseType === XMLHttpRequestResponseType.empty ||
|
||||
this.responseType === XMLHttpRequestResponseType.text) {
|
||||
this._responseTextReader = () => r.content.toString();
|
||||
}
|
||||
|
||||
this._setReadyState(this.DONE);
|
||||
}
|
||||
|
||||
private _setResponseType() {
|
||||
const contentType = this.getResponseHeader('Content-Type').toLowerCase();
|
||||
|
||||
if (contentType === 'application/json') {
|
||||
this.responseType = XMLHttpRequestResponseType.json;
|
||||
} else if (contentType === 'text/plain') {
|
||||
this.responseType = XMLHttpRequestResponseType.text;
|
||||
}
|
||||
}
|
||||
|
||||
private _listeners: Map<string, Array<Function>> = new Map<string, Array<Function>>();
|
||||
|
||||
public addEventListener(eventName: string, handler: Function) {
|
||||
@@ -211,8 +229,8 @@ export class XMLHttpRequest {
|
||||
}
|
||||
|
||||
get responseText(): string {
|
||||
if (types.isFunction(this._responseText)) {
|
||||
return this._responseText();
|
||||
if (types.isFunction(this._responseTextReader)) {
|
||||
return this._responseTextReader();
|
||||
}
|
||||
|
||||
return "";
|
||||
|
||||
Reference in New Issue
Block a user