joosy 1.2.0.alpha.64 → 1.2.0.alpha.65

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0823adf3077e02d1d72bf7dda25eca2619f6af2b
4
- data.tar.gz: 93a63a4a7a5ddb792667df29374155773fd28ea9
3
+ metadata.gz: 7b17df9ece3872cfea75fb7a050d5258691fe806
4
+ data.tar.gz: 9d1a40dcd0816133a7f7b7b4a292b381d8850d8b
5
5
  SHA512:
6
- metadata.gz: 1307d42fe3cbb35e2a14b072c735122dfadcbdb3027384b1e63c692f61ec4860704c2ae3a4d0c8be500175c41c65b752540a6416b21320c1497802200f5e542d
7
- data.tar.gz: b0610530a29bcd99bf4abfeda87f4cbb670011b137ecbc7e5b7c6076d4e095d8f125bc0a51a751646cccb9a785e4e61bac0bcc94d2fcdf911673975c7336f0d3
6
+ metadata.gz: f25cc66bcc9c37df768236f01cfde7d426938755aa84d6708d4c15cab770cf37d3ee450062b7d763f23ffc8fe057a060000ecba28a53f8e169130d36285739b4
7
+ data.tar.gz: 30b5ec47a529211643b2f599e68cf13e9506026e0b0b375585009422fb596c66a262669fd2100a6fa985d08d4c62b2fb99edc8a6b7650f3cc215f698ac7f7f4b
data/Gruntfile.coffee CHANGED
@@ -1,101 +1,93 @@
1
1
  require 'sugar'
2
2
 
3
- Mincer = require 'mincer'
4
3
  semver = require 'semver'
5
4
 
6
5
  module.exports = (grunt) ->
7
6
  #
8
7
  # Common settings
9
8
  #
10
- locations =
11
-
12
- source:
13
- root: 'joosy.coffee'
14
- path: 'source'
15
- build: 'build/joosy.js'
16
-
17
- extensions: (name) ->
18
- root: "joosy/extensions/#{name || '*'}"
19
- build: "build/joosy/extensions/#{name || '**/*'}.js"
20
-
21
- specs: [
22
- 'bower_components/sinonjs/sinon.js',
23
- 'bower_components/sugar/release/sugar-full.min.js',
24
- 'spec/helpers/*.coffee'
25
- ]
26
-
27
- testem =
28
- parallel: 8
29
- launch_in_dev: ['PhantomJS'],
30
- launch_in_ci: ['PhantomJS', 'Chrome', 'Firefox', 'Safari', 'IE7', 'IE8', 'IE9']
9
+ testemOptions = (vendor, specs) ->
10
+ return {
11
+ src: Array.create([
12
+ 'bower_components/sinonjs/sinon.js',
13
+ 'bower_components/sugar/release/sugar-full.min.js',
14
+ 'spec/helpers/*.coffee'
15
+ ], vendor, 'joosy.coffee', specs)
16
+ assets:
17
+ setup: ->
18
+ grunt.grill.assetter('development').environment
19
+ options:
20
+ parallel: 8
21
+ launch_in_dev: ['PhantomJS'],
22
+ launch_in_ci: ['PhantomJS', 'Chrome', 'Firefox', 'Safari', 'IE7', 'IE8', 'IE9']
23
+ }
31
24
 
32
25
  #
33
26
  # Grunt extensions
34
27
  #
28
+ grunt.loadNpmTasks 'grill'
35
29
  grunt.loadNpmTasks 'grunt-contrib-testem'
36
30
  grunt.loadNpmTasks 'grunt-coffeelint'
37
31
  grunt.loadNpmTasks 'grunt-release'
32
+ grunt.loadNpmTasks 'grunt-gh-pages'
38
33
 
39
34
  #
40
35
  # Config
41
36
  #
42
37
  grunt.initConfig
43
- mince:
44
- core:
45
- include: [locations.source.path]
46
- src: locations.source.root
47
- dest: locations.source.build
48
- resources:
49
- include: [locations.source.path]
50
- src: locations.source.extensions('resources').root
51
- dest: locations.source.extensions('resources').build
52
- form:
53
- include: [locations.source.path]
54
- src: locations.source.extensions('resources-form').root
55
- dest: locations.source.extensions('resources-form').build
38
+ grill:
39
+ assets:
40
+ destination: 'build'
41
+ paths: 'source'
42
+ root: ['joosy.coffee', 'joosy/extensions/*']
56
43
 
