Fix broken navigation after clear history with transition

Resolves #1948
This commit is contained in:
Rossen Hristov
2016-04-20 14:53:10 +03:00
parent c7918c51ce
commit 56065ae601
13 changed files with 175 additions and 66 deletions

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -0,0 +1,2 @@
{ "name" : "app-resources",
"main" : "dummy.js" }

View File

@@ -1,11 +1,14 @@
import * as application from "application";
import {NavPage} from "../nav-page";
import * as trace from "trace";
import { Frame } from "ui/frame";
Frame.defaultTransition = { name: "fade" };
trace.enable();
trace.setCategories(trace.categories.concat(
trace.categories.NativeLifecycle,
trace.categories.Navigation,
//trace.categories.Animation,
trace.categories.Transition
));

View File

@@ -1,7 +1,7 @@
import definition = require("controls-page");
import {View} from "ui/core/view";
import {Page} from "ui/page";
import {topmost as topmostFrame, NavigationTransition} from "ui/frame";
import {topmost as topmostFrame, NavigationTransition, Frame} from "ui/frame";
import {Orientation, AnimationCurve} from "ui/enums";
import {StackLayout} from "ui/layouts/stack-layout";
import {Button} from "ui/button";
@@ -10,6 +10,7 @@ import {TextField} from "ui/text-field";
import {Switch} from "ui/switch";
import {Slider} from "ui/slider";
import {Color} from "color";
import {ScrollView} from "ui/scroll-view";
import * as platform from "platform";
var availableTransitions = ["default", "custom", "flip", "flipRight", "flipLeft", "slide", "slideLeft", "slideRight", "slideTop", "slideBottom", "fade"];
@@ -57,6 +58,10 @@ export class NavPage extends Page implements definition.ControlsPage {
});
that.on(Page.navigatedToEvent, (args) => {
console.log(`${args.object}.navigatedToEvent`);
(<any>topmostFrame())._printFrameBackStack();
if (topmostFrame().android) {
(<any>topmostFrame())._printNativeBackStack();
}
});
this.id = "" + context.index;
@@ -122,6 +127,14 @@ export class NavPage extends Page implements definition.ControlsPage {
animatedSwitch.checked = context.animated;
optionsLayout.addChild(animatedSwitch);
var globalTransitionButton = new Button();
globalTransitionButton.text = "global: " + (Frame.defaultTransition ? Frame.defaultTransition.name : "none");
globalTransitionButton.on("tap", (args) => {
Frame.defaultTransition = Frame.defaultTransition ? null : { name: "fade" };
(<any>args.object).text = "global: " + (Frame.defaultTransition ? Frame.defaultTransition.name : "none");
});
optionsLayout.addChild(globalTransitionButton);
var transitionButton = new Button();
transitionButton.text = availableTransitions[context.transition];
transitionButton.on("tap", () => {
@@ -202,6 +215,8 @@ export class NavPage extends Page implements definition.ControlsPage {
});
stackLayout.addChild(forwardButton);
this.content = stackLayout;
var scrollView = new ScrollView();
scrollView.content = stackLayout;
this.content = scrollView;
}
}

View File

