crossroadsjs-rails 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
- # Crossroads.js for Rails ![Build Status][travis_ci_build_status]
1
+ # Crossroads.js for Rails [![Build Status][travis_ci_build_status]][travis_ci][![Dependency Status][gemnasium_dependency_status]][gemnasium]
2
2
 
3
- Provides Crossroads.js (0.8.0) for use with Rails 3
3
+ Provides Crossroads.js (0.9.0) for use with Rails 3
4
4
 
5
- [RubyGems][ruby_gems] | [Ruby Toolbox][ruby_toolbox] | [GitHub][github] | [Travis CI][travis_ci] | [RubyDoc][ruby_doc]
5
+ [RubyGems][ruby_gems] | [Ruby Toolbox][ruby_toolbox] | [GitHub][github] | [Travis CI][travis_ci] | [Gemnasium][gemnasium] | [RubyDoc][ruby_doc]
6
6
 
7
7
  ## Installation
8
8
  ### JavaScript Dependencies
@@ -45,12 +45,14 @@ Crossroads.js is now installed. Woop!
45
45
  ##Crossroads.js Resources
46
46
  [Project Page][crossroadsjs_project_page] | [GitHub][crossroadsjs_github]
47
47
 
48
- [github]: http://github.com/philostler/crossroadsjs-rails
49
- [ruby_doc]: http://rubydoc.info/github/philostler/crossroadsjs-rails/master/frames
50
48
  [ruby_gems]: http://rubygems.org/gems/crossroadsjs-rails
49
+ [ruby_toolbox]: http://www.ruby-toolbox.com/projects/crossroadsjs-rails
50
+ [github]: http://github.com/philostler/crossroadsjs-rails
51
51
  [travis_ci]: http://travis-ci.org/philostler/crossroadsjs-rails
52
52
  [travis_ci_build_status]: https://secure.travis-ci.org/philostler/crossroadsjs-rails.png
53
- [ruby_toolbox]: http://www.ruby-toolbox.com/projects/crossroadsjs-rails
53
+ [gemnasium]: https://gemnasium.com/philostler/crossroadsjs-rails
54
+ [gemnasium_dependency_status]: https://gemnasium.com/philostler/crossroadsjs-rails.png
55
+ [ruby_doc]: http://rubydoc.info/github/philostler/crossroadsjs-rails/master/frames
54
56
  [jssignals_project_page]: http://millermedeiros.github.com/js-signals
55
57
  [jssignals_rails_github]: http://github.com/philostler/jssignals-rails
56
58
  [crossroadsjs_project_page]: http://millermedeiros.github.com/crossroads.js
@@ -1,6 +1,6 @@
1
1
  module Crossroadsjs
2
2
  module Rails
3
- VERSION = "1.1.0"
4
- CROSSROADSJS_VERSION = "0.8.0";
3
+ VERSION = "1.2.0"
4
+ CROSSROADSJS_VERSION = "0.9.0";
5
5
  end
6
6
  end
@@ -1,6 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Crossroadsjs::Rails do
4
- it { Crossroadsjs::Rails::VERSION.should == "1.1.0" }
5
- it { Crossroadsjs::Rails::CROSSROADSJS_VERSION.should == "0.8.0" }
4
+ it { Crossroadsjs::Rails::VERSION.should == "1.2.0" }
5
+ it { Crossroadsjs::Rails::CROSSROADSJS_VERSION.should == "0.9.0" }
6
6
  end
@@ -2,7 +2,7 @@
2
2
  * crossroads <http://millermedeiros.github.com/crossroads.js/>
3
3
  * License: MIT
4
4
  * Author: Miller Medeiros
5
- * Version: 0.8.0 (2012/3/5 14:26)
5
+ * Version: 0.9.0 (2012/5/28 23:9)
6
6
  */
7
7
 
