1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the Qt Components project.
9 ** $QT_BEGIN_LICENSE:BSD$
10 ** You may use this file under the terms of the BSD license as follows:
12 ** "Redistribution and use in source and binary forms, with or without
13 ** modification, are permitted provided that the following conditions are
15 ** * Redistributions of source code must retain the above copyright
16 ** notice, this list of conditions and the following disclaimer.
17 ** * Redistributions in binary form must reproduce the above copyright
18 ** notice, this list of conditions and the following disclaimer in
19 ** the documentation and/or other materials provided with the
21 ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22 ** the names of its contributors may be used to endorse or promote
23 ** products derived from this software without specific prior written
26 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
39 ****************************************************************************/
41 // Page stack. Items are page containers.
44 // Page component cache map. Key is page url, value is page component.
45 var componentCache = {};
47 // Returns the page stack depth.
49 return pageStack.length;
52 // Pushes a page on the stack.
53 function push(page, properties, replace, immediate) {
54 // page order sanity check
55 if ((!replace && page == currentPage) ||
56 (replace && pageStack.length > 1 && page == pageStack[pageStack.length - 2].page)) {
57 throw new Error("Cannot navigate so that the resulting page stack has two consecutive entries of the same page instance.");
60 // figure out if more than one page is being pushed
62 if (page instanceof Array) {
65 if (page.createObject === undefined && page.parent === undefined && typeof page != "string") {
66 properties = properties || page.properties;
71 // get the current container
72 var oldContainer = pageStack[pageStack.length - 1];
74 // pop the old container off the stack if this is a replace
75 if (oldContainer && replace) {
79 // push any extra defined pages onto the stack
82 for (i = 0; i < pages.length; i++) {
85 if (tPage.createObject === undefined && tPage.parent === undefined && typeof tPage != "string") {
86 tProps = tPage.properties;
89 pageStack.push(initPage(tPage, tProps));
93 // initialize the page
94 var container = initPage(page, properties);
96 // push the page container onto the stack
97 pageStack.push(container);
99 depth = pageStack.length;
100 currentPage = container.page;
102 // perform page transition
103 immediate = immediate || !oldContainer;
105 oldContainer.pushExit(replace, immediate);
107 container.pushEnter(replace, immediate);
110 var tools = container.page.tools || null;
112 toolBar.setTools(tools, immediate ? "set" : replace ? "replace" : "push");
115 return container.page;
118 // Initializes a page and its container.
119 function initPage(page, properties) {
120 var container = containerComponent.createObject(root);
123 if (page.createObject) {
124 // page defined as component
126 } else if (typeof page == "string") {
127 // page defined as string (a url)
128 pageComp = componentCache[page];
130 pageComp = componentCache[page] = Qt.createComponent(page);
134 if (pageComp.status == Component.Error) {
135 throw new Error("Error while loading page: " + pageComp.errorString());
137 // instantiate page from component
138 page = pageComp.createObject(container, properties || {});
141 // copy properties to the page
142 for (var prop in properties) {
143 if (properties.hasOwnProperty(prop)) {
144 page[prop] = properties[prop];
149 container.page = page;
150 container.owner = page.parent;
152 // the page has to be reparented if
153 if (page.parent != container) {
154 page.parent = container;
157 if (page.pageStack !== undefined) {
158 page.pageStack = root;
164 // Pops a page off the stack.
165 function pop(page, immediate) {
166 // make sure there are enough pages in the stack to pop
167 if (pageStack.length > 1) {
168 // pop the current container off the stack and get the next container
169 var oldContainer = pageStack.pop();
170 var container = pageStack[pageStack.length - 1];
171 if (page !== undefined) {
172 // an unwind target has been specified - pop until we find it
173 while (page != container.page && pageStack.length > 1) {
176 container = pageStack[pageStack.length - 1];
180 depth = pageStack.length;
181 currentPage = container.page;
183 // perform page transition
184 oldContainer.popExit(immediate);
185 container.popEnter(immediate);
188 var tools = container.page.tools || null;
190 toolBar.setTools(tools, immediate ? "set" : "pop");
193 return oldContainer.page;
199 // Clears the page stack.
202 while (container = pageStack.pop()) {
209 // Iterates through all pages in the stack (top to bottom) to find a page.
210 function find(func) {
211 for (var i = pageStack.length - 1; i >= 0; i--) {
212 var page = pageStack[i].page;