@@ -1,6 +1,6 @@
import * as TKUnit from "../TKUnit";
import {Page} from "ui/page";
import {topmost as topmostFrame} from "ui/frame";
import {topmost as topmostFrame, NavigationTransition} from "ui/frame";
import {Color} from "color";
// Creates a random colorful page full of meaningless stuff.
@@ -10,32 +10,41 @@ var pageFactory = function(): Page {
return page;
};
export var test_backstackVisible = function () {
var mainTestPage = topmostFrame().currentPage;
topmostFrame().navigate({ create: pageFactory });
TKUnit.waitUntilReady(() => { return topmostFrame().currentPage !== mainTestPage; });
function _test_backstackVisible(transition?: NavigationTransition) {
let topmost = topmostFrame();
let mainTestPage = topmost.currentPage;
topmost.navigate({ create: pageFactory, transition: transition });
TKUnit.waitUntilReady(() => { return topmost.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; });
let page0 = topmost.currentPage;
topmost.navigate({ create: pageFactory, backstackVisible: false, transition: transition });
TKUnit.waitUntilReady(() => { return topmost.currentPage !== page0; });
var page1 = topmostFrame().currentPage;
topmostFrame().navigate({ create: pageFactory });
TKUnit.waitUntilReady(() => { return topmostFrame().currentPage !== page1; });
let page1 = topmost.currentPage;
topmost.navigate({ create: pageFactory, transition: transition });
TKUnit.waitUntilReady(() => { return topmost.currentPage !== page1; });
var page2 = topmostFrame().currentPage;
topmostFrame().goBack();
TKUnit.waitUntilReady(() => { return topmostFrame().currentPage !== page2; });
let page2 = topmost.currentPage;
topmost.goBack();
TKUnit.waitUntilReady(() => { return topmost.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.");
TKUnit.assert(topmost.currentPage === page0, "Page 1 should be skipped when going back.");
topmostFrame().goBack();
TKUnit.waitUntilReady(() => { return topmostFrame().currentPage === mainTestPage; });
topmost.goBack();
TKUnit.waitUntilReady(() => { return topmost.currentPage === mainTestPage; });
}
export var test_backToEntry = function () {
export var test_backstackVisible = function () {
_test_backstackVisible();
}
export var test_backstackVisible_WithTransition = function () {
_test_backstackVisible({name: "fade"});
}
function _test_backToEntry(transition?: NavigationTransition) {
let page = (tag) => () => {
var p = new Page();
p["tag"] = tag;
@@ -44,7 +53,7 @@ export var test_backToEntry = function () {
let topmost = topmostFrame();
let wait = tag => TKUnit.waitUntilReady(() => topmost.currentPage["tag"] === tag, 1);
let navigate = tag => {
topmost.navigate({ create: page(tag) });
topmost.navigate({ create: page(tag), transition: transition });
wait(tag)
}
let back = pages => {
@@ -75,42 +84,93 @@ export var test_backToEntry = function () {
back(1);
}
// Clearing the history messes up the tests app.
export var test_ClearHistory = function () {
var mainTestPage = topmostFrame().currentPage;
var mainPageFactory = function (): Page {
export var test_backToEntry = function () {
_test_backToEntry();
}
export var test_backToEntry_WithTransition = function () {
_test_backToEntry({name: "flip"});
}
function _test_ClearHistory(transition?: NavigationTransition) {
let topmost = topmostFrame();
let mainTestPage = topmost.currentPage;
let mainPageFactory = function (): Page {
return mainTestPage;
};
var currentPage: Page;
currentPage = topmostFrame().currentPage;
topmostFrame().navigate({ create: pageFactory, clearHistory: true });
TKUnit.waitUntilReady(() => { return topmostFrame().currentPage !== currentPage; });
currentPage = topmost.currentPage;
topmost.navigate({ create: pageFactory, clearHistory: true, transition: transition});
TKUnit.waitUntilReady(() => { return topmost.currentPage !== currentPage; });
currentPage = topmostFrame().currentPage;
topmostFrame().navigate({ create: pageFactory });
TKUnit.waitUntilReady(() => { return topmostFrame().currentPage !== currentPage; });
currentPage = topmost.currentPage;
topmost.navigate({ create: pageFactory, transition: transition });
TKUnit.waitUntilReady(() => { return topmost.currentPage !== currentPage; });
currentPage = topmostFrame().currentPage;
topmostFrame().navigate({ create: pageFactory });
TKUnit.waitUntilReady(() => { return topmostFrame().currentPage !== currentPage; });
currentPage = topmost.currentPage;
topmost.navigate({ create: pageFactory, transition: transition });
TKUnit.waitUntilReady(() => { return topmost.currentPage !== currentPage; });
currentPage = topmostFrame().currentPage;
topmostFrame().navigate({ create: pageFactory });
TKUnit.waitUntilReady(() => { return topmostFrame().currentPage !== currentPage; });
currentPage = topmost.currentPage;
topmost.navigate({ create: pageFactory, transition: transition });
TKUnit.waitUntilReady(() => { return topmost.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.");
TKUnit.assert(topmost.canGoBack(), "Frame should be able to go back.");
TKUnit.assert(topmost.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; });
currentPage = topmost.currentPage;
topmost.navigate({ create: pageFactory, clearHistory: true, transition: transition });
TKUnit.waitUntilReady(() => { return topmost.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.");
TKUnit.assert(!topmost.canGoBack(), "Frame should NOT be able to go back.");
TKUnit.assert(topmost.backStack.length === 0, "Back stack should have 0 entries.");
topmostFrame().navigate({ create: mainPageFactory });
TKUnit.waitUntilReady(() => { return topmostFrame().currentPage === mainTestPage; });
topmost.navigate({ create: mainPageFactory, transition: transition });
TKUnit.waitUntilReady(() => { return topmost.currentPage === mainTestPage; });
}
// Clearing the history messes up the tests app.
export var test_ClearHistory = function () {
_test_ClearHistory();
}
export var test_ClearHistory_WithTransition = function () {
_test_ClearHistory({ name: "slide" });
}
// Test case for https://github.com/NativeScript/NativeScript/issues/1948
export var test_ClearHistoryWithTransitionDoesNotBreakNavigation = function () {
let topmost = topmostFrame();
let mainTestPage = topmost.currentPage;
let mainPageFactory = function (): Page {
return mainTestPage;
};
// Go to details-page
topmost.navigate({ create: pageFactory, clearHistory: false });
TKUnit.waitUntilReady(() => { return topmost.currentPage !== mainTestPage; });
// Go back to main-page with clearHistory
var detailsPage: Page;
detailsPage = topmost.currentPage;
topmost.transition = { name: "fade" };
topmost.navigate({ create: mainPageFactory, clearHistory: true });
TKUnit.waitUntilReady(() => { return topmost.currentPage === mainTestPage; });
// Go to details-page AGAIN
topmost.navigate({ create: pageFactory, clearHistory: false });
TKUnit.waitUntilReady(() => { return topmost.currentPage !== mainTestPage; });
// Go back to main-page with clearHistory
detailsPage = topmost.currentPage;
topmost.transition = { name: "fade" };
topmost.navigate({ create: mainPageFactory, clearHistory: true });
TKUnit.waitUntilReady(() => { return topmost.currentPage === mainTestPage; });
// Clean up
topmost.transition = undefined;
}