57
44
  coffeelint:
58
45
  source:
59
46
  files:
60
- src: [locations.source.path + '/joosy/**/*.coffee']
47
+ src: 'source/joosy/**/*.coffee'
61
48
  options:
62
49
  'max_line_length':
63
50
  level: 'ignore'
64
51
 
52
+ 'gh-pages':
53
+ docs:
54
+ options:
55
+ add: true
56
+ clone: 'doc'
57
+ command:
58
+ cmd: 'grunt'
59
+ args: ['doc']
60
+
65
61
  testem:
66
- core:
67
- src: locations.specs
68
- .include('bower_components/jquery/jquery.js')
69
- .include(locations.source.build)
70
- .include('spec/joosy/core/**/*_spec.coffee')
71
- options: testem
72
- zepto:
73
- src: locations.specs
74
- .include('bower_components/zepto/zepto.js')
75
- .include(locations.source.build)
76
- .include('spec/joosy/core/**/*_spec.coffee')
77
- options: testem
78
- 'environments-global':
79
- src: locations.specs
80
- .include('bower_components/jquery/jquery.js')
81
- .include(locations.source.build)
82
- .include('spec/joosy/environments/global_spec.coffee')
83
- options: testem
84
- 'environments-amd':
85
- src: locations.specs
86
- .include('bower_components/jquery/jquery.js')
87
- .include('bower_components/requirejs/require.js')
88
- .include(locations.source.build)
89
- .include('spec/joosy/environments/amd_spec.coffee')
90
- options: testem
91
- extensions:
92
- src: locations.specs
93
- .include('bower_components/jquery/jquery.js')
94
- .include(locations.source.build)
95
- .include('bower_components/jquery-form/jquery.form.js')
96
- .include(locations.source.extensions().build)
97
- .include('spec/joosy/extensions/**/*_spec.coffee')
98
- options: testem
62
+ core: testemOptions(
63
+ 'bower_components/jquery/jquery.js',
64
+ 'spec/joosy/core/**/*_spec.coffee'
65
+ )
66
+ zepto: testemOptions(
67
+ 'bower_components/zepto/zepto.js',
68
+ 'spec/joosy/core/**/*_spec.coffee'
69
+ )
70
+ 'environments-global': testemOptions(
71
+ 'bower_components/jquery/jquery.js',
72
+ 'spec/joosy/environments/global_spec.coffee'
73
+ )
74
+ 'environments-amd': testemOptions(
75
+ [
76
+ 'bower_components/jquery/jquery.js',
77
+ 'bower_components/requirejs/require.js'
78
+ ],
79
+ 'spec/joosy/environments/amd_spec.coffee'
80
+ )
81
+ extensions: testemOptions(
82
+ [
83
+ 'bower_components/jquery/jquery.js',
84
+ 'bower_components/jquery-form/jquery.form.js'
85
+ ],
86
+ [
87
+ 'joosy/extensions/*',
88
+ 'spec/joosy/extensions/**/*_spec.coffee'
89
+ ]
90
+ )
99
91
 
100
92
  release:
101
93
  options:
@@ -109,21 +101,24 @@ module.exports = (grunt) ->
109
101
  #
110
102
  grunt.registerTask 'default', 'testem'
111
103
 
104
+ grunt.registerTask 'build', 'grill:compile'
105
+
112
106
  grunt.registerTask 'test', ->
107
+ grunt.task.run 'coffeelint'
113
108
  grunt.task.run if @args[0] then "testem:run:#{@args[0]}" else 'testem'
114
109
 
115
- grunt.registerTask 'publish', ['testem', 'publish:ensureCommits', 'doc', 'release', 'publish:gem']
116
-
110
+ grunt.registerTask 'publish', [
111
+ 'test',
112
+ 'build',
113
+ 'ensureCommits',
114
+ 'gh-pages',
115
+ 'release',
116
+ 'gemify'
117
+ ]
117
118
 
118
119
  #
119
120
  # Building
120
121
  #
