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