module Tabulous class Tab attr_reader :parent attr_accessor :subtabs, :kind, :name, :declared_to_have_subtabs attr_writer :text, :link_path, :visible_when, :enabled_when def initialize @subtabs = [] @active_actions = {} @kind = :primary_tab @declared_to_have_subtabs = false end def parent=(tab) raise "only subtabs can have parents" unless subtab? @parent = tab @parent.subtabs = @parent.subtabs + [self] end def subtab? @kind == :subtab end def text(view=nil) value = if @text.respond_to?(:call) view.instance_exec(&@text) else @text end unless value.is_a?(String) raise ImproperValueError, "The text of tab '#{self.name}' needs to be a string." end value end def link_path(view=nil) value = if @link_path.respond_to?(:call) view.instance_exec(&@link_path) else @link_path end unless value.is_a?(String) raise ImproperValueError, "The link_path of tab '#{self.name}' needs to be a string." end value end def visible?(view=nil) if @visible_when.respond_to?(:call) view.instance_exec(&@visible_when) else @visible_when end end def enabled?(view=nil) if @enabled_when.respond_to?(:call) view.instance_exec(&@enabled_when) else @enabled_when end end def clickable?(view) enabled?(view) && (!active?(view) || Config.active_tab_clickable) end # controller actions that make this tab active def add_active_actions(controller, actions) controller = controller.to_s actions = [actions] if !actions.is_a?(Array) for action in actions @active_actions[controller] ||= [] @active_actions[controller] << action.to_s end end def active?(view) current_controller = view.controller_path.to_s current_action = view.action_name.to_s active_actions = @active_actions[current_controller] return true if active_actions && (active_actions.include?('any') || active_actions.include?(current_action)) return true if @subtabs.any? { |subtab| subtab.active?(view) } false end def active_actions_overlap?(tab) for controller in @active_actions.keys other_actions = tab.active_actions[controller] if other_actions these_actions = @active_actions[controller] if (!(other_actions & these_actions).empty?) || other_actions.include?('any') || these_actions.include?('any') return true end end end false end protected def active_actions @active_actions end end end