# frozen_string_literal: truemoduleActionViewmoduleHelpersmoduleTags# :nodoc:classBase# :nodoc:includeHelpers::ActiveModelInstanceTag,Helpers::TagHelper,Helpers::FormTagHelperincludeFormOptionsHelperattr_reader:objectdefinitialize(object_name,method_name,template_object,options={})@object_name,@method_name=object_name.to_s.dup,method_name.to_s.dup@template_object=template_object@object_name.sub!(/\[\]$/,"")||@object_name.sub!(/\[\]\]$/,"]")@object=retrieve_object(options.delete(:object))@skip_default_ids=options.delete(:skip_default_ids)@allow_method_names_outside_object=options.delete(:allow_method_names_outside_object)@options=optionsifRegexp.last_match@generate_indexed_names=true@auto_index=retrieve_autoindex(Regexp.last_match.pre_match)else@generate_indexed_names=false@auto_index=nilendend# This is what child classes implement.defrenderraiseNotImplementedError,"Subclasses must implement a render method"endprivatedefvalueif@allow_method_names_outside_objectobject.public_send@method_nameifobject&&object.respond_to?(@method_name)elseobject.public_send@method_nameifobjectendenddefvalue_before_type_castunlessobject.nil?method_before_type_cast=@method_name+"_before_type_cast"ifvalue_came_from_user?&&object.respond_to?(method_before_type_cast)object.public_send(method_before_type_cast)elsevalueendendenddefvalue_came_from_user?method_name="#{@method_name}_came_from_user?"!object.respond_to?(method_name)||object.public_send(method_name)enddefretrieve_object(object)ifobjectobjectelsif@template_object.instance_variable_defined?("@#{@object_name}")@template_object.instance_variable_get("@#{@object_name}")endrescueNameError# As @object_name may contain the nested syntax (item[subobject]) we need to fallback to nil.nilenddefretrieve_autoindex(pre_match)object=self.object||@template_object.instance_variable_get("@#{pre_match}")ifobject&&object.respond_to?(:to_param)object.to_paramelseraiseArgumentError,"object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}"endenddefadd_default_name_and_id_for_value(tag_value,options)iftag_value.nil?add_default_name_and_id(options)elsespecified_id=options["id"]add_default_name_and_id(options)ifspecified_id.blank?&&options["id"].present?options["id"]+="_#{sanitized_value(tag_value)}"endendenddefadd_default_name_and_id(options)index=name_and_id_index(options)options["name"]=options.fetch("name"){tag_name(options["multiple"],index)}ifgenerate_ids?options["id"]=options.fetch("id"){tag_id(index,options.delete("namespace"))}ifnamespace=options.delete("namespace")options["id"]=options["id"]?"#{namespace}_#{options['id']}":namespaceendendenddeftag_name(multiple=false,index=nil)@template_object.field_name(@object_name,sanitized_method_name,multiple: multiple,index: index)enddeftag_id(index=nil,namespace=nil)@template_object.field_id(@object_name,@method_name,index: index,namespace: namespace)enddefsanitized_method_name@sanitized_method_name||=@method_name.delete_suffix("?")enddefsanitized_value(value)value.to_s.gsub(/[\s.]/,"_").gsub(/[^-[[:word:]]]/,"").downcaseenddefselect_content_tag(option_tags,options,html_options)html_options=html_options.stringify_keysadd_default_name_and_id(html_options)ifplaceholder_required?(html_options)raiseArgumentError,"include_blank cannot be false for a required field."ifoptions[:include_blank]==falseoptions[:include_blank]||=trueunlessoptions[:prompt]endvalue=options.fetch(:selected){value()}select=content_tag("select",add_options(option_tags,options,value),html_options)ifhtml_options["multiple"]&&options.fetch(:include_hidden,true)tag("input",disabled: html_options["disabled"],name: html_options["name"],type: "hidden",value: "",autocomplete: "off")+selectelseselectendenddefplaceholder_required?(html_options)# See https://html.spec.whatwg.org/multipage/forms.html#attr-select-requiredhtml_options["required"]&&!html_options["multiple"]&&html_options.fetch("size",1).to_i==1enddefadd_options(option_tags,options,value=nil)ifoptions[:include_blank]content=(options[:include_blank]ifoptions[:include_blank].is_a?(String))label=(" "unlesscontent)option_tags=tag_builder.content_tag_string("option",content,value: "",label: label)+"\n"+option_tagsendifvalue.blank?&&options[:prompt]tag_options={value: ""}.tapdo|prompt_opts|prompt_opts[:disabled]=trueifoptions[:disabled]==""prompt_opts[:selected]=trueifoptions[:selected]==""endoption_tags=tag_builder.content_tag_string("option",prompt_text(options[:prompt]),tag_options)+"\n"+option_tagsendoption_tagsenddefname_and_id_index(options)ifoptions.key?("index")options.delete("index")||""elsif@generate_indexed_names@auto_index||""endenddefgenerate_ids?!@skip_default_idsendendendendend