~ahasenack/lazr-js/lazr-js-11.03-packaging

« back to all changes in this revision

Viewing changes to src-js/lazrjs/yui/history-deprecated/history-deprecated-debug.js

  • Committer: Sidnei da Silva
  • Date: 2010-09-18 14:54:13 UTC
  • mfrom: (166.11.12 toolchain)
  • Revision ID: sidnei.da.silva@canonical.com-20100918145413-8scojue3rodcm0f4
- Merge from lazr-js trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
 
3
Code licensed under the BSD License:
 
4
http://developer.yahoo.com/yui/license.html
 
5
version: 3.2.0
 
6
build: 2676
 
7
*/
 
8
YUI.add('history-deprecated', function(Y) {
 
9
 
 
10
/*global YUI */
 
11
 
 
12
/**
 
13
 * <strong>Deprecated since 3.2.0.</strong> The Browser History Utility provides
 
14
 * the ability to use the back/forward navigation buttons in a DHTML
 
15
 * application. It also allows a DHTML application to be bookmarked in a
 
16
 * specific state.
 
17
 *
 
18
 * This utility requires the following static markup:
 
19
 *
 
20
 * &lt;iframe id="yui-history-iframe" src="path-to-real-asset-in-same-domain"&gt;&lt;/iframe&gt;
 
21
 * &lt;input id="yui-history-field" type="hidden"&gt;
 
22
 *
 
23
 * @module history-deprecated
 
24
 * @deprecated Please use the new "history" module instead.
 
25
 */
 
26
 
 
27
/**
 
28
 * This class represents an instance of the browser history utility.
 
29
 * @class History
 
30
 * @constructor
 
31
 * @deprecated Please use the new "history" module instead.
 
32
 */
 
33
 
 
34
        // Shortcuts, etc.
 
35
    var win = Y.config.win,
 
36
        doc = Y.config.doc,
 
37
 
 
38
        encode = encodeURIComponent,
 
39
        decode = decodeURIComponent,
 
40
 
 
41
        H, G,
 
42
 
 
43
        // YUI Compressor helper...
 
44
        E_MISSING_OR_INVALID_ARG = 'Missing or invalid argument',
 
45
 
 
46
        // Regular expression used to parse query strings and such.
 
47
        REGEXP = /([^=&]+)=([^&]*)/g,
 
48
 
 
49
        // A few private variables...
 
50
        _useIFrame = false,
 
51
        _getHash,
 
52
 
 
53
        /**
 
54
         * @event history:ready
 
55
         * @description Fires when the browser history utility is ready
 
56
         * @type Event.Custom
 
57
         */
 
58
        EV_HISTORY_READY = 'history:ready',
 
59
 
 
60
        /**
 
61
         * @event history:globalStateChange
 
62
         * @description Fires when the global state of the page has changed (that is,
 
63
         *     when the state of at least one browser history module has changed)
 
64
         * @type Event.Custom
 
65
         */
 
66
        EV_HISTORY_GLOBAL_STATE_CHANGE = 'history:globalStateChange',
 
67
 
 
68
        /**
 
69
         * @event history:moduleStateChange
 
70
         * @description Fires when the state of a history module object has changed
 
71
         * @type Event.Custom
 
72
         */
 
73
        EV_HISTORY_MODULE_STATE_CHANGE = 'history:moduleStateChange';
 
74
 
 
75
 
 
76
    G = YUI.Env.history || {
 
77
 
 
78
        // Flag used to tell whether the history utility is ready to be used.
 
79
        ready: false,
 
80
 
 
81
        // List of registered modules.
 
82
        _modules: [],
 
83
 
 
84
        // INPUT field (with type="hidden" or type="text") or TEXTAREA.
 
85
        // This field keeps the value of the initial state, current state
 
86
        // the list of all states across pages within a single browser session.
 
87
        _stateField: null,
 
88
 
 
89
        // Hidden IFrame used to store the browsing history on IE6/7.
 
90
        _historyIFrame: null
 
91
    };
 
92
 
 
93
    YUI.Env.history = G;
 
94
 
 
95
    /**
 
96
     * Returns the portion of the hash after the '#' symbol.
 
97
     * @method _getHash
 
98
     * @return {string} The hash portion of the document's location
 
99
     * @private
 
100
     */
 
101
    if (Y.UA.gecko) {
 
102
        // We branch at runtime for Gecko since window.location.hash in Gecko
 
103
        // returns a decoded string, and we want all encoding untouched.
 
104
        _getHash = function () {
 
105
            var m = /#(.*)$/.exec(win.location.href);
 
106
            return m && m[1] ? m[1] : '';
 
107
        };
 
108
    } else {
 
109
        _getHash = function () {
 
110
            return win.location.hash.substr(1);
 
111
        };
 
112
    }
 
113
 
 
114
    /**
 
115
     * Stores the initial state and current state for all registered modules
 
116
     * in the (hidden) form field specified during initialization.
 
117
     * @method _storeStates
 
118
     * @private
 
119
     */
 
120
    function _storeStates() {
 
121
        var initialStates = [], currentStates = [];
 
122
 
 
123
        Y.Object.each(G._modules, function (module, moduleId) {
 
124
            initialStates.push(moduleId + '=' + module.initialState);
 
125
            currentStates.push(moduleId + '=' + module.currentState);
 
126
        });
 
127
 
 
128
        G._stateField.set('value', initialStates.join('&') + '|' + currentStates.join('&'));
 
129
    }
 
130
 
 
131
    /**
 
132
     * Sets the new currentState attribute of all modules depending on the new fully
 
133
     * qualified state. Also notifies the modules which current state has changed.
 
134
     * @method _handleFQStateChange
 
135
     * @param {string} fqstate fully qualified state
 
136
     * @private
 
137
     */
 
138
    function _handleFQStateChange(fqstate) {
 
139
        var m, states = [], globalStateChanged = false;
 
140
 
 
141
        if (fqstate) {
 
142
 
 
143
            REGEXP.lastIndex = 0;
 
144
            while ((m = REGEXP.exec(fqstate))) {
 
145
                states[m[1]] = m[2];
 
146
            }
 
147
 
 
148
            Y.Object.each(G._modules, function (module, moduleId) {
 
149
                var currentState = states[moduleId];
 
150
 
 
151
                if (!currentState || module.currentState !== currentState) {
 
152
                    module.currentState = currentState || module.initialState;
 
153
                    module.fire(EV_HISTORY_MODULE_STATE_CHANGE, decode(module.currentState));
 
154
                    globalStateChanged = true;
 
155
                }
 
156
            });
 
157
 
 
158
        } else {
 
159
 
 
160
            Y.Object.each(G._modules, function (module, moduleId) {
 
161
                if (module.currentState !== module.initialState) {
 
162
                    module.currentState = module.initialState;
 
163
                    module.fire(EV_HISTORY_MODULE_STATE_CHANGE, decode(module.currentState));
 
164
                    globalStateChanged = true;
 
165
                }
 
166
            });
 
167
        }
 
168
 
 
169
        if (globalStateChanged) {
 
170
            H.fire(EV_HISTORY_GLOBAL_STATE_CHANGE);
 
171
        }
 
172
    }
 
173
 
 
174
    /**
 
175
     * Update the IFrame with our new state.
 
176
     * @method _updateIFrame
 
177
     * @private
 
178
     * @return {boolean} true if successful. false otherwise.
 
179
     */
 
180
    function _updateIFrame(fqstate) {
 
181
        var html, doc;
 
182
 
 
183
        html = '<html><body>' +
 
184
                   fqstate.replace(/&/g,'&amp;').
 
185
                           replace(/</g,'&lt;').
 
186
                           replace(/>/g,'&gt;').
 
187
                           replace(/"/g,'&quot;') +
 
188
               '</body></html>';
 
189
 
 
190
        try {
 
191
            doc = G._historyIFrame.get('contentWindow.document');
 
192
            // TODO: The Node API should expose these methods in the very near future...
 
193
            doc.invoke('open');
 
194
            doc.invoke('write', html, '', '', '', ''); // see bug #2447937
 
195
            doc.invoke('close');
 
196
            return true;
 
197
        } catch (e) {
 
198
            return false;
 
199
        }
 
200
    }
 
201
 
 
202
    /**
 
203
     * Periodically checks whether our internal IFrame is ready to be used
 
204
     * @method _checkIframeLoaded
 
205
     * @private
 
206
     */
 
207
    function _checkIframeLoaded() {
 
208
        var elem, fqstate, hash;
 
209
 
 
210
        if (!G._historyIFrame.get('contentWindow.document')) {
 
211
            // Check again in 10 msec...
 
212
            setTimeout(_checkIframeLoaded, 10);
 
213
            return;
 
214
        }
 
215
 
 
216
        // Periodically check whether a navigate operation has been
 
217
        // requested on the main window. This will happen when
 
218
        // History.navigate has been called or after the user
 
219
        // has hit the back/forward button.
 
220
        elem = G._historyIFrame.get('contentWindow.document.body');
 
221
        // We must use innerText, and not innerHTML because our string contains
 
222
        // the "&" character (which would end up being escaped as "&amp;") and
 
223
        // the string comparison would fail...
 
224
        fqstate = elem ? elem.get('innerText') : null;
 
225
 
 
226
        hash = _getHash();
 
227
 
 
228
        setInterval(function () {
 
229
            var newfqstate, states, newHash;
 
230
 
 
231
            elem = G._historyIFrame.get('contentWindow.document.body');
 
232
            // See my comment above about using innerText instead of innerHTML...
 
233
            newfqstate = elem ? elem.get('innerText') : null;
 
234
 
 
235
            newHash = _getHash();
 
236
 
 
237
            if (newfqstate !== fqstate) {
 
238
 
 
239
                fqstate = newfqstate;
 
240
                _handleFQStateChange(fqstate);
 
241
 
 
242
                if (!fqstate) {
 
243
                    states = [];
 
244
                    Y.Object.each(G._modules, function (module, moduleId) {
 
245
                        states.push(moduleId + '=' + module.initialState);
 
246
                    });
 
247
                    newHash = states.join('&');
 
248
                } else {
 
249
                    newHash = fqstate;
 
250
                }
 
251
 
 
252
                // Allow the state to be bookmarked by setting the top window's
 
253
                // URL fragment identifier. Note that here, we are on IE < 8
 
254
                // which does not touch the browser history when changing the
 
255
                // hash (unlike all the other browsers).
 
256
                win.location.hash = hash = newHash;
 
257
 
 
258
                _storeStates();
 
259
 
 
260
            } else if (newHash !== hash) {
 
261
 
 
262
                // The hash has changed. The user might have clicked on a link,
 
263
                // or modified the URL directly, or opened the same application
 
264
                // bookmarked in a specific state using a bookmark. However, we
 
265
                // know the hash change was not caused by a hit on the back or
 
266
                // forward buttons, or by a call to navigate() (because it would
 
267
                // have been handled above) We must handle these cases, which is
 
268
                // why we also need to keep track of hash changes on IE!
 
269
 
 
270
                // Note that IE6 has some major issues with this kind of user
 
271
                // interaction (the history stack gets completely messed up)
 
272
                // but it seems to work fine on IE7.
 
273
 
 
274
                hash = newHash;
 
275
 
 
276
                // Now, store a new history entry. The following will cause the
 
277
                // code above to execute, doing all the dirty work for us...
 
278
                _updateIFrame(newHash);
 
279
            }
 
280
 
 
281
        }, 50);
 
282
 
 
283
        G.ready = true;
 
284
        H.fire(EV_HISTORY_READY);
 
285
    }
 
286
 
 
287
    /**
 
288
     * Finish up the initialization of the browser utility library.
 
289
     * @method _initialize
 
290
     * @private
 
291
     */
 
292
    function _initialize() {
 
293
        var m, parts, moduleId, module, initialState, currentState, hash;
 
294
 
 
295
        // Decode the content of our storage field...
 
296
        parts = G._stateField.get('value').split('|');
 
297
 
 
298
        if (parts.length > 1) {
 
299
 
 
300
            REGEXP.lastIndex = 0;
 
301
            while ((m = REGEXP.exec(parts[0]))) {
 
302
                moduleId = m[1];
 
303
                initialState = m[2];
 
304
                module = G._modules[moduleId];
 
305
                if (module) {
 
306
                    module.initialState = initialState;
 
307
                }
 
308
            }
 
309
 
 
310
            REGEXP.lastIndex = 0;
 
311
            while ((m = REGEXP.exec(parts[1]))) {
 
312
                moduleId = m[1];
 
313
                currentState = m[2];
 
314
                module = G._modules[moduleId];
 
315
                if (module) {
 
316
                    module.currentState = currentState;
 
317
                }
 
318
            }
 
319
        }
 
320
 
 
321
        // IE8 in IE7 mode defines window.onhashchange, but never fires it...
 
322
        if (!Y.Lang.isUndefined(win.onhashchange) &&
 
323
            (Y.Lang.isUndefined(doc.documentMode) || doc.documentMode > 7)) {
 
324
 
 
325
            // The HTML5 way of handling DHTML history...
 
326
            // @TODO This is case-insensitive, at least in IE (WHY? spec, please actually specify things)
 
327
            // bug #2528444
 
328
            win.onhashchange = function () {
 
329
                var hash = _getHash();
 
330
                _handleFQStateChange(hash);
 
331
                _storeStates();
 
332
            };
 
333
 
 
334
            G.ready = true;
 
335
            H.fire(EV_HISTORY_READY);
 
336
 
 
337
        } else if (_useIFrame) {
 
338
 
 
339
            // IE < 8 or IE8 in quirks mode or IE7 standards mode
 
340
            _checkIframeLoaded();
 
341
 
 
342
        } else {
 
343
 
 
344
            // Periodically check whether a navigate operation has been
 
345
            // requested on the main window. This will happen when
 
346
            // History.navigate has been called, or after the user
 
347
            // has hit the back/forward button.
 
348
 
 
349
            // On Gecko and Opera, we just need to watch the hash...
 
350
            hash = _getHash();
 
351
 
 
352
            setInterval(function () {
 
353
                var newHash = _getHash();
 
354
                if (newHash !== hash) {
 
355
                    hash = newHash;
 
356
                    _handleFQStateChange(hash);
 
357
                    _storeStates();
 
358
                }
 
359
            }, 50);
 
360
 
 
361
            G.ready = true;
 
362
            H.fire(EV_HISTORY_READY);
 
363
        }
 
364
    }
 
365
 
 
366
 
 
367
    H = Y.mix(new Y.EventTarget(), {
 
368
 
 
369
        /**
 
370
         * Registers a new module.
 
371
         * @method register
 
372
         * @param {string} moduleId Non-empty string uniquely identifying the
 
373
         *     module you wish to register.
 
374
         * @param {string} initialState The initial state of the specified
 
375
         *     module corresponding to its earliest history entry.
 
376
         * @return {History.Module} The newly registered module
 
377
         */
 
378
        register: function (moduleId, initialState) {
 
379
            var module;
 
380
 
 
381
            if (!Y.Lang.isString(moduleId) || Y.Lang.trim(moduleId) === '' || !Y.Lang.isString(initialState)) {
 
382
                throw new Error(E_MISSING_OR_INVALID_ARG);
 
383
            }
 
384
 
 
385
            moduleId = encode(moduleId);
 
386
            initialState = encode(initialState);
 
387
 
 
388
            if (G._modules[moduleId]) {
 
389
                // The module seems to have already been registered.
 
390
                return;
 
391
            }
 
392
 
 
393
            // Note: A module CANNOT be registered once the browser history
 
394
            // utility has been initialized. This is related to reading and
 
395
            // writing state values from/to the input field. Relaxing this
 
396
            // rule would potentially create situations rather complicated
 
397
            // to deal with.
 
398
            if (G.ready) {
 
399
                return null;
 
400
            }
 
401
 
 
402
            module = new H.Module(moduleId, initialState);
 
403
            G._modules[moduleId] = module;
 
404
            return module;
 
405
        },
 
406
 
 
407
        /**
 
408
         * Initializes the Browser History Manager. Call this method
 
409
         * from a script block located right after the opening body tag.
 
410
         * @method initialize
 
411
         * @param {string|HTML Element} stateField <input type="hidden"> used
 
412
         *     to store application states. Must be in the static markup.
 
413
         * @param {string|HTML Element} historyIFrame IFrame used to store
 
414
         *     the history (only required for IE6/7)
 
415
         * @public
 
416
         */
 
417
        initialize: function (stateField, historyIFrame) {
 
418
            var tagName, type;
 
419
 
 
420
            if (G.ready) {
 
421
                // The browser history utility has already been initialized.
 
422
                return true;
 
423
            }
 
424
 
 
425
            stateField = Y.one(stateField);
 
426
            if (!stateField) {
 
427
                throw new Error(E_MISSING_OR_INVALID_ARG);
 
428
            }
 
429
 
 
430
            tagName = stateField.get('tagName').toUpperCase();
 
431
            type = stateField.get('type');
 
432
 
 
433
            if (tagName !== 'TEXTAREA' && (tagName !== 'INPUT' || type !== 'hidden' && type !== 'text')) {
 
434
                throw new Error(E_MISSING_OR_INVALID_ARG);
 
435
            }
 
436
 
 
437
            // IE < 8 or IE8 in quirks mode or IE7 standards mode
 
438
            if (Y.UA.ie && (Y.Lang.isUndefined(doc.documentMode) || doc.documentMode < 8)) {
 
439
                _useIFrame = true;
 
440
                historyIFrame = Y.one(historyIFrame);
 
441
                if (!historyIFrame || historyIFrame.get('tagName').toUpperCase() !== 'IFRAME') {
 
442
                    throw new Error(E_MISSING_OR_INVALID_ARG);
 
443
                }
 
444
            }
 
445
 
 
446
            if (Y.UA.opera && !Y.Lang.isUndefined(win.history.navigationMode)) {
 
447
                // Disable Opera's fast back/forward navigation mode and put
 
448
                // it in compatible mode. This makes anchor-based history
 
449
                // navigation work after the page has been navigated away
 
450
                // from and re-activated, at the cost of slowing down
 
451
                // back/forward navigation to and from that page.
 
452
                win.history.navigationMode = 'compatible';
 
453
            }
 
454
 
 
455
            G._stateField = stateField;
 
456
            G._historyIFrame = historyIFrame;
 
457
 
 
458
            Y.on('domready', _initialize);
 
459
            return true;
 
460
        },
 
461
 
 
462
        /**
 
463
         * Stores a new entry in the browser history by changing the state of a registered module.
 
464
         * @method navigate
 
465
         * @param {string} module Non-empty string representing your module.
 
466
         * @param {string} state String representing the new state of the specified module.
 
467
         * @return {boolean} Indicates whether the new state was successfully added to the history.
 
468
         * @public
 
469
         */
 
470
        navigate: function (moduleId, state) {
 
471
            var states;
 
472
 
 
473
            if (!Y.Lang.isString(moduleId) || !Y.Lang.isString(state)) {
 
474
                throw new Error(E_MISSING_OR_INVALID_ARG);
 
475
            }
 
476
 
 
477
            // The ncoding of module id and state takes place in mutiNavigate.
 
478
            states = {};
 
479
            states[moduleId] = state;
 
480
 
 
481
            return H.multiNavigate(states);
 
482
        },
 
483
 
 
484
        /**
 
485
         * Stores a new entry in the browser history by changing the state
 
486
         * of several registered modules in one atomic operation.
 
487
         * @method multiNavigate
 
488
         * @param {object} states Associative array of module-state pairs to set simultaneously.
 
489
         * @return {boolean} Indicates whether the new state was successfully added to the history.
 
490
         * @public
 
491
         */
 
492
        multiNavigate: function (states) {
 
493
            var newStates = [], fqstate, globalStateChanged = false;
 
494
 
 
495
            if (!G.ready) {
 
496
                return false;
 
497
            }
 
498
 
 
499
            Y.Object.each(G._modules, function (module, moduleId) {
 
500
                var state, decodedModuleId = decode(moduleId);
 
501
 
 
502
                if (!states.hasOwnProperty(decodedModuleId)) {
 
503
                    // The caller did not wish to modify the state of this
 
504
                    // module. We must however include it in fqstate!
 
505
                    state = module.currentState;
 
506
                } else {
 
507
                    state = encode(states[decodedModuleId]);
 
508
                    if (state !== module.upcomingState) {
 
509
                        module.upcomingState = state;
 
510
                        globalStateChanged = true;
 
511
                    }
 
512
                }
 
513
 
 
514
                newStates.push(moduleId + '=' + state);
 
515
            });
 
516
 
 
517
            if (!globalStateChanged) {
 
518
                // Nothing changed, so don't do anything.
 
519
                return false;
 
520
            }
 
521
 
 
522
            fqstate = newStates.join('&');
 
523
 
 
524
            if (_useIFrame) {
 
525
                return _updateIFrame(fqstate);
 
526
            } else {
 
527
                win.location.hash = fqstate;
 
528
                return true;
 
529
            }
 
530
        },
 
531
 
 
532
        /**
 
533
         * Returns the current state of the specified module.
 
534
         * @method getCurrentState
 
535
         * @param {string} moduleId Non-empty string representing your module.
 
536
         * @return {string} The current state of the specified module.
 
537
         * @public
 
538
         */
 
539
        getCurrentState: function (moduleId) {
 
540
            var module;
 
541
 
 
542
            if (!Y.Lang.isString(moduleId)) {
 
543
                throw new Error(E_MISSING_OR_INVALID_ARG);
 
544
            }
 
545
 
 
546
            if (!G.ready) {
 
547
                return null;
 
548
            }
 
549
 
 
550
            moduleId = encode(moduleId);
 
551
            module = G._modules[moduleId];
 
552
            if (!module) {
 
553
                return null;
 
554
            }
 
555
 
 
556
            return decode(module.currentState);
 
557
        },
 
558
 
 
559
        /**
 
560
         * Returns the state of a module according to the URL fragment
 
561
         * identifier. This method is useful to initialize your modules
 
562
         * if your application was bookmarked from a particular state.
 
563
         * @method getBookmarkedState
 
564
         * @param {string} moduleId Non-empty string representing your module.
 
565
         * @return {string} The bookmarked state of the specified module.
 
566
         * @public
 
567
         */
 
568
        getBookmarkedState: function (moduleId) {
 
569
            var m, i, h;
 
570
 
 
571
            if (!Y.Lang.isString(moduleId)) {
 
572
                throw new Error(E_MISSING_OR_INVALID_ARG);
 
573
            }
 
574
 
 
575
            moduleId = encode(moduleId);
 
576
 
 
577
            // Use location.href instead of location.hash which is already
 
578
            // URL-decoded, which creates problems if the state value
 
579
            // contained special characters...
 
580
            h = win.location.href;
 
581
            i = h.indexOf('#');
 
582
 
 
583
            if (i >= 0) {
 
584
                h = h.substr(i + 1);
 
585
                REGEXP.lastIndex = 0;
 
586
                while ((m = REGEXP.exec(h))) {
 
587
                    if (m[1] === moduleId) {
 
588
                        return decode(m[2]);
 
589
                    }
 
590
                }
 
591
            }
 
592
 
 
593
            return null;
 
594
        },
 
595
 
 
596
        /**
 
597
         * Returns the value of the specified query string parameter.
 
598
         * This method is not used internally by the Browser History Manager.
 
599
         * However, it is provided here as a helper since many applications
 
600
         * using the Browser History Manager will want to read the value of
 
601
         * url parameters to initialize themselves.
 
602
         * @method getQueryStringParameter
 
603
         * @param {string} paramName Name of the parameter we want to look up.
 
604
         * @param {string} queryString Optional URL to look at. If not specified,
 
605
         *     this method uses the URL in the address bar.
 
606
         * @return {string} The value of the specified parameter, or null.
 
607
         * @public
 
608
         * @deprecated Use Y.QueryString.parse() in the querystring module.
 
609
         * This will be removed in 3.2.0.
 
610
         */
 
611
        getQueryStringParameter: function (paramName, url) {
 
612
            var m, q, i;
 
613
 
 
614
            url = url || win.location.href;
 
615
 
 
616
            i = url.indexOf('?');
 
617
            q = i >= 0 ? url.substr(i + 1) : url;
 
618
 
 
619
            // Remove the hash if any
 
620
            i = q.lastIndexOf('#');
 
621
            q = i >= 0 ? q.substr(0, i) : q;
 
622
 
 
623
            REGEXP.lastIndex = 0;
 
624
            while ((m = REGEXP.exec(q))) {
 
625
                if (m[1] === paramName) {
 
626
                    return decode(m[2]);
 
627
                }
 
628
            }
 
629
 
 
630
            return null;
 
631
        }
 
632
    });
 
633
 
 
634
    /**
 
635
     * This class represents a browser history module.
 
636
     * @class History.Module
 
637
     * @constructor
 
638
     * @param id {String} the module identifier
 
639
     * @param initialState {String} the module's initial state
 
640
     * @deprecated Please use the new "history" module instead.
 
641
     */
 
642
    H.Module = function (id, initialState) {
 
643
 
 
644
        /**
 
645
         * The module identifier
 
646
         * @type String
 
647
         * @final
 
648
         */
 
649
        this.id = id;
 
650
 
 
651
        /**
 
652
         * The module's initial state
 
653
         * @type String
 
654
         * @final
 
655
         */
 
656
        this.initialState = initialState;
 
657
 
 
658
        /**
 
659
         * The module's current state
 
660
         * @type String
 
661
         * @final
 
662
         */
 
663
        this.currentState = initialState;
 
664
 
 
665
        /**
 
666
         * The module's upcoming state. There can be a slight delay between the
 
667
         * time a state is changed, and the time a state change is detected.
 
668
         * This property allows us to not fire the module state changed event
 
669
         * multiple times, making client code simpler.
 
670
         * @type String
 
671
         * @private
 
672
         * @final
 
673
         */
 
674
        this.upcomingState = initialState;
 
675
    };
 
676
 
 
677
    Y.augment(H.Module, Y.EventTarget);
 
678
 
 
679
    Y.History = H;
 
680
 
 
681
 
 
682
}, '3.2.0' ,{skinnable:false, requires:['node-base']});