Class: Collapser

Inherits:
Object show all
Defined in:
lib/collapser.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(collapsed_level: nil, collapsible_types: COLLAPSIBLE_TYPES, compress_ids:, expand_ids:, options: {}) ⇒ Collapser

Returns a new instance of Collapser.



11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/collapser.rb', line 11

def initialize(
  collapsed_level: nil,
  collapsible_types: COLLAPSIBLE_TYPES,
  compress_ids:,
  expand_ids:,
  options: {}
)
  @collapsed_level = collapsed_level
  @collapsible_types = collapsible_types.dup
  @options = options.dup
  @compress_ids = compress_ids # by ref, user action
  @expand_ids = expand_ids # by ref, user action
end

Instance Attribute Details

#compress_idsObject

Returns the value of attribute compress_ids.



9
10
11
# File 'lib/collapser.rb', line 9

def compress_ids
  @compress_ids
end

#expand_idsObject

Returns the value of attribute expand_ids.



9
10
11
# File 'lib/collapser.rb', line 9

def expand_ids
  @expand_ids
end

#optionsObject

Returns the value of attribute options.



9
10
11
# File 'lib/collapser.rb', line 9

def options
  @options
end

Instance Method Details

#analyze(fcbs, initialize: true, reject: false, &block) ⇒ Object

Reject rows that should be hidden based on the hierarchy



124
125
126
127
128
129
130
131
# File 'lib/collapser.rb', line 124

def analyze(fcbs, initialize: true, reject: false, &block)
  fcbs.reject do |fcb|
    @collapsed_level = hide?(fcb, initialize: initialize)
    block.call fcb, @collapsed_level if block

    reject && fcb.hide
  end
end

#collapse?(fcb, initialize: false) ⇒ Boolean

Returns:

  • (Boolean)


58
59
60
61
62
63
64
65
# File 'lib/collapser.rb', line 58

def collapse?(fcb, initialize: false)
  per_options_and_token = (collapse_per_options?(fcb) || collapse_per_token?(fcb)) && !expand_per_token?(fcb)
  if initialize
    per_options_and_token
  else
    collapse_per_state?(fcb, default: per_options_and_token)
  end
end

#collapse_per_options?(fcb, options: @options) ⇒ Boolean

Returns:

  • (Boolean)


25
26
27
28
29
30
# File 'lib/collapser.rb', line 25

def collapse_per_options?(fcb, options: @options)
  criteria = options[:"#{fcb.type}#{fcb.level}_collapse"]
  return false if criteria.nil?

  criteria
end

#collapse_per_state?(fcb, default: false) ⇒ Boolean

collapse per user action

Returns:

  • (Boolean)


33
34
35
36
37
38
39
40
41
# File 'lib/collapser.rb', line 33

def collapse_per_state?(fcb, default: false)
  if @compress_ids.key?(fcb.id) && !!@compress_ids[fcb.id]
    true
  elsif @expand_ids.key?(fcb.id) && !!@expand_ids[fcb.id]
    false
  else
    default
  end
end

#collapse_per_token?(fcb) ⇒ Boolean

Returns:

  • (Boolean)


43
44
45
# File 'lib/collapser.rb', line 43

def collapse_per_token?(fcb)
  fcb.token == COLLAPSIBLE_TOKEN_COLLAPSE
end

#collapsible?(fcb) ⇒ Boolean

Returns:

  • (Boolean)


67
68
69
# File 'lib/collapser.rb', line 67

def collapsible?(fcb)
  collapsible_per_options?(fcb)
end

#collapsible_per_options?(fcb, options: @options) ⇒ Boolean

Returns:

  • (Boolean)


47
48
49
50
51
52
# File 'lib/collapser.rb', line 47

def collapsible_per_options?(fcb, options: @options)
  criteria = options[:"#{fcb.type}#{fcb.level}_collapsible"]
  return false if criteria.nil?

  criteria
end

#collapsible_per_type?(fcb, collapsible_types: @collapsible_types) ⇒ Boolean

Returns:

  • (Boolean)


54
55
56
# File 'lib/collapser.rb', line 54

def collapsible_per_type?(fcb, collapsible_types: @collapsible_types)
  @collapsible_types.nil? || @collapsible_types.include?(fcb.type)
end

#expand_per_token?(fcb) ⇒ Boolean

Returns:

  • (Boolean)


71
72
73
# File 'lib/collapser.rb', line 71

def expand_per_token?(fcb)
  fcb.token == COLLAPSIBLE_TOKEN_EXPAND
end

#hide?(fcb, collapsed_level: @collapsed_level, collapsible_types: @collapsible_types, initialize: true) ⇒ Boolean

Returns:

  • (Boolean)


75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/collapser.rb', line 75

def hide?(fcb,
          collapsed_level: @collapsed_level,
          collapsible_types: @collapsible_types,
          initialize: true)

  fcb.collapsible = collapsible?(fcb)
  if collapsed_level.nil?
    # is not collapsing
    fcb.collapse = collapse?(fcb, initialize: initialize)
    collapsed_level = fcb.level if fcb.collapse
    fcb.hide = false

  elsif fcb.level.nil?
    fcb.hide = true

  elsif fcb.level > collapsed_level
    # Currently collapsed; evaluate for the current block
    fcb.collapse = collapse?(fcb, initialize: initialize)
    collapsed_level = fcb.level if fcb.collapse
    fcb.hide = true # block is at a deeper level thus hidden

  elsif fcb.collapsible
    # Currently expanded; evaluate for the current block
    fcb.collapse = collapse?(fcb, initialize: initialize)
    collapsed_level = fcb.collapse ? fcb.level : nil
    fcb.hide = false
  elsif collapsible_per_type?(fcb)
    fcb.collapsible = false
    fcb.collapse = false
    fcb.hide = false
  else
    fcb.hide = true
  end
  if fcb.collapse
    @compress_ids[fcb.id] = fcb.level
    @expand_ids.delete(fcb.id)
  else
    @compress_ids.delete(fcb.id)
    @expand_ids[fcb.id] = fcb.level
  end
  collapsed_level
end

#reject(fcbs, initialize: true, &block) ⇒ Object

Reject rows that should be hidden based on the hierarchy



119
120
121
# File 'lib/collapser.rb', line 119

def reject(fcbs, initialize: true, &block)
  analyze(fcbs, initialize: initialize, reject: true, &block)
end