121
- grunt.registerMultiTask 'mince', ->
122
- Mincer.CoffeeEngine.configure bare: false
123
- environment = new Mincer.Environment
124
- environment.appendPath x for x in @data.include
125
- grunt.file.write @data.dest, environment.findAsset(@data.src).toString()
126
-
127
122
  grunt.registerTask 'bowerize', ->
128
123
  bower = require './bower.json'
129
124
  meta = require './package.json'
@@ -134,7 +129,7 @@ module.exports = (grunt) ->
134
129
  #
135
130
  # Publishing
136
131
  #
137
- grunt.registerTask 'publish:ensureCommits', ->
132
+ grunt.registerTask 'ensureCommits', ->
138
133
  complete = @async()
139
134
 
140
135
  grunt.util.spawn {cmd: "git", args: ["status", "--porcelain" ]}, (error, result) ->
@@ -146,7 +141,7 @@ module.exports = (grunt) ->
146
141
  else
147
142
  complete true
148
143
 
149
- grunt.registerTask 'publish:gem', ->
144
+ grunt.registerTask 'gemify', ->
150
145
  meta = require './package.json'
151
146
  complete = @async()
152
147
 
@@ -165,79 +160,40 @@ module.exports = (grunt) ->
165
160
  #
166
161
  # Documentation
167
162
  #
168
- grunt.registerTask 'doc', ['doc:prepare', 'doc:generate']
169
-
170
- grunt.registerTask 'doc:generate', ->
163
+ grunt.registerTask 'doc', ->
171
164
  complete = @async()
172
- version = JSON.parse(grunt.file.read 'package.json').version.split('-')
173
- version = version[0]+'-'+version[1]?.split('.')[0]
174
- destination = "doc/#{version}"
175
- args = ['source', '--output-dir', destination]
176
165
 
177
- git = (args, callback) ->
178
- grunt.util.spawn {cmd: "git", args: args, opts: {stdio: [0,1,2], cwd: 'doc'}}, callback
166
+ version = require('./package.json').version.split('-')
167
+ version = version[0]+'-'+version[1]?.split('.')[0]
168
+ destination = "doc/#{version}"
179
169
 
180
170
  date = (version) ->
181
171
  return undefined unless version
182
172
  Date.create(grunt.file.read "doc/#{version}/DATE").format "{d} {Month} {yyyy}"
183
173
 
184
- git ['pull'], (error, result) ->
185
- grunt.fatal "Error pulling from git" if error
186
-
187
- grunt.file.delete destination if grunt.file.exists destination
188
- grunt.util.spawn {cmd: "codo", args: args, opts: {stdio: [0,1,2]}}, (error, result) ->
189
- grunt.fatal "Error generating docs" if error
190
- grunt.file.write "#{destination}/DATE", (new Date).toISOString()
191
-
192
- versions = []
193
- for version in grunt.file.expand({cwd: 'doc'}, '*')
194
- versions.push version if semver.valid(version)
195
-
196
- versions = versions.sort(semver.rcompare)
197
- edge = versions.find (x) -> x.has('-')
198
- stable = versions.find (x) -> !x.has('-')
199
- versions = versions.remove edge, stable
200
-
201
- versions = {
202
- edge:
203
- version: edge
204
- date: date(edge)
205
- stable:
206
- version: stable
207
- date: date(stable)
208
- versions: versions.map (x) -> { version: x, date: date(x) }
209
- }
210
- grunt.file.write 'doc/versions.js', "window.versions = #{JSON.stringify(versions)}"
211
-
212
- git ['add', '-A'], (error, result) ->
213
- grunt.fatal "Error adding files" if error
214
-
215
- git ['commit', '-m', "Updated at #{(new Date).toISOString()}"], (error, result) ->
216
- grunt.fatal "Error commiting" if error
217
-
218
- git ['push', 'origin', 'gh-pages'], (error, result) ->
219
- grunt.fatal "Error pushing" if error
220
- complete()
221
-
222
- grunt.registerTask 'doc:prepare', ->
223
- if grunt.file.exists 'doc'
224
- unless grunt.file.exists 'doc/.git'
225
- grunt.fatal "Documentation directory exists. Please remove it"
226
- else
227
- return
228
-
229
- complete = @async()
230
-
231
- base = process.cwd()
232
- git = (args, callback) ->
233
- grunt.util.spawn {cmd: "git", args: args, opts: {stdio: [0,1,2]}}, callback
234
-
235
- git ["clone", "git@github.com:joosy/joosy.git", "doc"], (error, result) ->
236
- grunt.fatal "Erorr cloning repo" if error
237
- process.chdir 'doc'
238
-
239
- git ["checkout", "gh-pages"], (error, result) ->
240
- grunt.fatal "Erorr checking branch out" if error
241
-
242
- process.chdir base
243
- complete()
174
+ args = ['source', '--output-dir', destination]
175
+ grunt.file.delete destination if grunt.file.exists destination
176
+
177
+ grunt.util.spawn {cmd: "codo", args: args, opts: {stdio: [0,1,2]}}, (error, result) ->
178
+ grunt.fatal "Error generating docs" if error
179
+ grunt.file.write "#{destination}/DATE", (new Date).toISOString()
180
+
181
+ versions = []
182
+ for version in grunt.file.expand({cwd: 'doc'}, '*')
183
+ versions.push version if semver.valid(version)
184
+
185
+ versions = versions.sort(semver.rcompare)
186
+ edge = versions.filter((x) -> x.has('-')).first()
187
+ stable = versions.filter((x) -> !x.has('-')).first()
188
+ versions = versions.remove edge, stable
189
+
190
+ versions = {
191
+ edge:
192
+ version: edge
193
+ date: date(edge)
194
+ stable:
195
+ version: stable
196
+ date: date(stable)
197
+ versions: versions.map (x) -> { version: x, date: date(x) }
198
+ }
199
+ grunt.file.write 'doc/versions.js', "window.versions = #{JSON.stringify(versions)}"
data/README.md CHANGED
@@ -87,8 +87,8 @@ You assets are at `public/` directory, enjoy!
87
87
  * Clone the project
