@@ -3,14 +3,18 @@ import { toEnumerable } from '../../util/collection'
3
3
import { ForloopDrop } from '../../drop/forloop-drop'
4
4
import { Hash } from '../../template/tag/hash'
5
5
6
+ const MODIFIERS = [ 'offset' , 'limit' , 'reversed' ]
7
+
8
+ type valueof < T > = T [ keyof T ]
9
+
6
10
export default {
7
11
type : 'block' ,
8
12
parse : function ( token : TagToken , remainTokens : TopLevelToken [ ] ) {
9
- const toknenizer = new Tokenizer ( token . args , this . liquid . options . operatorsTrie )
13
+ const tokenizer = new Tokenizer ( token . args , this . liquid . options . operatorsTrie )
10
14
11
- const variable = toknenizer . readIdentifier ( )
12
- const inStr = toknenizer . readIdentifier ( )
13
- const collection = toknenizer . readValue ( )
15
+ const variable = tokenizer . readIdentifier ( )
16
+ const inStr = tokenizer . readIdentifier ( )
17
+ const collection = tokenizer . readValue ( )
14
18
assert (
15
19
variable . size ( ) && inStr . content === 'in' && collection ,
16
20
( ) => `illegal tag: ${ token . getText ( ) } `
@@ -44,14 +48,15 @@ export default {
44
48
}
45
49
46
50
const hash = yield this . hash . render ( ctx )
47
- const offset = hash . offset || 0
48
- const limit = ( hash . limit === undefined ) ? collection . length : hash . limit
49
- const reversedIndex = Reflect . ownKeys ( hash ) . indexOf ( 'reversed' )
51
+ const modifiers = this . liquid . options . orderedFilterParameters
52
+ ? Object . keys ( hash ) . filter ( x => MODIFIERS . includes ( x ) )
53
+ : MODIFIERS . filter ( x => hash [ x ] !== undefined )
50
54
51
- // reverse collection before slicing if 'reversed' is 1st parameter
52
- if ( reversedIndex === 0 ) collection . reverse ( )
53
- collection = collection . slice ( offset , offset + limit )
54
- if ( reversedIndex > 0 ) collection . reverse ( )
55
+ collection = modifiers . reduce ( ( collection , modifier : valueof < typeof MODIFIERS > ) => {
56
+ if ( modifier === 'offset' ) return offset ( collection , hash [ 'offset' ] )
57
+ if ( modifier === 'limit' ) return limit ( collection , hash [ 'limit' ] )
58
+ return reversed ( collection )
59
+ } , collection )
55
60
56
61
const scope = { forloop : new ForloopDrop ( collection . length ) }
57
62
ctx . push ( scope )
@@ -68,3 +73,15 @@ export default {
68
73
ctx . pop ( )
69
74
}
70
75
} as TagImplOptions
76
+
77
+ function reversed < T > ( arr : Array < T > ) {
78
+ return [ ...arr ] . reverse ( )
79
+ }
80
+
81
+ function offset < T > ( arr : Array < T > , count : number ) {
82
+ return arr . slice ( count )
83
+ }
84
+
85
+ function limit < T > ( arr : Array < T > , count : number ) {
86
+ return arr . slice ( 0 , count )
87
+ }
0 commit comments