eyeballs 0.3.7 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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);
|