88
88
  * Run `npm install` to get required Node modules
89
89
  * Run `bower install` to get required JS components
90
- * Run `grunt test` to run specs once
91
- * Run `grunt` to watch sources (automatic changes compilations) and run test-server (get your browser to http://localhost:8888/)
90
+ * Run `grunt test` to run all specs in all available browsers
91
+ * Run `grunt test:*` where `*` is then name of an environment to run the environment in the development mode. Check `Gruntfile.coffee` (section **testem**) for the list of existing environments.
92
92
 
93
93
  While current repository is at the same time NPM package, Ruby gem and Bower component, – the main Core
94
94
  environment is Node.js.
data/bower.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "joosy",
3
- "version": "1.2.0-alpha.64",
3
+ "version": "1.2.0-alpha.65",
4
4
  "main": "build/joosy.js",
5
5
  "ignore": [
6
6
  "lib",
@@ -370,6 +370,58 @@
370
370
 
371
371
  })(Joosy.Module);
372
372
 
373
+ }).call(this);
374
+ (function() {
375
+ var _ref,
376
+ __hasProp = {}.hasOwnProperty,
377
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
378
+ __slice = [].slice;
379
+
380
+ Joosy.Resources.RESTCollection = (function(_super) {
381
+ __extends(RESTCollection, _super);
382
+
383
+ function RESTCollection() {
384
+ _ref = RESTCollection.__super__.constructor.apply(this, arguments);
385
+ return _ref;
386
+ }
387
+
388
+ RESTCollection.include(Joosy.Modules.Log);
389
+
390
+ RESTCollection.include(Joosy.Modules.Events);
391
+
392
+ RESTCollection.prototype.reload = function(options, callback) {
393
+ var _this = this;
394
+ if (options == null) {
395
+ options = {};
396
+ }
397
+ if (callback == null) {
398
+ callback = false;
399
+ }
400
+ if (Object.isFunction(options)) {
401
+ callback = options;
402
+ options = {};
403
+ }
404
+ return this.model.__query(this.model.collectionPath(options, this.__source), 'GET', options.params, function(data) {
405
+ _this.load(data);
406
+ return typeof callback === "function" ? callback(data) : void 0;
407
+ });
408
+ };
409
+
410
+ RESTCollection.prototype.load = function() {
411
+ var args, res,
412
+ _this = this;
413
+ args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
414
+ res = RESTCollection.__super__.load.apply(this, args);
415
+ this.data.each(function(x) {
416
+ return x.__source = _this.__source;
417
+ });
418
+ return res;
419
+ };
420
+
421
+ return RESTCollection;
422
+
423
+ })(Joosy.Resources.Collection);
424
+
373
425
  }).call(this);
