1 | /**
|
2 | * Copyright 2014, Yahoo! Inc.
|
3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
|
4 | */
|
5 | /*global window */
|
6 | ;
|
7 |
|
8 | var EVENT_POPSTATE = 'popstate';
|
9 |
|
10 | /**
|
11 | * This only supports pushState for the browsers with native pushState support.
|
12 | * For other browsers (mainly IE8 and IE9), it will refresh the page upon pushState()
|
13 | * and replaceState().
|
14 | * @class History
|
15 | * @constructor
|
16 | * @param {Object} [options] The options object
|
17 | * @param {Window} [options.win=window] The window object
|
18 | */
|
19 | function History(options) {
|
20 | this.win = (options && options.win) || window;
|
21 | this._hasPushState = !!(this.win && this.win.history && this.win.history.pushState);
|
22 | }
|
23 |
|
24 | History.prototype = {
|
25 | /**
|
26 | * Add the given listener for 'popstate' event (nothing happens for browsers that
|
27 | * don't support popstate event).
|
28 | * @method on
|
29 | * @param {Function} listener
|
30 | */
|
31 | on: function (listener) {
|
32 | if (this._hasPushState) {
|
33 | this.win.addEventListener(EVENT_POPSTATE, listener);
|
34 | }
|
35 | },
|
36 |
|
37 | /**
|
38 | * Remove the given listener for 'popstate' event (nothing happens for browsers that
|
39 | * don't support popstate event).
|
40 | * @method off
|
41 | * @param {Function} listener
|
42 | */
|
43 | off: function (listener) {
|
44 | if (this._hasPushState) {
|
45 | this.win.removeEventListener(EVENT_POPSTATE, listener);
|
46 | }
|
47 | },
|
48 |
|
49 | /**
|
50 | * @method getState
|
51 | * @return {Object|null} The state object in history
|
52 | */
|
53 | getState: function () {
|
54 | return (this.win.history && this.win.history.state) || null;
|
55 | },
|
56 |
|
57 | /**
|
58 | * Gets the path string, including the pathname and search query (if it exists).
|
59 | * @method getUrl
|
60 | * @return {String} The url string that denotes current route path and query
|
61 | */
|
62 | getUrl: function () {
|
63 | var location = this.win.location;
|
64 | return location.pathname + location.search;
|
65 | },
|
66 |
|
67 | /**
|
68 | * Same as HTML5 pushState API, but with old browser support
|
69 | * @method pushState
|
70 | * @param {Object} state The state object
|
71 | * @param {String} title The title string
|
72 | * @param {String} url The new url
|
73 | */
|
74 | pushState: function (state, title, url) {
|
75 | var win = this.win;
|
76 | if (this._hasPushState) {
|
77 | win.history.pushState.apply(win.history, arguments);
|
78 | } else if (url) {
|
79 | win.location.href = url;
|
80 | }
|
81 | },
|
82 |
|
83 | /**
|
84 | * Same as HTML5 replaceState API, but with old browser support
|
85 | * @method replaceState
|
86 | * @param {Object} state The state object
|
87 | * @param {String} title The title string
|
88 | * @param {String} url The new url
|
89 | */
|
90 | replaceState: function (state, title, url) {
|
91 | var win = this.win;
|
92 | if (this._hasPushState) {
|
93 | win.history.replaceState.apply(win.history, arguments);
|
94 | } else if (url) {
|
95 | win.location.replace(url);
|
96 | }
|
97 | }
|
98 | };
|
99 |
|
100 | module.exports = History;
|