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