374
426
  (function() {
375
427
  var _ref,
@@ -651,58 +703,6 @@
651
703
 
652
704
  })(Joosy.Resources.Base);
653
705
 
654
- }).call(this);
655
- (function() {
656
- var _ref,
657
- __hasProp = {}.hasOwnProperty,
658
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
659
- __slice = [].slice;
660
-
661
- Joosy.Resources.RESTCollection = (function(_super) {
662
- __extends(RESTCollection, _super);
663
-
664
- function RESTCollection() {
665
- _ref = RESTCollection.__super__.constructor.apply(this, arguments);
666
- return _ref;
667
- }
668
-
669
- RESTCollection.include(Joosy.Modules.Log);
670
-
671
- RESTCollection.include(Joosy.Modules.Events);
672
-
673
- RESTCollection.prototype.reload = function(options, callback) {
674
- var _this = this;
675
- if (options == null) {
676
- options = {};
677
- }
678
- if (callback == null) {
679
- callback = false;
680
- }
681
- if (Object.isFunction(options)) {
682
- callback = options;
683
- options = {};
684
- }
685
- return this.model.__query(this.model.collectionPath(options, this.__source), 'GET', options.params, function(data) {
686
- _this.load(data);
687
- return typeof callback === "function" ? callback(data) : void 0;
688
- });
689
- };
690
-
691
- RESTCollection.prototype.load = function() {
692
- var args, res,
693
- _this = this;
694
- args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
695
- res = RESTCollection.__super__.load.apply(this, args);
696
- this.data.each(function(x) {
697
- return x.__source = _this.__source;
698
- });
699
- return res;
700
- };
701
-
702
- return RESTCollection;
703
-
704
- })(Joosy.Resources.Collection);
705
-
706
706
  }).call(this);
