crossroadsjs-rails 1.1.0 → 1.2.0

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/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
+ ...