spine_paginator 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ # gem
2
+ *.gem
3
+ *.rbc
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+
20
+ # npm
21
+ *.swp
22
+ node_modules/**/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in spine_paginator.gemspec
4
+ gemspec
data/Gruntfile.coffee ADDED
@@ -0,0 +1,52 @@
1
+ module.exports = (grunt) ->
2
+ grunt.initConfig
3
+ pkg: grunt.file.readJSON('package.json')
4
+
5
+ meta:
6
+ banner:
7
+ '// spine.paginator.js\n' +
8
+ '// version: <%= pkg.version %>\n' +
9
+ '// author: <%= pkg.author %>\n' +
10
+ '// license: <%= pkg.licenses[0].type %>\n'
11
+
12
+ coffee:
13
+ all:
14
+ files:
15
+ 'dist/spine.paginator.js': 'src/spine.paginator.coffee'
16
+
17
+ concat:
18
+ all:
19
+ options:
20
+ banner: '<%= meta.banner %>'
21
+ files:
22
+ 'dist/spine.paginator.js': 'dist/spine.paginator.js'
23
+
24
+ uglify:
25
+ all:
26
+ options:
27
+ banner: '<%= meta.banner %>'
28
+ report: 'gzip'
29
+ files:
30
+ 'dist/spine.paginator.min.js': 'dist/spine.paginator.js'
31
+
32
+ jasmine:
33
+ all:
34
+ src: 'dist/spine.paginator.js'
35
+ options:
36
+ specs: 'spec/spine.paginator/**/*.js'
37
+ helpers: 'spec/lib/**/*.js'
38
+
39
+ watch:
40
+ all:
41
+ files: 'src/spine.paginator.coffee'
42
+ tasks: ['build', 'spec']
43
+
44
+ grunt.loadNpmTasks 'grunt-contrib-coffee'
45
+ grunt.loadNpmTasks 'grunt-contrib-concat'
46
+ grunt.loadNpmTasks 'grunt-contrib-uglify'
47
+ grunt.loadNpmTasks 'grunt-contrib-jasmine'
48
+ grunt.loadNpmTasks 'grunt-contrib-watch'
49
+
50
+ grunt.registerTask 'default', ['watch']
51
+ grunt.registerTask 'spec', ['jasmine']
52
+ grunt.registerTask 'build', ['coffee', 'concat', 'uglify']
data/LICENSE-MIT ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 vkill
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 vkill
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # SpinePaginator
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'spine_paginator'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install spine_paginator
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/component.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "spine.paginator",
3
+ "repo": "vkill/spine_paginator",
4
+ "description": "Paginator for Spine.",
5
+ "version": "0.1.0",
6
+ "keywords": [
7
+ "paginator",
8
+ "spine",
9
+ "pagination"
10
+ ],
11
+ "scripts": [
12
+ "dist/spine.paginator.js"
13
+ ],
14
+ "main": "dist/spine.paginator.js",
15
+ "license": "MIT",
16
+ "ignore": [
17
+ "**/.*",
18
+ "node_modules",
19
+ "components"
20
+ ]
21
+ }
data/dist/.gitkeep ADDED
File without changes
@@ -0,0 +1,271 @@
1
+ // spine.paginator.js
2
+ // version: 0.1.0
3
+ // author: vkill
4
+ // license: MIT
5
+ (function() {
6
+ var Extend, Model, Paginator, Spine;
7
+
8
+ Spine = this.Spine || require('spine');
9
+
10
+ Model = Spine.Model;
11
+
12
+ Paginator = (function() {
13
+ Paginator.DEFAULT_PER_PAGE = 25;
14
+
15
+ Paginator.MAX_PER_PAGE = null;
16
+
17
+ Paginator.WINDOW = 4;
18
+
19
+ Paginator.OUTER_WINDOW = 0;
20
+
21
+ Paginator.LEFT = 0;
22
+
23
+ Paginator.RIGHT = 0;
24
+
25
+ function Paginator(records, _page, options) {
26
+ var outer_window;
27
+
28
+ this._page = _page;
29
+ if (options == null) {
30
+ options = {};
31
+ }
32
+ this._page = parseInt(this._page);
33
+ if (isNaN(this._page) || this._page <= 0) {
34
+ this._page = 1;
35
+ }
36
+ this._originalPage = this._page;
37
+ this.perPage = options.perPage || this.constructor.DEFAULT_PER_PAGE;
38
+ this.perPage = parseInt(this.perPage);
39
+ if (isNaN(this.perPage) || this.perPage <= 0) {
40
+ this.perPage = this.constructor.DEFAULT_PER_PAGE;
41
+ }
42
+ this.maxPerPage = options.maxPerPage || this.constructor.MAX_PER_PAGE;
43
+ this.window = options.window || options.inner_window || this.constructor.WINDOW;
44
+ outer_window = options.outer_window || this.constructor.OUTER_WINDOW;
45
+ this.left = options.left || this.constructor.LEFT;
46
+ if (this.left === 0) {
47
+ this.left = outer_window;
48
+ }
49
+ this.right = options.right || this.constructor.RIGHT;
50
+ if (this.right === 0) {
51
+ this.right = outer_window;
52
+ }
53
+ this.originalRecords = this.cloneArray(records);
54
+ this.totalCount = this.originalRecords.length;
55
+ this.skipbuildButtonsAndLocals = options.skipbuildButtonsAndLocals;
56
+ this.records = [];
57
+ this.buttons = [];
58
+ this.locals = {};
59
+ this.per();
60
+ }
61
+
62
+ Paginator.prototype.per = function(num) {
63
+ var fromN, n, toN;
64
+
65
+ n = parseInt(num);
66
+ if (!isNaN(n) && n > 0) {
67
+ this.perPage = n;
68
+ this._page = this._originalPage;
69
+ }
70
+ fromN = this.offsetValue();
71
+ toN = fromN + this.limitValue();
72
+ this.records = this.originalRecords.slice(fromN, toN);
73
+ if (this.skipbuildButtonsAndLocals == null) {
74
+ this.buildButtonsAndLocals();
75
+ }
76
+ return this;
77
+ };
78
+
79
+ Paginator.prototype.totalPages = function() {
80
+ return Math.ceil(this.totalCount / this.limitValue());
81
+ };
82
+
83
+ Paginator.prototype.currentPage = function() {
84
+ if (this.limitValue() == null) {
85
+ return this.firstPage();
86
+ }
87
+ return (this.offsetValue() / this.limitValue()) + 1;
88
+ };
89
+
90
+ Paginator.prototype.firstPage = function() {
91
+ return 1;
92
+ };
93
+
94
+ Paginator.prototype.isFirstPage = function() {
95
+ return this.currentPage() === this.firstPage();
96
+ };
97
+
98
+ Paginator.prototype.lastPage = function() {
99
+ return this.totalPages();
100
+ };
101
+
102
+ Paginator.prototype.isLastPage = function() {
103
+ return this.currentPage() >= this.lastPage();
104
+ };
105
+
106
+ Paginator.prototype.pages = function() {
107
+ var currentPage, firstPage, last, lastPage, page, result, _i, _pages;
108
+
109
+ currentPage = this.currentPage();
110
+ firstPage = this.firstPage();
111
+ lastPage = this.lastPage();
112
+ _pages = [];
113
+ last = null;
114
+ for (page = _i = firstPage; firstPage <= lastPage ? _i <= lastPage : _i >= lastPage; page = firstPage <= lastPage ? ++_i : --_i) {
115
+ result = this.buildPage(page, last, currentPage, firstPage, lastPage);
116
+ if (result.isLeftOuter || result.isRightOuter || result.isInsideWindow) {
117
+ last = null;
118
+ } else {
119
+ last = 'gap';
120
+ }
121
+ _pages.push(result);
122
+ }
123
+ return _pages;
124
+ };
125
+
126
+ Paginator.prototype.curPage = function() {
127
+ var currentPage, firstPage, lastPage;
128
+
129
+ currentPage = this.currentPage();
130
+ firstPage = this.firstPage();
131
+ lastPage = this.lastPage();
132
+ return this.buildPage(currentPage, null, currentPage, firstPage, lastPage);
133
+ };
134
+
135
+ Paginator.prototype.limitValue = function() {
136
+ if (this.perPage > this.totalCount) {
137
+ this.perPage = this.totalCount;
138
+ }
139
+ if ((this.maxPerPage != null) && this.perPage > this.maxPerPage) {
140
+ this.perPage = this.maxPerPage;
141
+ }
142
+ return this.perPage;
143
+ };
144
+
145
+ Paginator.prototype.offsetValue = function() {
146
+ var totalPages;
147
+
148
+ totalPages = this.totalPages();
149
+ if (this._page > totalPages) {
150
+ this._page = totalPages;
151
+ }
152
+ return (this._page - 1) * this.limitValue();
153
+ };
154
+
155
+ Paginator.prototype.buildPage = function(page, last, currentPage, firstPage, lastPage) {
156
+ return {
157
+ number: page,
158
+ isCurrent: page === currentPage,
159
+ isFirst: page === firstPage,
160
+ isLast: page === lastPage,
161
+ isPrev: page === (currentPage - 1),
162
+ isNext: page === (currentPage + 1),
163
+ isLeftOuter: page <= this.left,
164
+ isRightOuter: (lastPage - page) < this.right,
165
+ isInsideWindow: Math.abs(currentPage - page) <= this.window,
166
+ isWasTruncated: last === 'gap'
167
+ };
168
+ };
169
+
170
+ Paginator.prototype.buildButtonsAndLocals = function() {
171
+ var curPage, page, pages, _buttons, _i, _len, _locals;
172
+
173
+ _buttons = [];
174
+ _locals = {};
175
+ curPage = this.curPage();
176
+ pages = this.pages();
177
+ if (!curPage.isFirst) {
178
+ _buttons.push('first');
179
+ _locals.hasFirst = true;
180
+ } else {
181
+ _locals.hasFirst = false;
182
+ }
183
+ if (!curPage.isFirst) {
184
+ _buttons.push('prev');
185
+ _locals.hasPrev = true;
186
+ } else {
187
+ _locals.hasPrev = false;
188
+ }
189
+ _locals.pages = [];
190
+ for (_i = 0, _len = pages.length; _i < _len; _i++) {
191
+ page = pages[_i];
192
+ if (page.isLeftOuter || page.isRightOuter || page.isInsideWindow) {
193
+ if (page.isCurrent) {
194
+ _buttons.push('current');
195
+ _locals.pages.push({
196
+ number: page.number,
197
+ current: true
198
+ });
199
+ } else {
200
+ _buttons.push(page.number);
201
+ _locals.pages.push({
202
+ number: page.number,
203
+ current: false
204
+ });
205
+ }
206
+ } else if (!page.isWasTruncated) {
207
+ _buttons.push('gap');
208
+ _locals.pages.push({
209
+ number: page.number,
210
+ gap: true
211
+ });
212
+ }
213
+ }
214
+ if (!curPage.isLast) {
215
+ _buttons.push('next');
216
+ _locals.hasNext = true;
217
+ } else {
218
+ _locals.hasNext = false;
219
+ }
220
+ if (!curPage.isLast) {
221
+ _buttons.push('last');
222
+ _locals.hasLast = true;
223
+ } else {
224
+ _locals.hasLast = false;
225
+ }
226
+ _locals.first = this.firstPage();
227
+ _locals.current = this.currentPage();
228
+ _locals.last = this.lastPage();
229
+ _locals.numStart = this.records.length === 0 ? 0 : this.offsetValue() + 1;
230
+ _locals.numEnd = this.offsetValue() + this.records.length;
231
+ _locals.numTotal = this.totalCount;
232
+ this.buttons = _buttons;
233
+ return this.locals = _locals;
234
+ };
235
+
236
+ Paginator.prototype.cloneArray = function(array) {
237
+ var value, _i, _len, _results;
238
+
239
+ _results = [];
240
+ for (_i = 0, _len = array.length; _i < _len; _i++) {
241
+ value = array[_i];
242
+ _results.push(value.clone());
243
+ }
244
+ return _results;
245
+ };
246
+
247
+ return Paginator;
248
+
249
+ })();
250
+
251
+ Extend = {
252
+ _perPaginateRecords: function() {
253
+ return this.records;
254
+ },
255
+ page: function(n, options) {
256
+ if (options == null) {
257
+ options = {};
258
+ }
259
+ return new Paginator(this._perPaginateRecords(), n, options);
260
+ }
261
+ };
262
+
263
+ Model.Paginator = {
264
+ extended: function() {
265
+ return this.extend(Extend);
266
+ }
267
+ };
268
+
269
+ Spine.Paginator = Paginator;
270
+
271
+ }).call(this);
@@ -0,0 +1,5 @@
1
+ // spine.paginator.js
2
+ // version: 0.1.0
3
+ // author: vkill
4
+ // license: MIT
5
+ (function(){var t,s,i,e;e=this.Spine||require("spine"),s=e.Model,i=function(){function t(t,s,i){var e;this._page=s,null==i&&(i={}),this._page=parseInt(this._page),(isNaN(this._page)||0>=this._page)&&(this._page=1),this._originalPage=this._page,this.perPage=i.perPage||this.constructor.DEFAULT_PER_PAGE,this.perPage=parseInt(this.perPage),(isNaN(this.perPage)||0>=this.perPage)&&(this.perPage=this.constructor.DEFAULT_PER_PAGE),this.maxPerPage=i.maxPerPage||this.constructor.MAX_PER_PAGE,this.window=i.window||i.inner_window||this.constructor.WINDOW,e=i.outer_window||this.constructor.OUTER_WINDOW,this.left=i.left||this.constructor.LEFT,0===this.left&&(this.left=e),this.right=i.right||this.constructor.RIGHT,0===this.right&&(this.right=e),this.originalRecords=this.cloneArray(t),this.totalCount=this.originalRecords.length,this.skipbuildButtonsAndLocals=i.skipbuildButtonsAndLocals,this.records=[],this.buttons=[],this.locals={},this.per()}return t.DEFAULT_PER_PAGE=25,t.MAX_PER_PAGE=null,t.WINDOW=4,t.OUTER_WINDOW=0,t.LEFT=0,t.RIGHT=0,t.prototype.per=function(t){var s,i,e;return i=parseInt(t),!isNaN(i)&&i>0&&(this.perPage=i,this._page=this._originalPage),s=this.offsetValue(),e=s+this.limitValue(),this.records=this.originalRecords.slice(s,e),null==this.skipbuildButtonsAndLocals&&this.buildButtonsAndLocals(),this},t.prototype.totalPages=function(){return Math.ceil(this.totalCount/this.limitValue())},t.prototype.currentPage=function(){return null==this.limitValue()?this.firstPage():this.offsetValue()/this.limitValue()+1},t.prototype.firstPage=function(){return 1},t.prototype.isFirstPage=function(){return this.currentPage()===this.firstPage()},t.prototype.lastPage=function(){return this.totalPages()},t.prototype.isLastPage=function(){return this.currentPage()>=this.lastPage()},t.prototype.pages=function(){var t,s,i,e,r,a,n,h;for(t=this.currentPage(),s=this.firstPage(),e=this.lastPage(),h=[],i=null,r=n=s;e>=s?e>=n:n>=e;r=e>=s?++n:--n)a=this.buildPage(r,i,t,s,e),i=a.isLeftOuter||a.isRightOuter||a.isInsideWindow?null:"gap",h.push(a);return h},t.prototype.curPage=function(){var t,s,i;return t=this.currentPage(),s=this.firstPage(),i=this.lastPage(),this.buildPage(t,null,t,s,i)},t.prototype.limitValue=function(){return this.perPage>this.totalCount&&(this.perPage=this.totalCount),null!=this.maxPerPage&&this.perPage>this.maxPerPage&&(this.perPage=this.maxPerPage),this.perPage},t.prototype.offsetValue=function(){var t;return t=this.totalPages(),this._page>t&&(this._page=t),(this._page-1)*this.limitValue()},t.prototype.buildPage=function(t,s,i,e,r){return{number:t,isCurrent:t===i,isFirst:t===e,isLast:t===r,isPrev:t===i-1,isNext:t===i+1,isLeftOuter:this.left>=t,isRightOuter:this.right>r-t,isInsideWindow:Math.abs(i-t)<=this.window,isWasTruncated:"gap"===s}},t.prototype.buildButtonsAndLocals=function(){var t,s,i,e,r,a,n;for(e=[],n={},t=this.curPage(),i=this.pages(),t.isFirst?n.hasFirst=!1:(e.push("first"),n.hasFirst=!0),t.isFirst?n.hasPrev=!1:(e.push("prev"),n.hasPrev=!0),n.pages=[],r=0,a=i.length;a>r;r++)s=i[r],s.isLeftOuter||s.isRightOuter||s.isInsideWindow?s.isCurrent?(e.push("current"),n.pages.push({number:s.number,current:!0})):(e.push(s.number),n.pages.push({number:s.number,current:!1})):s.isWasTruncated||(e.push("gap"),n.pages.push({number:s.number,gap:!0}));return t.isLast?n.hasNext=!1:(e.push("next"),n.hasNext=!0),t.isLast?n.hasLast=!1:(e.push("last"),n.hasLast=!0),n.first=this.firstPage(),n.current=this.currentPage(),n.last=this.lastPage(),n.numStart=0===this.records.length?0:this.offsetValue()+1,n.numEnd=this.offsetValue()+this.records.length,n.numTotal=this.totalCount,this.buttons=e,this.locals=n},t.prototype.cloneArray=function(t){var s,i,e,r;for(r=[],i=0,e=t.length;e>i;i++)s=t[i],r.push(s.clone());return r},t}(),t={_perPaginateRecords:function(){return this.records},page:function(t,s){return null==s&&(s={}),new i(this._perPaginateRecords(),t,s)}},s.Paginator={extended:function(){return this.extend(t)}},e.Paginator=i}).call(this);
@@ -0,0 +1,11 @@
1
+
2
+ module SpinePaginator
3
+ class Railtie < ::Rails::Railtie
4
+
5
+ initializer "sprockets.spine_paginator", after: "append_asset_paths" do |app|
6
+ next unless app.config.assets.enabled
7
+ app.config.assets.paths << File.expand_path("../../../dist", __FILE__)
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module SpinePaginator
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,9 @@
1
+ require "spine_paginator/version"
2
+
3
+ if defined?(::Rails)
4
+ require "spine_paginator/railtie"
5
+ end
6
+
7
+ module SpinePaginator
8
+ end
9
+
data/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "spine.paginator",
3
+ "description": "Paginator for Spine.",
4
+ "version": "0.1.0",
5
+ "author": "vkill",
6
+ "url": "https://github.com/vkill/spine_paginator",
7
+ "main": "./dist/spine.paginator.js",
8
+ "licenses": [
9
+ {
10
+ "type": "MIT",
11
+ "url": "https://github.com/vkill/spina_paginator/blob/master/LICENSE-MIT"
12
+ }
13
+ ],
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/vkill/spine_paginator.git"
17
+ },
18
+ "dependencies": {
19
+ "spine": "~1.1.0"
20
+ },
21
+ "devDependencies": {
22
+ "grunt": "~0.4.1",
23
+ "grunt-contrib-coffee": "~0.7.0",
24
+ "grunt-contrib-concat": "~0.3.0",
25
+ "grunt-contrib-uglify": "~0.2.0",
26
+ "grunt-contrib-jasmine": "~0.4.2",
27
+ "grunt-contrib-watch": "~0.3.1"
28
+ },
29
+ "engines": {
30
+ "node": ">= 0.8.0"
31
+ }
32
+ }
data/spec/lib/.gitkeep ADDED
File without changes