707
707
  (function() {
708
708
 
data/build/joosy.js CHANGED
@@ -1959,17 +1959,20 @@
1959
1959
  respond = true;
1960
1960
  }
1961
1961
  if (!history.pushState) {
1962
+ this.config.prefix = this.config.hashSuffix;
1962
1963
  this.config.html5 = false;
1963
1964
  }
1965
+ if (!this.config.html5) {
1966
+ this.config.prefix = this.config.hashSuffix;
1967
+ }
1964
1968
  (_base = this.config).prefix || (_base.prefix = '');
1965
1969
  if (this.config.html5) {
1966
1970
  this.config.prefix = ('/' + this.config.prefix + '/').replace(/\/{2,}/g, '/');
1967
- }
1968
- if (this.config.html5) {
1969
1971
  this.listener = this.bind('popstate pushstate', function() {
1970
1972
  return _this.respond(_this.canonizeLocation());
1971
1973
  });
1972
1974
  } else {
1975
+ this.config.prefix = this.config.prefix.replace(/^\#?\/?/, '').replace(/\/?$/, '');
1973
1976
  $(window).bind('hashchange.JoosyRouter', function() {
1974
1977
  return _this.respond(_this.canonizeLocation());
1975
1978
  });
@@ -1997,31 +2000,24 @@
1997
2000
  }
1998
2001
  path = to;
1999
2002
  if (this.config.html5) {
2000
- if (path[0] === '/') {
2001
- path = path.substr(1);
2002
- }
2003
- path = this.config.prefix + path;
2004
- } else {
2005
- if (path[0] === '#') {
2006
- path = path.substr(1);
2003
+ if (this.config.prefix && path[0] === '/' && !path.match(RegExp("^" + (this.config.prefix.replace(/\/$/, '')) + "(/|$)"))) {
2004
+ path = path.replace(/^\//, this.config.prefix);
2007
2005
  }
2008
- if (this.config.prefix && !path.startsWith(this.config.prefix)) {
2009
- path = this.config.prefix + path;
2010
- }
2011
- }
2012
- if (this.config.html5) {
2013
2006
  history.pushState({}, '', path);
2014
2007
  this.trigger('pushstate');
2015
2008
  } else {
2009
+ if (this.config.prefix && !path.match(RegExp("^#?/?" + this.config.prefix + "(/|$)"))) {
2010
+ path = path.replace(/^\#?\/?/, "" + this.config.prefix + "/");
2011
+ }
2016
2012
  location.hash = path;
2017
2013
  }
2018
2014
  };
2019
2015
 
2020
2016
  Router.canonizeLocation = function() {
2021
2017
  if (this.config.html5) {
2022
- return location.pathname.replace(RegExp("^" + (RegExp.escape(this.config.prefix)) + "?"), '/') + location.search;
2018
+ return location.pathname.replace(RegExp("^(" + this.config.prefix + "?)?/?"), '/') + location.search;
2023
2019
  } else {
2024
- return location.hash.replace(RegExp("^\\#(" + this.config.prefix + ")?\\/?"), '/');
2020
+ return location.hash.replace(RegExp("^#?/?(" + this.config.prefix + "(/|$))?"), '/');
2025
2021
  }
2026
2022
  };
2027
2023
 
data/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "keywords": [
5
5
  "joosy"
6
6
  ],
7
- "version": "1.2.0-alpha.64",
7
+ "version": "1.2.0-alpha.65",
8
8
  "author": "Boris Staal <boris@staal.io>",
9
9
  "homepage": "http://joosy.ws/",
10
10
  "repository": {
@@ -20,11 +20,11 @@
20
20
  "devDependencies": {
21
21
  "coffee-script": "~1.6.3",
22
22
  "sugar": "~1.3.8",
23
- "bower": "~1.1.2",
24
- "mincer": ">= 0.5.5",
23
+ "bower": "~1.2.1",
25
24
  "semver": "~2.1.0",
26
25
  "grunt-coffeelint": "0.0.6",
27
26
  "grunt-release": "~0.3.5",
28
- "grunt-contrib-testem": ">=0.2.0"
27
+ "grunt-contrib-testem": ">=0.4.0",
28
+ "grunt-gh-pages": "git+https://github.com/inossidabile/grunt-gh-pages.git"
29
29
  }
30
30
  }
@@ -1,5 +1,5 @@
1
1
  #= require ./base
2
- #= require ./collection
2
+ #= require ./rest_collection
3
3
 
4
4
  #
5
5
  # Resource with REST/JSON backend
@@ -125,15 +125,28 @@ class Joosy.Router extends Joosy.Module
125
125
  # Inits the routing system and loads the current route
126
126
  #
127
127
  @setup: (@config, @responder, respond=true) ->
128
- @config.html5 = false unless history.pushState
128
+ # Fallback to hashchange if we are unlucky
129
+ # enough to work in IE...
130
+ unless history.pushState
131
+ @config.prefix = @config.hashSuffix
132
+ @config.html5 = false
133
+
134
+ # ... or for some reason it was explicitly turned off
135
+ unless @config.html5
136
+ @config.prefix = @config.hashSuffix
137
+
129
138
  @config.prefix ||= ''
130
- @config.prefix = ('/'+@config.prefix+'/').replace(/\/{2,}/g, '/') if @config.html5
131
139
 
132
140
  if @config.html5
141
+ # Canonical form of HTML5 prefix is '/any/thing/'
142
+ @config.prefix = ('/'+@config.prefix+'/').replace /\/{2,}/g, '/'
143
+
133
144
  @listener = @bind 'popstate pushstate', =>
134
145
  @respond @canonizeLocation()
135
-
136
146
  else
147
+ # Canonical form of hash suffix is 'any/thing'
148
+ @config.prefix = @config.prefix.replace(/^\#?\/?/, '').replace /\/?$/, ''
149
+
137
150
  $(window).bind 'hashchange.JoosyRouter', =>
138
151
  @respond @canonizeLocation()
139
152
 
@@ -169,19 +182,16 @@ class Joosy.Router extends Joosy.Module
169
182
  path = to
170
183
 
171
184
  if @config.html5
172
- path = path.substr(1) if path[0] == '/'
173
- path = @config.prefix+path
174
- else
175
- path = path.substr(1) if path[0] == '#'
176
-
177
- if @config.prefix && !path.startsWith(@config.prefix)
178
- path = @config.prefix + path
179
-
180
- if @config.html5
185
+ # omit html5 relative links
186
+ if @config.prefix && path[0] == '/' && !path.match(RegExp("^#{@config.prefix.replace(/\/$/, '')}(/|$)"))
187
+ path = path.replace /^\//, @config.prefix
181
188
  history.pushState {}, '', path
182
189
  @trigger 'pushstate'
183
190
  else
191
+ if @config.prefix && !path.match(RegExp("^#?/?#{@config.prefix}(/|$)"))
192
+ path = path.replace /^\#?\/?/, "#{@config.prefix}/"
184
193
  location.hash = path
194
+
185
195
  return
186
196
 
187
197
  #
@@ -191,9 +201,9 @@ class Joosy.Router extends Joosy.Module
191
201
  #
192
202
  @canonizeLocation: ->
193
203
  if @config.html5
194
- location.pathname.replace(///^#{RegExp.escape @config.prefix}?///, '/')+location.search
204
+ location.pathname.replace(RegExp("^(#{@config.prefix}?)?/?"), '/')+location.search
195
205
  else
196
- location.hash.replace ///^\#(#{@config.prefix})?\/?///, '/'
206
+ location.hash.replace RegExp("^#?/?(#{@config.prefix}(/|$))?"), '/'
197
207
 
198
208
  #
199
209
  # Compiles one single route
@@ -277,6 +277,41 @@ describe "Joosy.Router", ->
277
277
  expect(Joosy.Helpers.Routes.sectionPagePath(id: 1)).toEqual '/section/page/1'
278
278
  expect(Joosy.Helpers.Routes.sectionPageUrl(id: 1)).toEqual "http://#{location.host}/section/page/1"
279
279
 
280
+ for name, val of { html5: true, hash: false }
281
+ do(name, val) ->
282
+ describe "#{name} prefix", ->
283
+ afterEach ->
284
+ Joosy.Router.reset()
285
+ location.hash = ''
286
+ history.pushState {}, '', pathname
287
+ waits 0
288
+
289
+ beforeEach ->
290
+ Joosy.Router.setup {html5: val, prefix: 'admin', hashSuffix: 'admin'}, @spies.responder, false
291
+ Joosy.Router.map @map
292
+
293
+ it "is considered in path without prefix", ->
294
+ runs -> Joosy.Router.navigate '/base'
295
+ waits 0
296
+ runs ->
297
+ expect(@spies.responder.callCount).toEqual 1
298
+ expect(@spies.responder.args[0][0]).toEqual @spies.base
299
+
300
+ it "is considered in path with prefix", ->
301
+ runs -> Joosy.Router.navigate '/admin/base'
302
+ waits 0
303
+ runs ->
304
+ expect(@spies.responder.callCount).toEqual 1
305
+ expect(@spies.responder.args[0][0]).toEqual @spies.base
306
+
307
+ it "is considered in root path", ->
308
+ runs -> Joosy.Router.navigate '/admin'
309
+ waits 0
310
+ runs ->
311
+ expect(@spies.responder.callCount).toEqual 1
312
+ expect(@spies.responder.args[0][0]).toEqual @spies.root
313
+
314
+
280
315
  describe 'linker', ->
281
316
  it 'defines helper', ->
282
317
  tag = Joosy.Helpers.Routes.linkTo 'test', '/base', class: 'zomg!'
@@ -1,9 +1,11 @@
1
1
  {
2
2
  "dependencies": {
3
3
  "joosy": "<%= joosy %>",
4
- "haml-coffee": "~1.11.1",
5
- "stylus": "~0.32.1",
6
- "nib": "~0.9.1",
4
+
5
+ "haml-coffee": "~1.11.4",
6
+ "stylus": "~0.37.0",
7
+ "nib": "~1.0.0",
8
+
7
9
  "grunt": "~0.4.1",
8
10
  "grunt-cli": "~0.1.9",
9
11
  "grunt-contrib-uglify": "~0.2.2",
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: joosy
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0.alpha.64
4
+ version: 1.2.0.alpha.65
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boris Staal
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-08-21 00:00:00.000000000 Z
13
+ date: 2013-08-27 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: sprockets