eyeballs 0.3.7 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +6 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +47 -0
- data/README.md +62 -17
- data/Rakefile +1 -1
- data/dist/{jquery-1.4.2.min.js → jquery/jquery-1.4.2.min.js} +0 -0
- data/dist/jquery/jquery.ba-hashchange.js +244 -0
- data/dist/{jquery.livequery.js → jquery/jquery.livequery.js} +0 -0
- data/dist/{mustache.js → mustache/mustache.0.2.3.js} +27 -50
- data/eyeballs.gemspec +23 -14
- data/lib/eyeballs/app_generator.rb +3 -3
- data/spec/app_generator_spec.rb +7 -1
- data/spec/spec_helper.rb +1 -2
- data/src/{o_O.localstorage.js → adapters/o_O.localstorage.js} +0 -0
- data/src/{jquery.o_O.couchdb.js → drivers/jquery/adapters/o_O.couchdb.js} +0 -0
- data/src/{jquery.o_O.dom.js → drivers/jquery/adapters/o_O.dom.js} +0 -0
- data/src/{jquery.o_O.rails.js → drivers/jquery/adapters/o_O.rest.js} +1 -1
- data/src/{jquery.o_O.js → drivers/jquery/modules/o_O.controller.js} +3 -65
- data/src/drivers/jquery/modules/o_O.routes.js +45 -0
- data/src/drivers/jquery/modules/o_O.support.js +69 -0
- data/src/modules/o_O.model.js +188 -0
- data/src/modules/o_O.validations.js +45 -0
- data/src/o_O.js +0 -235
- data/templates/app_root/config/initializer.js +3 -0
- data/templates/app_root/config/routes.js +7 -0
- data/test/unit/test_controller.html +7 -7
- data/test/unit/test_dom.html +7 -4
- data/test/unit/test_dom_with_callbacks.html +7 -3
- data/test/unit/test_form.html +7 -2
- data/test/unit/test_localstorage.html +7 -4
- data/test/unit/test_model.html +7 -3
- data/test/unit/test_model_with_callbacks.html +7 -3
- data/test/unit/{test_rails.html → test_rest.html} +9 -6
- data/test/unit/test_routing.html +76 -0
- metadata +39 -15
- data/eyeballs.js.gemspec +0 -83
data/CHANGELOG
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
Tue Jul 6 2010
|
2
|
+
- - - - - - - -
|
3
|
+
- Housekeeping, add adapters, modules and drivers directories and relevant sub-directories
|
4
|
+
- Add routing
|
5
|
+
- use "meetings#index" style data-bind shortcuts instead of "meetings/index"
|
6
|
+
|
1
7
|
Thu Jun 17 2010
|
2
8
|
- - - - - - - -
|
3
9
|
- Add "prefix" to Rails find method
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
---
|
2
|
+
dependencies:
|
3
|
+
thor:
|
4
|
+
group:
|
5
|
+
- :default
|
6
|
+
version: ">= 0"
|
7
|
+
rspec:
|
8
|
+
group:
|
9
|
+
- :test
|
10
|
+
version: ">= 0"
|
11
|
+
sinatra:
|
12
|
+
group:
|
13
|
+
- :default
|
14
|
+
version: ">= 0"
|
15
|
+
jeweler:
|
16
|
+
group:
|
17
|
+
- :development
|
18
|
+
version: ">= 0"
|
19
|
+
activesupport:
|
20
|
+
group:
|
21
|
+
- :default
|
22
|
+
version: ">= 0"
|
23
|
+
specs:
|
24
|
+
- activesupport:
|
25
|
+
version: 2.3.8
|
26
|
+
- json_pure:
|
27
|
+
version: 1.4.3
|
28
|
+
- gemcutter:
|
29
|
+
version: 0.5.0
|
30
|
+
- git:
|
31
|
+
version: 1.2.5
|
32
|
+
- rubyforge:
|
33
|
+
version: 2.0.4
|
34
|
+
- jeweler:
|
35
|
+
version: 1.4.0
|
36
|
+
- rack:
|
37
|
+
version: 1.2.1
|
38
|
+
- rspec:
|
39
|
+
version: 1.3.0
|
40
|
+
- sinatra:
|
41
|
+
version: "1.0"
|
42
|
+
- thor:
|
43
|
+
version: 0.13.7
|
44
|
+
hash: 17f409790dfc3ab7e279201874a3aab85e4c7c95
|
45
|
+
sources:
|
46
|
+
- Rubygems:
|
47
|
+
uri: http://gemcutter.org
|
data/README.md
CHANGED
@@ -6,15 +6,16 @@ eyeballs.js is a slim javascript library designed to sit on top of a javascript
|
|
6
6
|
The goals are:
|
7
7
|
|
8
8
|
* Organisation of client-side web app code using the Model-View-Controller pattern.
|
9
|
-
* Simple model implementation for
|
10
|
-
*
|
9
|
+
* Simple model implementation for handling non event-related concerns.
|
10
|
+
* Simple routing layer for hash-tag change based navigation, preserving the back-button
|
11
|
+
* Rapid development of javascript apps using strong conventions.
|
11
12
|
* Easing the pain of building fast, responsive interfaces.
|
12
13
|
* Exploring the possibilities of offline web apps.
|
13
14
|
|
14
15
|
The implementation is owes a lot to Ruby on Rails, but also attempts to be idiomatic javascript.
|
15
16
|
|
16
17
|
Overview
|
17
|
-
|
18
|
+
--------
|
18
19
|
|
19
20
|
eyeballs.js can sit on top of an already implemented web app with a well thought out object model. It can also be used to build standalone javascript apps, backed by HTML5 local storage or something like CouchDB.
|
20
21
|
|
@@ -22,14 +23,20 @@ eyeballs.js models are not necessarily one-to-one mapped to server side models u
|
|
22
23
|
|
23
24
|
Finally, eyeballs.js is still a bit of an experiment. It's a quick implementation of a crazy idea to help make javascript code a little bit more organised.
|
24
25
|
|
26
|
+
eyeballs.js is supposed to be both agnostic and modular. The code is broken down into modules, drivers and adapters.
|
27
|
+
|
28
|
+
*Modules* add various parts of functionality, for example the code that powers the individual model, controller, routing and validation layers.
|
29
|
+
*Drivers* add support for underlying javascript frameworks. Features that rely on event handling etc. are part of driver logic.
|
30
|
+
*Adapters* provide an API to various persistence layers, eg. HTML5 Local Storage, a REST interface or a CouchDB instance.
|
31
|
+
|
25
32
|
Getting Started
|
26
|
-
|
33
|
+
---------------
|
27
34
|
|
28
35
|
eyeballs.js is packaged into modules, according to dependencies.
|
29
36
|
|
30
|
-
The main
|
37
|
+
The main library has no dependencies and lets you use eyeballs.js models standalone.
|
31
38
|
|
32
|
-
Standalone,
|
39
|
+
Standalone, eyeballs.js doesn't do much: it provides the o\_O() function for initializing models and some validations.
|
33
40
|
|
34
41
|
At a very minimum, you should choose an adapter. There are a few to choose from:
|
35
42
|
|
@@ -38,7 +45,7 @@ At a very minimum, you should choose an adapter. There are a few to choose from:
|
|
38
45
|
- **o\_O.couchdb** - persist records to a local CouchDB instance, for building MVC CouchApps, for example.
|
39
46
|
- **o\_O.rails** - An adapter for persisting models to a backend powered by Rails, or using Rails-style RESTful routing.
|
40
47
|
|
41
|
-
Finally, you need a controller. The first release of eyeballs.js includes a controller
|
48
|
+
Finally, you need a controller. The first release of eyeballs.js includes a controller as part of the jQuery driver. This adapter also depends on jQuery.livequery.
|
42
49
|
|
43
50
|
You can also use a javascript templating language. Mustache.js fits this need quite nicely.
|
44
51
|
|
@@ -51,17 +58,23 @@ Wrapping that all up, to use eyeballs.js with the Rails adapter and jQuery:
|
|
51
58
|
<!-- Mustache for templating -->
|
52
59
|
<script src="mustache.js"></script>
|
53
60
|
|
54
|
-
<!-- eyeballs.js -->
|
61
|
+
<!-- eyeballs.js basic -->
|
55
62
|
<script src="o_O.js"></script>
|
56
|
-
<script src="
|
63
|
+
<script src="modules/o_O.model.js"></script>
|
64
|
+
<script src="modules/o_O.validations.js"></script>
|
65
|
+
|
66
|
+
<!-- eyeballs.js jquery driver for controller logic -->
|
67
|
+
<script src="drivers/jquery/modules/o_O.controller.js"></script>
|
68
|
+
<script src="drivers/jquery/modules/o_O.support.js"></script>
|
69
|
+
<script src="drivers/jquery/modules/o_O.routes.js"></script>
|
57
70
|
|
58
|
-
<!--
|
59
|
-
<script src="o_O.
|
71
|
+
<!-- REST adapter -->
|
72
|
+
<script src="drivers/jquery/adapters/o_O.rest.js"></script>
|
60
73
|
|
61
74
|
Badabing, badaboom! You're now ready to start creating some models and controllers.
|
62
75
|
|
63
76
|
Generators
|
64
|
-
|
77
|
+
----------
|
65
78
|
|
66
79
|
If you install the eyeballs.js Ruby gem, you can use the eyeballs command to generate eyeballs.js apps, models and controllers:
|
67
80
|
|
@@ -89,7 +102,7 @@ This will generate a `posts.html`, a `post.js` and a `posts_controller.js`.
|
|
89
102
|
If the generator detects a "public" directory when you run it, it will install into public/javascripts.
|
90
103
|
|
91
104
|
Models
|
92
|
-
|
105
|
+
------
|
93
106
|
|
94
107
|
You define a model by passing a name and function to the eyeballs ( o_O ) function (pronounced 'eep eep'). As inspired by Rails, model definitions are capitalised. Note, however, that the new prefix is not used.
|
95
108
|
|
@@ -181,7 +194,7 @@ Finding, saving, updating and deleting. With callbacks? Easy peasy:
|
|
181
194
|
There's a strong emphasis on callbacks: since any persisting to backends should be done asynchronously.
|
182
195
|
|
183
196
|
Controllers
|
184
|
-
|
197
|
+
-----------
|
185
198
|
|
186
199
|
An eyeballs.js controller is also initialized with the eyeballs function, by passing a string name and an object containing the controller actions.
|
187
200
|
|
@@ -196,6 +209,36 @@ An eyeballs.js controller is also initialized with the eyeballs function, by pas
|
|
196
209
|
|
197
210
|
Again, this looks nice and familiar. Dead, dead simple.
|
198
211
|
|
212
|
+
### Calling Controller Actions & Binding Events ###
|
213
|
+
|
214
|
+
There are several ways to bind events to controller actions.
|
215
|
+
|
216
|
+
#### Calling Directly ####
|
217
|
+
|
218
|
+
The simplest way to call controller actions is to bind them directly. From the above example, you can simply call:
|
219
|
+
|
220
|
+
PostsController.new()
|
221
|
+
|
222
|
+
...once you have initialized your controller.
|
223
|
+
|
224
|
+
#### Routing ####
|
225
|
+
|
226
|
+
You can use the eyeballs.js router to bind events to changes in the URL hash. This is particularly effective for graceful degradation, as well as preserving the back button history.
|
227
|
+
|
228
|
+
Your `config/routes.js` file would look something like this:
|
229
|
+
|
230
|
+
o_O.routes.draw(function(map){
|
231
|
+
map.match('/posts/new/', {to: 'posts#new'})
|
232
|
+
})
|
233
|
+
|
234
|
+
You can now bind this to particular links, by adding the `data-ajax-history` attribute to your `a` elements:
|
235
|
+
|
236
|
+
<a href="/posts/new" data-ajax-history="true">Click Me!</a>
|
237
|
+
|
238
|
+
This link will now call `PostsController.new()` when it is clicked.
|
239
|
+
|
240
|
+
#### Binding actions to events ####
|
241
|
+
|
199
242
|
To bind events to these controller actions, use the data-controller and data-action attributes:
|
200
243
|
|
201
244
|
<a href="/posts/new" data-controller="posts" data-action="new">Click me!</a>
|
@@ -231,7 +274,9 @@ Finally, in shorthand only, you can bind multiple events to a single element:
|
|
231
274
|
Isn't that cool?
|
232
275
|
|
233
276
|
Putting it all together
|
234
|
-
|
277
|
+
-----------------------
|
278
|
+
|
279
|
+
TODO: The demo app isn't working right now. There should be a generator to generate a new demo app after each release.
|
235
280
|
|
236
281
|
There's a small demo app included in this package, a simple app for adding personal reviews. It's a simple Sinatra app, so you can run it with:
|
237
282
|
|
@@ -290,12 +335,12 @@ That's all for now!
|
|
290
335
|
|
291
336
|
|
292
337
|
Running the tests
|
293
|
-
|
338
|
+
-----------------
|
294
339
|
|
295
340
|
eyeballs.js uses QUnit for in-browser testing. Just load the files in the test directory in any browser to run them.
|
296
341
|
|
297
342
|
About me
|
298
|
-
|
343
|
+
--------
|
299
344
|
|
300
345
|
I'm Paul Campbell. I'm an avid web developer. Follow my ramblings at [http://www.pabcas.com](http://www.pabcas.com)
|
301
346
|
|
data/Rakefile
CHANGED
File without changes
|
@@ -0,0 +1,244 @@
|
|
1
|
+
/*!
|
2
|
+
* jQuery hashchange event - v1.2 - 2/11/2010
|
3
|
+
* http://benalman.com/projects/jquery-hashchange-plugin/
|
4
|
+
*
|
5
|
+
* Copyright (c) 2010 "Cowboy" Ben Alman
|
6
|
+
* Dual licensed under the MIT and GPL licenses.
|
7
|
+
* http://benalman.com/about/license/
|
8
|
+
*/
|
9
|
+
|
10
|
+
// Script: jQuery hashchange event
|
11
|
+
//
|
12
|
+
// *Version: 1.2, Last updated: 2/11/2010*
|
13
|
+
//
|
14
|
+
// Project Home - http://benalman.com/projects/jquery-hashchange-plugin/
|
15
|
+
// GitHub - http://github.com/cowboy/jquery-hashchange/
|
16
|
+
// Source - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.js
|
17
|
+
// (Minified) - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.min.js (1.1kb)
|
18
|
+
//
|
19
|
+
// About: License
|
20
|
+
//
|
21
|
+
// Copyright (c) 2010 "Cowboy" Ben Alman,
|
22
|
+
// Dual licensed under the MIT and GPL licenses.
|
23
|
+
// http://benalman.com/about/license/
|
24
|
+
//
|
25
|
+
// About: Examples
|
26
|
+
//
|
27
|
+
// This working example, complete with fully commented code, illustrate one way
|
28
|
+
// in which this plugin can be used.
|
29
|
+
//
|
30
|
+
// hashchange event - http://benalman.com/code/projects/jquery-hashchange/examples/hashchange/
|
31
|
+
//
|
32
|
+
// About: Support and Testing
|
33
|
+
//
|
34
|
+
// Information about what version or versions of jQuery this plugin has been
|
35
|
+
// tested with, what browsers it has been tested in, and where the unit tests
|
36
|
+
// reside (so you can test it yourself).
|
37
|
+
//
|
38
|
+
// jQuery Versions - 1.3.2, 1.4.1, 1.4.2pre
|
39
|
+
// Browsers Tested - Internet Explorer 6-8, Firefox 2-3.7, Safari 3-4, Chrome, Opera 9.6-10.1.
|
40
|
+
// Unit Tests - http://benalman.com/code/projects/jquery-hashchange/unit/
|
41
|
+
//
|
42
|
+
// About: Known issues
|
43
|
+
//
|
44
|
+
// While this jQuery hashchange event implementation is quite stable and robust,
|
45
|
+
// there are a few unfortunate browser bugs surrounding expected hashchange
|
46
|
+
// event-based behaviors, independent of any JavaScript window.onhashchange
|
47
|
+
// abstraction. See the following examples for more information:
|
48
|
+
//
|
49
|
+
// Chrome: Back Button - http://benalman.com/code/projects/jquery-hashchange/examples/bug-chrome-back-button/
|
50
|
+
// Firefox: Remote XMLHttpRequest - http://benalman.com/code/projects/jquery-hashchange/examples/bug-firefox-remote-xhr/
|
51
|
+
// WebKit: Back Button in an Iframe - http://benalman.com/code/projects/jquery-hashchange/examples/bug-webkit-hash-iframe/
|
52
|
+
// Safari: Back Button from a different domain - http://benalman.com/code/projects/jquery-hashchange/examples/bug-safari-back-from-diff-domain/
|
53
|
+
//
|
54
|
+
// About: Release History
|
55
|
+
//
|
56
|
+
// 1.2 - (2/11/2010) Fixed a bug where coming back to a page using this plugin
|
57
|
+
// from a page on another domain would cause an error in Safari 4. Also,
|
58
|
+
// IE6/7 Iframe is now inserted after the body (this actually works),
|
59
|
+
// which prevents the page from scrolling when the event is first bound.
|
60
|
+
// Event can also now be bound before DOM ready, but it won't be usable
|
61
|
+
// before then in IE6/7.
|
62
|
+
// 1.1 - (1/21/2010) Incorporated document.documentMode test to fix IE8 bug
|
63
|
+
// where browser version is incorrectly reported as 8.0, despite
|
64
|
+
// inclusion of the X-UA-Compatible IE=EmulateIE7 meta tag.
|
65
|
+
// 1.0 - (1/9/2010) Initial Release. Broke out the jQuery BBQ event.special
|
66
|
+
// window.onhashchange functionality into a separate plugin for users
|
67
|
+
// who want just the basic event & back button support, without all the
|
68
|
+
// extra awesomeness that BBQ provides. This plugin will be included as
|
69
|
+
// part of jQuery BBQ, but also be available separately.
|
70
|
+
|
71
|
+
(function($,window,undefined){
|
72
|
+
'$:nomunge'; // Used by YUI compressor.
|
73
|
+
|
74
|
+
// Method / object references.
|
75
|
+
var fake_onhashchange,
|
76
|
+
jq_event_special = $.event.special,
|
77
|
+
|
78
|
+
// Reused strings.
|
79
|
+
str_location = 'location',
|
80
|
+
str_hashchange = 'hashchange',
|
81
|
+
str_href = 'href',
|
82
|
+
|
83
|
+
// IE6/7 specifically need some special love when it comes to back-button
|
84
|
+
// support, so let's do a little browser sniffing..
|
85
|
+
browser = $.browser,
|
86
|
+
mode = document.documentMode,
|
87
|
+
is_old_ie = browser.msie && ( mode === undefined || mode < 8 ),
|
88
|
+
|
89
|
+
// Does the browser support window.onhashchange? Test for IE version, since
|
90
|
+
// IE8 incorrectly reports this when in "IE7" or "IE8 Compatibility View"!
|
91
|
+
supports_onhashchange = 'on' + str_hashchange in window && !is_old_ie;
|
92
|
+
|
93
|
+
// Get location.hash (or what you'd expect location.hash to be) sans any
|
94
|
+
// leading #. Thanks for making this necessary, Firefox!
|
95
|
+
function get_fragment( url ) {
|
96
|
+
url = url || window[ str_location ][ str_href ];
|
97
|
+
return url.replace( /^[^#]*#?(.*)$/, '$1' );
|
98
|
+
};
|
99
|
+
|
100
|
+
// Property: jQuery.hashchangeDelay
|
101
|
+
//
|
102
|
+
// The numeric interval (in milliseconds) at which the <hashchange event>
|
103
|
+
// polling loop executes. Defaults to 100.
|
104
|
+
|
105
|
+
$[ str_hashchange + 'Delay' ] = 100;
|
106
|
+
|
107
|
+
// Event: hashchange event
|
108
|
+
//
|
109
|
+
// Fired when location.hash changes. In browsers that support it, the native
|
110
|
+
// window.onhashchange event is used (IE8, FF3.6), otherwise a polling loop is
|
111
|
+
// initialized, running every <jQuery.hashchangeDelay> milliseconds to see if
|
112
|
+
// the hash has changed. In IE 6 and 7, a hidden Iframe is created to allow
|
113
|
+
// the back button and hash-based history to work.
|
114
|
+
//
|
115
|
+
// Usage:
|
116
|
+
//
|
117
|
+
// > $(window).bind( 'hashchange', function(e) {
|
118
|
+
// > var hash = location.hash;
|
119
|
+
// > ...
|
120
|
+
// > });
|
121
|
+
//
|
122
|
+
// Additional Notes:
|
123
|
+
//
|
124
|
+
// * The polling loop and Iframe are not created until at least one callback
|
125
|
+
// is actually bound to 'hashchange'.
|
126
|
+
// * If you need the bound callback(s) to execute immediately, in cases where
|
127
|
+
// the page 'state' exists on page load (via bookmark or page refresh, for
|
128
|
+
// example) use $(window).trigger( 'hashchange' );
|
129
|
+
// * The event can be bound before DOM ready, but since it won't be usable
|
130
|
+
// before then in IE6/7 (due to the necessary Iframe), recommended usage is
|
131
|
+
// to bind it inside a $(document).ready() callback.
|
132
|
+
|
133
|
+
jq_event_special[ str_hashchange ] = $.extend( jq_event_special[ str_hashchange ], {
|
134
|
+
|
135
|
+
// Called only when the first 'hashchange' event is bound to window.
|
136
|
+
setup: function() {
|
137
|
+
// If window.onhashchange is supported natively, there's nothing to do..
|
138
|
+
if ( supports_onhashchange ) { return false; }
|
139
|
+
|
140
|
+
// Otherwise, we need to create our own. And we don't want to call this
|
141
|
+
// until the user binds to the event, just in case they never do, since it
|
142
|
+
// will create a polling loop and possibly even a hidden Iframe.
|
143
|
+
$( fake_onhashchange.start );
|
144
|
+
},
|
145
|
+
|
146
|
+
// Called only when the last 'hashchange' event is unbound from window.
|
147
|
+
teardown: function() {
|
148
|
+
// If window.onhashchange is supported natively, there's nothing to do..
|
149
|
+
if ( supports_onhashchange ) { return false; }
|
150
|
+
|
151
|
+
// Otherwise, we need to stop ours (if possible).
|
152
|
+
$( fake_onhashchange.stop );
|
153
|
+
}
|
154
|
+
|
155
|
+
});
|
156
|
+
|
157
|
+
// fake_onhashchange does all the work of triggering the window.onhashchange
|
158
|
+
// event for browsers that don't natively support it, including creating a
|
159
|
+
// polling loop to watch for hash changes and in IE 6/7 creating a hidden
|
160
|
+
// Iframe to enable back and forward.
|
161
|
+
fake_onhashchange = (function(){
|
162
|
+
var self = {},
|
163
|
+
timeout_id,
|
164
|
+
iframe,
|
165
|
+
set_history,
|
166
|
+
get_history;
|
167
|
+
|
168
|
+
// Initialize. In IE 6/7, creates a hidden Iframe for history handling.
|
169
|
+
function init(){
|
170
|
+
// Most browsers don't need special methods here..
|
171
|
+
set_history = get_history = function(val){ return val; };
|
172
|
+
|
173
|
+
// But IE6/7 do!
|
174
|
+
if ( is_old_ie ) {
|
175
|
+
|
176
|
+
// Create hidden Iframe after the end of the body to prevent initial
|
177
|
+
// page load from scrolling unnecessarily.
|
178
|
+
iframe = $('<iframe src="javascript:0"/>').hide().insertAfter( 'body' )[0].contentWindow;
|
179
|
+
|
180
|
+
// Get history by looking at the hidden Iframe's location.hash.
|
181
|
+
get_history = function() {
|
182
|
+
return get_fragment( iframe.document[ str_location ][ str_href ] );
|
183
|
+
};
|
184
|
+
|
185
|
+
// Set a new history item by opening and then closing the Iframe
|
186
|
+
// document, *then* setting its location.hash.
|
187
|
+
set_history = function( hash, history_hash ) {
|
188
|
+
if ( hash !== history_hash ) {
|
189
|
+
var doc = iframe.document;
|
190
|
+
doc.open().close();
|
191
|
+
doc[ str_location ].hash = '#' + hash;
|
192
|
+
}
|
193
|
+
};
|
194
|
+
|
195
|
+
// Set initial history.
|
196
|
+
set_history( get_fragment() );
|
197
|
+
}
|
198
|
+
};
|
199
|
+
|
200
|
+
// Start the polling loop.
|
201
|
+
self.start = function() {
|
202
|
+
// Polling loop is already running!
|
203
|
+
if ( timeout_id ) { return; }
|
204
|
+
|
205
|
+
// Remember the initial hash so it doesn't get triggered immediately.
|
206
|
+
var last_hash = get_fragment();
|
207
|
+
|
208
|
+
// Initialize if not yet initialized.
|
209
|
+
set_history || init();
|
210
|
+
|
211
|
+
// This polling loop checks every $.hashchangeDelay milliseconds to see if
|
212
|
+
// location.hash has changed, and triggers the 'hashchange' event on
|
213
|
+
// window when necessary.
|
214
|
+
(function loopy(){
|
215
|
+
var hash = get_fragment(),
|
216
|
+
history_hash = get_history( last_hash );
|
217
|
+
|
218
|
+
if ( hash !== last_hash ) {
|
219
|
+
set_history( last_hash = hash, history_hash );
|
220
|
+
|
221
|
+
$(window).trigger( str_hashchange );
|
222
|
+
|
223
|
+
} else if ( history_hash !== last_hash ) {
|
224
|
+
window[ str_location ][ str_href ] = window[ str_location ][ str_href ].replace( /#.*/, '' ) + '#' + history_hash;
|
225
|
+
}
|
226
|
+
|
227
|
+
timeout_id = setTimeout( loopy, $[ str_hashchange + 'Delay' ] );
|
228
|
+
})();
|
229
|
+
};
|
230
|
+
|
231
|
+
// Stop the polling loop, but only if an IE6/7 Iframe wasn't created. In
|
232
|
+
// that case, even if there are no longer any bound event handlers, the
|
233
|
+
// polling loop is still necessary for back/next to work at all!
|
234
|
+
self.stop = function() {
|
235
|
+
if ( !iframe ) {
|
236
|
+
timeout_id && clearTimeout( timeout_id );
|
237
|
+
timeout_id = 0;
|
238
|
+
}
|
239
|
+
};
|
240
|
+
|
241
|
+
return self;
|
242
|
+
})();
|
243
|
+
|
244
|
+
})(jQuery,this);
|