8
8
  (function (define) {
@@ -42,7 +42,7 @@ define(['signals'], function (signals) {
42
42
  }
43
43
 
44
44
  function isFunction(val) {
45
- return isKind(val, 'Function');
45
+ return typeof val === 'function';
46
46
  }
47
47
 
48
48
  //borrowed from AMD-utils
@@ -75,6 +75,20 @@ define(['signals'], function (signals) {
75
75
  return result;
76
76
  }
77
77
 
78
+ //borrowed from AMD-Utils
79
+ function decodeQueryString(str) {
80
+ var queryArr = (str || '').replace('?', '').split('&'),
81
+ n = queryArr.length,
82
+ obj = {},
83
+ item, val;
84
+ while (n--) {
85
+ item = queryArr[n].split('=');
86
+ val = typecastValue(item[1]);
87
+ obj[item[0]] = (typeof val === 'string')? decodeURIComponent(val) : val;
88
+ }
89
+ return obj;
90
+ }
91
+
78
92
 
79
93
  // Crossroads --------
80
94
  //====================
@@ -91,6 +105,10 @@ define(['signals'], function (signals) {
91
105
 
92
106
  Crossroads.prototype = {
93
107
 
108
+ greedy : false,
109
+
110
+ greedyEnabled : true,
111
+
94
112
  normalizeFn : null,
95
113
 
96
114
  create : function () {
@@ -131,7 +149,7 @@ define(['signals'], function (signals) {
131
149
  cur;
132
150
 
133
151
  if (n) {
134
- this._notifyPrevRoutes(request);
152
+ this._notifyPrevRoutes(routes, request);
135
153
  this._prevRoutes = routes;
136
154
  //shold be incremental loop, execute routes in order
137
155
  while (i < n) {
@@ -146,14 +164,28 @@ define(['signals'], function (signals) {
146
164
  }
147
165
  },
148
166
 
149
- _notifyPrevRoutes : function(request) {
150
- var i = 0, cur;
151
- while (cur = this._prevRoutes[i++]) {
167
+ _notifyPrevRoutes : function(matchedRoutes, request) {
168
+ var i = 0, prev;
169
+ while (prev = this._prevRoutes[i++]) {
152
170
  //check if switched exist since route may be disposed
153
- if(cur.route.switched) cur.route.switched.dispatch(request);
171
+ if(prev.route.switched && this._didSwitch(prev.route, matchedRoutes)) {
172
+ prev.route.switched.dispatch(request);
173
+ }
154
174
  }
155
175
  },
156
176
 
177
+ _didSwitch : function (route, matchedRoutes){
178
+ var matched,
179
+ i = 0;
180
+ while (matched = matchedRoutes[i++]) {
181
+ // only dispatch switched if it is going to a different route
182
+ if (matched.route === route) {
183
+ return false;
184
+ }
185
+ }
186
+ return true;
187
+ },
188
+
157
189
  getNumRoutes : function () {
158
190
  return this._routes.length;
159
191
  },
@@ -173,12 +205,15 @@ define(['signals'], function (signals) {
173
205
  route;
174
206
  //should be decrement loop since higher priorities are added at the end of array
175
207
  while (route = routes[--n]) {
176
- if ((!res.length || route.greedy) && route.match(request)) {
208
+ if ((!res.length || this.greedy || route.greedy) && route.match(request)) {
177
209
  res.push({
178
210
  route : route,
179
211
  params : route._getParamsArray(request)
180
212
  });
181
213
  }
214
+ if (!this.greedyEnabled && res.length) {
215
+ break;
216
+ }
182
217
  }
183
218
  return res;
184
219
  },
@@ -190,7 +225,7 @@ define(['signals'], function (signals) {
190
225
 
191
226
  //"static" instance
192
227
  crossroads = new Crossroads();
193
- crossroads.VERSION = '0.8.0';
228
+ crossroads.VERSION = '0.9.0';
194
229
 
195
230
  crossroads.NORM_AS_ARRAY = function (req, vals) {
196
231
  return [vals.vals_];
@@ -230,6 +265,7 @@ define(['signals'], function (signals) {
230
265
  rules : void(0),
231
266
 
232
267
  match : function (request) {
268
+ request = request || '';
233
269
  return this._matchRegexp.test(request) && this._validateParams(request); //validate params even if regexp because of `request_` rule.
234
270
  },
235
271
 
@@ -249,15 +285,22 @@ define(['signals'], function (signals) {
249
285
  _isValidParam : function (request, prop, values) {
250
286
  var validationRule = this.rules[prop],
251
287
  val = values[prop],
252
- isValid = false;
288
+ isValid = false,
289
+ isQuery = (prop.indexOf('?') === 0);
253
290
 
254
291
  if (val == null && this._optionalParamsIds && arrayIndexOf(this._optionalParamsIds, prop) !== -1) {
255
292
  isValid = true;
256
293
  }
257
294
  else if (isRegExp(validationRule)) {
295
+ if (isQuery) {
296
+ val = values[prop +'_']; //use raw string
297
+ }
258
298
  isValid = validationRule.test(val);
259
299
  }
260
300
  else if (isArray(validationRule)) {
301
+ if (isQuery) {
302
+ val = values[prop +'_']; //use raw string
303
+ }
261
304
  isValid = arrayIndexOf(validationRule, val) !== -1;
262
305
  }
263
306
  else if (isFunction(validationRule)) {
@@ -271,12 +314,25 @@ define(['signals'], function (signals) {
271
314
  var shouldTypecast = this._router.shouldTypecast,
272
315
  values = crossroads.patternLexer.getParamValues(request, this._matchRegexp, shouldTypecast),
273
316
  o = {},
274
- n = values.length;
317
+ n = values.length,
318
+ param, val;
275
319
  while (n--) {
276
- o[n] = values[n]; //for RegExp pattern and also alias to normal paths
320
+ val = values[n];
277
321
  if (this._paramsIds) {
278
- o[this._paramsIds[n]] = values[n];
322
+ param = this._paramsIds[n];
323
+ if (param.indexOf('?') === 0 && val) {
324
+ //make a copy of the original string so array and
325
+ //RegExp validation can be applied properly
326
+ o[param +'_'] = val;
327
+ //update vals_ array as well since it will be used
328
+ //during dispatch
329
+ val = decodeQueryString(val);
330
+ values[n] = val;
331
+ }
332
+ o[param] = val;
279
333
  }
334
+ //alias to paths and for RegExp pattern
335
+ o[n] = val;
280
336
  }
281
337
  o.request_ = shouldTypecast? typecastValue(request) : request;
282
338
  o.vals_ = values;
@@ -290,11 +346,19 @@ define(['signals'], function (signals) {
290
346
  if (norm && isFunction(norm)) {
291
347
  params = norm(request, this._getParamsObject(request));
292
348
  } else {
293
- params = crossroads.patternLexer.getParamValues(request, this._matchRegexp, this._router.shouldTypecast);
349
+ params = this._getParamsObject(request).vals_;
294
350
  }
295
351
  return params;
296
352
  },
297
353
 
354
+ interpolate : function(replacements) {
355
+ var str = crossroads.patternLexer.interpolate(this._pattern, replacements);
356
+ if (! this._validateParams(str) ) {
357
+ throw new Error('Generated string doesn\'t validate against `Route.rules`.');
358
+ }
359
+ return str;
360
+ },
361
+
298
362
  dispose : function () {
299
363
  this._router.removeRoute(this);
300
364
  },
@@ -318,32 +382,88 @@ define(['signals'], function (signals) {
318
382
 
319
383
  crossroads.patternLexer = (function () {
320
384
 
385
+ var
386
+ //match chars that should be escaped on string regexp
387
+ ESCAPE_CHARS_REGEXP = /[\\.+*?\^$\[\](){}\/'#]/g,
321
388
 
322
- var ESCAPE_CHARS_REGEXP = /[\\.+*?\^$\[\](){}\/'#]/g, //match chars that should be escaped on string regexp
323
- UNNECESSARY_SLASHES_REGEXP = /\/$/g, //trailing slash
324
- OPTIONAL_SLASHES_REGEXP = /([:}]|\w(?=\/))\/?(:)/g, //slash between `::` or `}:` or `\w:`. $1 = before, $2 = after
325
- REQUIRED_SLASHES_REGEXP = /([:}])\/?(\{)/g, //used to insert slash between `:{` and `}{`
389
+ //trailing slashes (begin/end of string)
390
+ LOOSE_SLASHES_REGEXP = /^\/|\/$/g,
391
+ LEGACY_SLASHES_REGEXP = /\/$/g,
326
392
 
327
- REQUIRED_PARAMS_REGEXP = /\{([^}]+)\}/g, //match everything between `{ }`
328
- OPTIONAL_PARAMS_REGEXP = /:([^:]+):/g, //match everything between `: :`
329
- PARAMS_REGEXP = /(?:\{|:)([^}:]+)(?:\}|:)/g, //capture everything between `{ }` or `: :`
330
- REQUIRED_REST = /\{([^}]+)\*\}/g,
331
- OPTIONAL_REST = /:([^:]+)\*:/g,
393
+ //params - everything between `{ }` or `: :`
394
+ PARAMS_REGEXP = /(?:\{|:)([^}:]+)(?:\}|:)/g,
332
395
 
333
396
  //used to save params during compile (avoid escaping things that
334
397
  //shouldn't be escaped).
335
- SAVE_REQUIRED_PARAMS = '__CR_RP__',
336
- SAVE_OPTIONAL_PARAMS = '__CR_OP__',
337
- SAVE_REQUIRED_REST = '__CR_RR__',
338
- SAVE_OPTIONAL_REST = '__CR_OR__',
339
- SAVE_REQUIRED_SLASHES = '__CR_RS__',
340
- SAVE_OPTIONAL_SLASHES = '__CR_OS__',
341
- SAVED_REQUIRED_REGEXP = new RegExp(SAVE_REQUIRED_PARAMS, 'g'),
342
- SAVED_OPTIONAL_REGEXP = new RegExp(SAVE_OPTIONAL_PARAMS, 'g'),
343
- SAVED_REQUIRED_REST_REGEXP = new RegExp(SAVE_REQUIRED_REST, 'g'),
344
- SAVED_OPTIONAL_REST_REGEXP = new RegExp(SAVE_OPTIONAL_REST, 'g'),
345
- SAVED_OPTIONAL_SLASHES_REGEXP = new RegExp(SAVE_OPTIONAL_SLASHES, 'g'),
346
- SAVED_REQUIRED_SLASHES_REGEXP = new RegExp(SAVE_REQUIRED_SLASHES, 'g');
398
+ TOKENS = {
399
+ 'OS' : {
400
+ //optional slashes
401
+ //slash between `::` or `}:` or `\w:` or `:{?` or `}{?` or `\w{?`
402
+ rgx : /([:}]|\w(?=\/))\/?(:|(?:\{\?))/g,
403
+ save : '$1{{id}}$2',
404
+ res : '\\/?'
405
+ },
406
+ 'RS' : {
407
+ //required slashes
408
+ //used to insert slash between `:{` and `}{`
409
+ rgx : /([:}])\/?(\{)/g,
410
+ save : '$1{{id}}$2',
411
+ res : '\\/'
412
+ },
413
+ 'RQ' : {
414
+ //required query string - everything in between `{? }`
415
+ rgx : /\{\?([^}]+)\}/g,
416
+ //everything from `?` till `#` or end of string
417
+ res : '\\?([^#]+)'
418
+ },
419
+ 'OQ' : {
420
+ //optional query string - everything in between `:? :`
421
+ rgx : /:\?([^:]+):/g,
422
+ //everything from `?` till `#` or end of string
423
+ res : '(?:\\?([^#]*))?'
424
+ },
425
+ 'OR' : {
426
+ //optional rest - everything in between `: *:`
427
+ rgx : /:([^:]+)\*:/g,
428
+ res : '(.*)?' // optional group to avoid passing empty string as captured
429
+ },
430
+ 'RR' : {
431
+ //rest param - everything in between `{ *}`
432
+ rgx : /\{([^}]+)\*\}/g,
433
+ res : '(.+)'
434
+ },
435
+ // required/optional params should come after rest segments
436
+ 'RP' : {
437
+ //required params - everything between `{ }`
438
+ rgx : /\{([^}]+)\}/g,
439
+ res : '([^\\/?]+)'
440
+ },
441
+ 'OP' : {
442
+ //optional params - everything between `: :`
443
+ rgx : /:([^:]+):/g,
444
+ res : '([^\\/?]+)?\/?'
445
+ }
446
+ },
447
+
448
+ LOOSE_SLASH = 1,
449
+ STRICT_SLASH = 2,
450
+ LEGACY_SLASH = 3,
451
+
452
+ _slashMode = LOOSE_SLASH;
453
+
454
+
455
+ function precompileTokens(){
456
+ var key, cur;
457
+ for (key in TOKENS) {
458
+ if (TOKENS.hasOwnProperty(key)) {
459
+ cur = TOKENS[key];
460
+ cur.id = '__CR_'+ key +'__';
461
+ cur.save = ('save' in cur)? cur.save.replace('{{id}}', cur.id) : cur.id;
462
+ cur.rRestore = new RegExp(cur.id, 'g');
463
+ }
464
+ }
465
+ }
466
+ precompileTokens();
347
467
 
348
468
 
349
469
  function captureVals(regex, pattern) {
@@ -359,37 +479,48 @@ define(['signals'], function (signals) {
359
479
  }
360
480
 
361
481
  function getOptionalParamsIds(pattern) {
362
- return captureVals(OPTIONAL_PARAMS_REGEXP, pattern);
482
+ return captureVals(TOKENS.OP.rgx, pattern);
363
483
  }
364
484
 
365
485
  function compilePattern(pattern) {
366
486
  pattern = pattern || '';
487
+
367
488
  if(pattern){
368
- pattern = pattern.replace(UNNECESSARY_SLASHES_REGEXP, '');
369
- pattern = tokenize(pattern);
489
+ if (_slashMode === LOOSE_SLASH) {
490
+ pattern = pattern.replace(LOOSE_SLASHES_REGEXP, '');
491
+ }
492
+ else if (_slashMode === LEGACY_SLASH) {
493
+ pattern = pattern.replace(LEGACY_SLASHES_REGEXP, '');
494
+ }
495
+
496
+ //save tokens
497
+ pattern = replaceTokens(pattern, 'rgx', 'save');
498
+ //regexp escape
370
499
  pattern = pattern.replace(ESCAPE_CHARS_REGEXP, '\\$&');
371
- pattern = untokenize(pattern);
500
+ //restore tokens
501
+ pattern = replaceTokens(pattern, 'rRestore', 'res');
502
+
503
+ if (_slashMode === LOOSE_SLASH) {
504
+ pattern = '\\/?'+ pattern;
505
+ }
372
506
  }
373
- return new RegExp('^'+ pattern + '/?$'); //trailing slash is optional
374
- }
375
507
 
376
- function tokenize(pattern) {
377
- //save chars that shouldn't be escaped
378
- pattern = pattern.replace(OPTIONAL_SLASHES_REGEXP, '$1'+ SAVE_OPTIONAL_SLASHES +'$2');
379
- pattern = pattern.replace(REQUIRED_SLASHES_REGEXP, '$1'+ SAVE_REQUIRED_SLASHES +'$2');
380
- pattern = pattern.replace(OPTIONAL_REST, SAVE_OPTIONAL_REST);
381
- pattern = pattern.replace(REQUIRED_REST, SAVE_REQUIRED_REST);
382
- pattern = pattern.replace(OPTIONAL_PARAMS_REGEXP, SAVE_OPTIONAL_PARAMS);
383
- return pattern.replace(REQUIRED_PARAMS_REGEXP, SAVE_REQUIRED_PARAMS);
508
+ if (_slashMode !== STRICT_SLASH) {
509
+ //single slash is treated as empty and end slash is optional
510
+ pattern += '\\/?';
511
+ }
512
+ return new RegExp('^'+ pattern + '$');
384
513
  }
385
514
 
386
- function untokenize(pattern) {
387
- pattern = pattern.replace(SAVED_OPTIONAL_SLASHES_REGEXP, '\\/?');
388
- pattern = pattern.replace(SAVED_REQUIRED_SLASHES_REGEXP, '\\/');
389
- pattern = pattern.replace(SAVED_OPTIONAL_REST_REGEXP, '(.*)?'); // optional group to avoid passing empty string as captured
390
- pattern = pattern.replace(SAVED_REQUIRED_REST_REGEXP, '(.+)');
391
- pattern = pattern.replace(SAVED_OPTIONAL_REGEXP, '([^\\/]+)?\/?');
392
- return pattern.replace(SAVED_REQUIRED_REGEXP, '([^\\/]+)');
515
+ function replaceTokens(pattern, regexpName, replaceName) {
516
+ var cur, key;
517
+ for (key in TOKENS) {
518
+ if (TOKENS.hasOwnProperty(key)) {
519
+ cur = TOKENS[key];
520
+ pattern = pattern.replace(cur[regexpName], cur[replaceName]);
521
+ }
522
+ }
523
+ return pattern;
393
524
  }
394
525
 
395
526
  function getParamValues(request, regexp, shouldTypecast) {
@@ -403,12 +534,55 @@ define(['signals'], function (signals) {
403
534
  return vals;
404
535
  }
405
536
 
537
+ function interpolate(pattern, replacements) {
538
+ if (typeof pattern !== 'string') {
539
+ throw new Error('Route pattern should be a string.');
540
+ }
541
+
542
+ var replaceFn = function(match, prop){
543
+ var val;
544
+ if (prop in replacements) {
545
+ val = replacements[prop];
546
+ if (match.indexOf('*') === -1 && val.indexOf('/') !== -1) {
547
+ throw new Error('Invalid value "'+ val +'" for segment "'+ match +'".');
548
+ }
549
+ }
550
+ else if (match.indexOf('{') !== -1) {
551
+ throw new Error('The segment '+ match +' is required.');
552
+ }
553
+ else {
554
+ val = '';
555
+ }
556
+ return val;
557
+ };
558
+
559
+ if (! TOKENS.OS.trail) {
560
+ TOKENS.OS.trail = new RegExp('(?:'+ TOKENS.OS.id +')+$');
561
+ }
562
+
563
+ return pattern
564
+ .replace(TOKENS.OS.rgx, TOKENS.OS.save)
565
+ .replace(PARAMS_REGEXP, replaceFn)
566
+ .replace(TOKENS.OS.trail, '') // remove trailing
567
+ .replace(TOKENS.OS.rRestore, '/'); // add slash between segments
568
+ }
569
+
406
570
  //API
407
571
  return {
572
+ strict : function(){
573
+ _slashMode = STRICT_SLASH;
574
+ },
575
+ loose : function(){
576
+ _slashMode = LOOSE_SLASH;
577
+ },
578
+ legacy : function(){
579
+ _slashMode = LEGACY_SLASH;
580
+ },
408
581
  getParamIds : getParamIds,
409
582
  getOptionalParamsIds : getOptionalParamsIds,
410
583
  getParamValues : getParamValues,
411
- compilePattern : compilePattern
584
+ compilePattern : compilePattern,
585
+ interpolate : interpolate
412
586
  };
413
587
 
414
588
  }());
@@ -2,6 +2,6 @@
2
2
  * crossroads <http://millermedeiros.github.com/crossroads.js/>
3
3
  * License: MIT
4
4
  * Author: Miller Medeiros
5
- * Version: 0.8.0 (2012/3/5 14:26)
5
+ * Version: 0.9.0 (2012/5/28 23:9)
6
6
  */
7
- (function(a){a(["signals"],function(a){function d(a,b){if(a.indexOf)return a.indexOf(b);var c=a.length;while(c--)if(a[c]===b)return c;return-1}function e(a,b){return"[object "+b+"]"===Object.prototype.toString.call(a)}function f(a){return e(a,"RegExp")}function g(a){return e(a,"Array")}function h(a){return e(a,"Function")}function i(a){var b;return a===null||a==="null"?b=null:a==="true"?b=!0:a==="false"?b=!1:a===c||a==="undefined"?b=c:a===""||isNaN(a)?b=a:b=parseFloat(a),b}function j(a){var b=a.length,c=[];while(b--)c[b]=i(a[b]);return c}function k(){this._routes=[],this._prevRoutes=[],this.bypassed=new a.Signal,this.routed=new a.Signal}function l(c,d,e,g){var h=f(c),i=b.patternLexer;this._router=g,this._pattern=c,this._paramsIds=h?null:i.getParamIds(this._pattern),this._optionalParamsIds=h?null:i.getOptionalParamsIds(this._pattern),this._matchRegexp=h?c:i.compilePattern(c),this.matched=new a.Signal,this.switched=new a.Signal,d&&this.matched.add(d),this._priority=e||0}var b,c;return k.prototype={normalizeFn:null,create:function(){return new k},shouldTypecast:!1,addRoute:function(a,b,c){var d=new l(a,b,c,this);return this._sortedInsert(d),d},removeRoute:function(a){var b=d(this._routes,a);b!==-1&&this._routes.splice(b,1),a._destroy()},removeAllRoutes:function(){var a=this.getNumRoutes();while(a--)this._routes[a]._destroy();this._routes.length=0},parse:function(a,b){a=a||"",b=b||[];var c=this._getMatchedRoutes(a),d=0,e=c.length,f;if(e){this._notifyPrevRoutes(a),this._prevRoutes=c;while(d<e)f=c[d],f.route.matched.dispatch.apply(f.route.matched,b.concat(f.params)),f.isFirst=!d,this.routed.dispatch.apply(this.routed,b.concat([a,f])),d+=1}else this.bypassed.dispatch.apply(this.bypassed,b.concat([a]))},_notifyPrevRoutes:function(a){var b=0,c;while(c=this._prevRoutes[b++])c.route.switched&&c.route.switched.dispatch(a)},getNumRoutes:function(){return this._routes.length},_sortedInsert:function(a){var b=this._routes,c=b.length;do--c;while(b[c]&&a._priority<=b[c]._priority);b.splice(c+1,0,a)},_getMatchedRoutes:function(a){var b=[],c=this._routes,d=c.length,e;while(e=c[--d])(!b.length||e.greedy)&&e.match(a)&&b.push({route:e,params:e._getParamsArray(a)});return b},toString:function(){return"[crossroads numRoutes:"+this.getNumRoutes()+"]"}},b=new k,b.VERSION="0.8.0",b.NORM_AS_ARRAY=function(a,b){return[b.vals_]},b.NORM_AS_OBJECT=function(a,b){return[b]},l.prototype={greedy:!1,rules:void 0,match:function(a){return this._matchRegexp.test(a)&&this._validateParams(a)},_validateParams:function(a){var b=this.rules,c=this._getParamsObject(a),d;for(d in b)if(d!=="normalize_"&&b.hasOwnProperty(d)&&!this._isValidParam(a,d,c))return!1;return!0},_isValidParam:function(a,b,c){var e=this.rules[b],i=c[b],j=!1;return i==null&&this._optionalParamsIds&&d(this._optionalParamsIds,b)!==-1?j=!0:f(e)?j=e.test(i):g(e)?j=d(e,i)!==-1:h(e)&&(j=e(i,a,c)),j},_getParamsObject:function(a){var c=this._router.shouldTypecast,d=b.patternLexer.getParamValues(a,this._matchRegexp,c),e={},f=d.length;while(f--)e[f]=d[f],this._paramsIds&&(e[this._paramsIds[f]]=d[f]);return e.request_=c?i(a):a,e.vals_=d,e},_getParamsArray:function(a){var c=this.rules?this.rules.normalize_:null,d;return c=c||this._router.normalizeFn,c&&h(c)?d=c(a,this._getParamsObject(a)):d=b.patternLexer.getParamValues(a,this._matchRegexp,this._router.shouldTypecast),d},dispose:function(){this._router.removeRoute(this)},_destroy:function(){this.matched.dispose(),this.switched.dispose(),this.matched=this.switched=this._pattern=this._matchRegexp=null},toString:function(){return'[Route pattern:"'+this._pattern+'", numListeners:'+this.matched.getNumListeners()+"]"}},b.patternLexer=function(){function w(a,b){var c=[],d;while(d=a.exec(b))c.push(d[1]);return c}function x(a){return w(g,a)}function y(a){return w(f,a)}function z(c){return c=c||"",c&&(c=c.replace(b,""),c=A(c),c=c.replace(a,"\\$&"),c=B(c)),new RegExp("^"+c+"/?$")}function A(a){return a=a.replace(c,"$1"+p+"$2"),a=a.replace(d,"$1"+o+"$2"),a=a.replace(i,n),a=a.replace(h,m),a=a.replace(f,l),a.replace(e,k)}function B(a){return a=a.replace(u,"\\/?"),a=a.replace(v,"\\/"),a=a.replace(t,"(.*)?"),a=a.replace(s,"(.+)"),a=a.replace(r,"([^\\/]+)?/?"),a.replace(q,"([^\\/]+)")}function C(a,b,c){var d=b.exec(a);return d&&(d.shift(),c&&(d=j(d))),d}var a=/[\\.+*?\^$\[\](){}\/'#]/g,b=/\/$/g,c=/([:}]|\w(?=\/))\/?(:)/g,d=/([:}])\/?(\{)/g,e=/\{([^}]+)\}/g,f=/:([^:]+):/g,g=/(?:\{|:)([^}:]+)(?:\}|:)/g,h=/\{([^}]+)\*\}/g,i=/:([^:]+)\*:/g,k="__CR_RP__",l="__CR_OP__",m="__CR_RR__",n="__CR_OR__",o="__CR_RS__",p="__CR_OS__",q=new RegExp(k,"g"),r=new RegExp(l,"g"),s=new RegExp(m,"g"),t=new RegExp(n,"g"),u=new RegExp(p,"g"),v=new RegExp(o,"g");return{getParamIds:x,getOptionalParamsIds:y,getParamValues:C,compilePattern:z}}(),b})})(typeof define=="function"&&define.amd?define:function(a,b){typeof module!="undefined"&&module.exports?module.exports=b(require(a[0])):window.crossroads=b(window[a[0]])})
7
+ (function(a){a(["signals"],function(a){function d(a,b){if(a.indexOf)return a.indexOf(b);var c=a.length;while(c--)if(a[c]===b)return c;return-1}function e(a,b){return"[object "+b+"]"===Object.prototype.toString.call(a)}function f(a){return e(a,"RegExp")}function g(a){return e(a,"Array")}function h(a){return typeof a=="function"}function i(a){var b;return a===null||a==="null"?b=null:a==="true"?b=!0:a==="false"?b=!1:a===c||a==="undefined"?b=c:a===""||isNaN(a)?b=a:b=parseFloat(a),b}function j(a){var b=a.length,c=[];while(b--)c[b]=i(a[b]);return c}function k(a){var b=(a||"").replace("?","").split("&"),c=b.length,d={},e,f;while(c--)e=b[c].split("="),f=i(e[1]),d[e[0]]=typeof f=="string"?decodeURIComponent(f):f;return d}function l(){this._routes=[],this._prevRoutes=[],this.bypassed=new a.Signal,this.routed=new a.Signal}function m(c,d,e,g){var h=f(c),i=b.patternLexer;this._router=g,this._pattern=c,this._paramsIds=h?null:i.getParamIds(this._pattern),this._optionalParamsIds=h?null:i.getOptionalParamsIds(this._pattern),this._matchRegexp=h?c:i.compilePattern(c),this.matched=new a.Signal,this.switched=new a.Signal,d&&this.matched.add(d),this._priority=e||0}var b,c;return l.prototype={greedy:!1,greedyEnabled:!0,normalizeFn:null,create:function(){return new l},shouldTypecast:!1,addRoute:function(a,b,c){var d=new m(a,b,c,this);return this._sortedInsert(d),d},removeRoute:function(a){var b=d(this._routes,a);b!==-1&&this._routes.splice(b,1),a._destroy()},removeAllRoutes:function(){var a=this.getNumRoutes();while(a--)this._routes[a]._destroy();this._routes.length=0},parse:function(a,b){a=a||"",b=b||[];var c=this._getMatchedRoutes(a),d=0,e=c.length,f;if(e){this._notifyPrevRoutes(c,a),this._prevRoutes=c;while(d<e)f=c[d],f.route.matched.dispatch.apply(f.route.matched,b.concat(f.params)),f.isFirst=!d,this.routed.dispatch.apply(this.routed,b.concat([a,f])),d+=1}else this.bypassed.dispatch.apply(this.bypassed,b.concat([a]))},_notifyPrevRoutes:function(a,b){var c=0,d;while(d=this._prevRoutes[c++])d.route.switched&&this._didSwitch(d.route,a)&&d.route.switched.dispatch(b)},_didSwitch:function(a,b){var c,d=0;while(c=b[d++])if(c.route===a)return!1;return!0},getNumRoutes:function(){return this._routes.length},_sortedInsert:function(a){var b=this._routes,c=b.length;do--c;while(b[c]&&a._priority<=b[c]._priority);b.splice(c+1,0,a)},_getMatchedRoutes:function(a){var b=[],c=this._routes,d=c.length,e;while(e=c[--d]){(!b.length||this.greedy||e.greedy)&&e.match(a)&&b.push({route:e,params:e._getParamsArray(a)});if(!this.greedyEnabled&&b.length)break}return b},toString:function(){return"[crossroads numRoutes:"+this.getNumRoutes()+"]"}},b=new l,b.VERSION="0.9.0",b.NORM_AS_ARRAY=function(a,b){return[b.vals_]},b.NORM_AS_OBJECT=function(a,b){return[b]},m.prototype={greedy:!1,rules:void 0,match:function(a){return a=a||"",this._matchRegexp.test(a)&&this._validateParams(a)},_validateParams:function(a){var b=this.rules,c=this._getParamsObject(a),d;for(d in b)if(d!=="normalize_"&&b.hasOwnProperty(d)&&!this._isValidParam(a,d,c))return!1;return!0},_isValidParam:function(a,b,c){var e=this.rules[b],i=c[b],j=!1,k=b.indexOf("?")===0;return i==null&&this._optionalParamsIds&&d(this._optionalParamsIds,b)!==-1?j=!0:f(e)?(k&&(i=c[b+"_"]),j=e.test(i)):g(e)?(k&&(i=c[b+"_"]),j=d(e,i)!==-1):h(e)&&(j=e(i,a,c)),j},_getParamsObject:function(a){var c=this._router.shouldTypecast,d=b.patternLexer.getParamValues(a,this._matchRegexp,c),e={},f=d.length,g,h;while(f--)h=d[f],this._paramsIds&&(g=this._paramsIds[f],g.indexOf("?")===0&&h&&(e[g+"_"]=h,h=k(h),d[f]=h),e[g]=h),e[f]=h;return e.request_=c?i(a):a,e.vals_=d,e},_getParamsArray:function(a){var b=this.rules?this.rules.normalize_:null,c;return b=b||this._router.normalizeFn,b&&h(b)?c=b(a,this._getParamsObject(a)):c=this._getParamsObject(a).vals_,c},interpolate:function(a){var c=b.patternLexer.interpolate(this._pattern,a);if(!this._validateParams(c))throw new Error("Generated string doesn't validate against `Route.rules`.");return c},dispose:function(){this._router.removeRoute(this)},_destroy:function(){this.matched.dispose(),this.switched.dispose(),this.matched=this.switched=this._pattern=this._matchRegexp=null},toString:function(){return'[Route pattern:"'+this._pattern+'", numListeners:'+this.matched.getNumListeners()+"]"}},b.patternLexer=function(){function k(){var a,b;for(a in e)e.hasOwnProperty(a)&&(b=e[a],b.id="__CR_"+a+"__",b.save="save"in b?b.save.replace("{{id}}",b.id):b.id,b.rRestore=new RegExp(b.id,"g"))}function l(a,b){var c=[],d;while(d=a.exec(b))c.push(d[1]);return c}function m(a){return l(d,a)}function n(a){return l(e.OP.rgx,a)}function o(d){return d=d||"",d&&(i===f?d=d.replace(b,""):i===h&&(d=d.replace(c,"")),d=p(d,"rgx","save"),d=d.replace(a,"\\$&"),d=p(d,"rRestore","res"),i===f&&(d="\\/?"+d)),i!==g&&(d+="\\/?"),new RegExp("^"+d+"$")}function p(a,b,c){var d,f;for(f in e)e.hasOwnProperty(f)&&(d=e[f],a=a.replace(d[b],d[c]));return a}function q(a,b,c){var d=b.exec(a);return d&&(d.shift(),c&&(d=j(d))),d}function r(a,b){if(typeof a!="string")throw new Error("Route pattern should be a string.");var c=function(a,c){var d;if(c in b){d=b[c];if(a.indexOf("*")===-1&&d.indexOf("/")!==-1)throw new Error('Invalid value "'+d+'" for segment "'+a+'".')}else{if(a.indexOf("{")!==-1)throw new Error("The segment "+a+" is required.");d=""}return d};return e.OS.trail||(e.OS.trail=new RegExp("(?:"+e.OS.id+")+$")),a.replace(e.OS.rgx,e.OS.save).replace(d,c).replace(e.OS.trail,"").replace(e.OS.rRestore,"/")}var a=/[\\.+*?\^$\[\](){}\/'#]/g,b=/^\/|\/$/g,c=/\/$/g,d=/(?:\{|:)([^}:]+)(?:\}|:)/g,e={OS:{rgx:/([:}]|\w(?=\/))\/?(:|(?:\{\?))/g,save:"$1{{id}}$2",res:"\\/?"},RS:{rgx:/([:}])\/?(\{)/g,save:"$1{{id}}$2",res:"\\/"},RQ:{rgx:/\{\?([^}]+)\}/g,res:"\\?([^#]+)"},OQ:{rgx:/:\?([^:]+):/g,res:"(?:\\?([^#]*))?"},OR:{rgx:/:([^:]+)\*:/g,res:"(.*)?"},RR:{rgx:/\{([^}]+)\*\}/g,res:"(.+)"},RP:{rgx:/\{([^}]+)\}/g,res:"([^\\/?]+)"},OP:{rgx:/:([^:]+):/g,res:"([^\\/?]+)?/?"}},f=1,g=2,h=3,i=f;return k(),{strict:function(){i=g},loose:function(){i=f},legacy:function(){i=h},getParamIds:m,getOptionalParamsIds:n,getParamValues:q,compilePattern:o,interpolate:r}}(),b})})(typeof define=="function"&&define.amd?define:function(a,b){typeof module!="undefined"&&module.exports?module.exports=b(require(a[0])):window.crossroads=b(window[a[0]])})
metadata CHANGED
@@ -1,38 +1,48 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crossroadsjs-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
5
- prerelease:
4
+ prerelease:
5
+ version: 1.2.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Phil Ostler
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-12 00:00:00.000000000 Z
12
+ date: 2012-05-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: railties
16
- requirement: &21993624 !ruby/object:Gem::Requirement
16
+ version_requirements: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ~>
19
+ - !ruby/object:Gem::Version
20
+ version: '3.0'
17
21
  none: false
22
+ requirement: !ruby/object:Gem::Requirement
18
23
  requirements:
19
24
  - - ~>
20
25
  - !ruby/object:Gem::Version
21
26
  version: '3.0'
22
- type: :runtime
27
+ none: false
23
28
  prerelease: false
24
- version_requirements: *21993624
29
+ type: :runtime
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: rspec
27
- requirement: &21993312 !ruby/object:Gem::Requirement
32
+ version_requirements: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ~>
35
+ - !ruby/object:Gem::Version
36
+ version: '2.0'
28
37
  none: false
38
+ requirement: !ruby/object:Gem::Requirement
29
39
  requirements:
30
40
  - - ~>
31
41
  - !ruby/object:Gem::Version
32
42
  version: '2.0'
33
- type: :development
43
+ none: false
34
44
  prerelease: false
35
- version_requirements: *21993312
45
+ type: :development
36
46
  description: Provides Crossroads.js for use with Rails 3
37
47
  email: philostler@gmail.com
38
48
  executables: []
@@ -48,36 +58,37 @@ files:
48
58
  - README.md
49
59
  - vendor/assets/javascripts/crossroads.js
50
60
  - vendor/assets/javascripts/crossroads.min.js
61
+ - lib/crossroadsjs-rails.rb
62
+ - lib/crossroadsjs/rails.rb
51
63
  - lib/crossroadsjs/rails/engine.rb
52
64
  - lib/crossroadsjs/rails/railtie.rb
53
65
  - lib/crossroadsjs/rails/version.rb
54
- - lib/crossroadsjs/rails.rb
55
- - lib/crossroadsjs-rails.rb
56
66
  - lib/generators/crossroadsjs/install/install_generator.rb
57
- - spec/crossroadsjs/rails/version_spec.rb
58
67
  - spec/spec_helper.rb
68
+ - spec/crossroadsjs/rails/version_spec.rb
59
69
  homepage: http://github.com/philostler/crossroadsjs-rails
60
70
  licenses: []
61
- post_install_message:
71
+ post_install_message:
62
72
  rdoc_options: []
63
73
  require_paths:
64
74
  - lib
65
75
  required_ruby_version: !ruby/object:Gem::Requirement
66
- none: false
67
76
  requirements:
68
77
  - - ! '>='
69
78
  - !ruby/object:Gem::Version
70
79
  version: '0'
71
- required_rubygems_version: !ruby/object:Gem::Requirement
72
80
  none: false
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
82
  requirements:
74
83
  - - ! '>='
75
84
  - !ruby/object:Gem::Version
76
85
  version: '0'
86
+ none: false
77
87
  requirements: []
78
- rubyforge_project:
79
- rubygems_version: 1.8.16
80
- signing_key:
88
+ rubyforge_project:
89
+ rubygems_version: 1.8.24
90
+ signing_key:
81
91
  specification_version: 3
82
92
  summary: Crossroads.js for Rails
83
93
  test_files: []
94
+ ...