Upgrade to ExtJS 3.3.0 - Released 10/06/2010
[extjs.git] / docs / source / History.html
1 <html>
2 <head>
3   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    
4   <title>The source code</title>
5     <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
6     <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
7 </head>
8 <body  onload="prettyPrint();">
9     <pre class="prettyprint lang-js">/*!
10  * Ext JS Library 3.3.0
11  * Copyright(c) 2006-2010 Ext JS, Inc.
12  * licensing@extjs.com
13  * http://www.extjs.com/license
14  */
15 <div id="cls-Ext.History"></div>/**
16  * @class Ext.History
17  * @extends Ext.util.Observable
18  * History management component that allows you to register arbitrary tokens that signify application
19  * history state on navigation actions.  You can then handle the history {@link #change} event in order
20  * to reset your application UI to the appropriate state when the user navigates forward or backward through
21  * the browser history stack.
22  * @singleton
23  */
24 Ext.History = (function () {
25     var iframe, hiddenField;
26     var ready = false;
27     var currentToken;
28
29     function getHash() {
30         var href = location.href, i = href.indexOf("#");
31         return i >= 0 ? href.substr(i + 1) : null;
32     }
33
34     function doSave() {
35         hiddenField.value = currentToken;
36     }
37
38     function handleStateChange(token) {
39         currentToken = token;
40         Ext.History.fireEvent('change', token);
41     }
42
43     function updateIFrame (token) {
44         var html = ['<html><body><div id="state">',Ext.util.Format.htmlEncode(token),'</div></body></html>'].join('');
45         try {
46             var doc = iframe.contentWindow.document;
47             doc.open();
48             doc.write(html);
49             doc.close();
50             return true;
51         } catch (e) {
52             return false;
53         }
54     }
55
56     function checkIFrame() {
57         if (!iframe.contentWindow || !iframe.contentWindow.document) {
58             setTimeout(checkIFrame, 10);
59             return;
60         }
61
62         var doc = iframe.contentWindow.document;
63         var elem = doc.getElementById("state");
64         var token = elem ? elem.innerText : null;
65
66         var hash = getHash();
67
68         setInterval(function () {
69
70             doc = iframe.contentWindow.document;
71             elem = doc.getElementById("state");
72
73             var newtoken = elem ? elem.innerText : null;
74
75             var newHash = getHash();
76
77             if (newtoken !== token) {
78                 token = newtoken;
79                 handleStateChange(token);
80                 top.location.hash = token;
81                 hash = token;
82                 doSave();
83             } else if (newHash !== hash) {
84                 hash = newHash;
85                 updateIFrame(newHash);
86             }
87
88         }, 50);
89
90         ready = true;
91
92         Ext.History.fireEvent('ready', Ext.History);
93     }
94
95     function startUp() {
96         currentToken = hiddenField.value ? hiddenField.value : getHash();
97
98         if (Ext.isIE) {
99             checkIFrame();
100         } else {
101             var hash = getHash();
102             setInterval(function () {
103                 var newHash = getHash();
104                 if (newHash !== hash) {
105                     hash = newHash;
106                     handleStateChange(hash);
107                     doSave();
108                 }
109             }, 50);
110             ready = true;
111             Ext.History.fireEvent('ready', Ext.History);
112         }
113     }
114
115     return {
116         <div id="prop-Ext.History-fieldId"></div>/**
117          * The id of the hidden field required for storing the current history token.
118          * @type String
119          * @property
120          */
121         fieldId: 'x-history-field',
122         <div id="prop-Ext.History-iframeId"></div>/**
123          * The id of the iframe required by IE to manage the history stack.
124          * @type String
125          * @property
126          */
127         iframeId: 'x-history-frame',
128
129         events:{},
130
131         <div id="method-Ext.History-init"></div>/**
132          * Initialize the global History instance.
133          * @param {Boolean} onReady (optional) A callback function that will be called once the history
134          * component is fully initialized.
135          * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the callback is executed. Defaults to the browser window.
136          */
137         init: function (onReady, scope) {
138             if(ready) {
139                 Ext.callback(onReady, scope, [this]);
140                 return;
141             }
142             if(!Ext.isReady){
143                 Ext.onReady(function(){
144                     Ext.History.init(onReady, scope);
145                 });
146                 return;
147             }
148             hiddenField = Ext.getDom(Ext.History.fieldId);
149             if (Ext.isIE) {
150                 iframe = Ext.getDom(Ext.History.iframeId);
151             }
152             this.addEvents(
153                 <div id="event-Ext.History-ready"></div>/**
154                  * @event ready
155                  * Fires when the Ext.History singleton has been initialized and is ready for use.
156                  * @param {Ext.History} The Ext.History singleton.
157                  */
158                 'ready',
159                 <div id="event-Ext.History-change"></div>/**
160                  * @event change
161                  * Fires when navigation back or forwards within the local page's history occurs.
162                  * @param {String} token An identifier associated with the page state at that point in its history.
163                  */
164                 'change'
165             );
166             if(onReady){
167                 this.on('ready', onReady, scope, {single:true});
168             }
169             startUp();
170         },
171
172         <div id="method-Ext.History-add"></div>/**
173          * Add a new token to the history stack. This can be any arbitrary value, although it would
174          * commonly be the concatenation of a component id and another id marking the specifc history
175          * state of that component.  Example usage:
176          * <pre><code>
177 // Handle tab changes on a TabPanel
178 tabPanel.on('tabchange', function(tabPanel, tab){
179     Ext.History.add(tabPanel.id + ':' + tab.id);
180 });
181 </code></pre>
182          * @param {String} token The value that defines a particular application-specific history state
183          * @param {Boolean} preventDuplicates When true, if the passed token matches the current token
184          * it will not save a new history step. Set to false if the same state can be saved more than once
185          * at the same history stack location (defaults to true).
186          */
187         add: function (token, preventDup) {
188             if(preventDup !== false){
189                 if(this.getToken() == token){
190                     return true;
191                 }
192             }
193             if (Ext.isIE) {
194                 return updateIFrame(token);
195             } else {
196                 top.location.hash = token;
197                 return true;
198             }
199         },
200
201         <div id="method-Ext.History-back"></div>/**
202          * Programmatically steps back one step in browser history (equivalent to the user pressing the Back button).
203          */
204         back: function(){
205             history.go(-1);
206         },
207
208         <div id="method-Ext.History-forward"></div>/**
209          * Programmatically steps forward one step in browser history (equivalent to the user pressing the Forward button).
210          */
211         forward: function(){
212             history.go(1);
213         },
214
215         <div id="method-Ext.History-getToken"></div>/**
216          * Retrieves the currently-active history token.
217          * @return {String} The token
218          */
219         getToken: function() {
220             return ready ? currentToken : getHash();
221         }
222     };
223 })();
224 Ext.apply(Ext.History, new Ext.util.Observable());</pre>    
225 </body>
226 </html>