<commit_before>require 'bureaucrat/utils'
require 'bureaucrat/validation'
require 'bureaucrat/widgets'
require 'bureaucrat/fields'

module Bureaucrat; module Forms
  class BoundField
    include Utils

    attr_accessor :label

    def initialize(form, field, name)
      @form = form
      @field = field
      @name = name
      @html_name = form.add_prefix(name)
      @html_initial_name = form.add_initial_prefix(name)
      @label = @field.label || pretty_name(name)
      @help_text = @field.help_text || ''
    end

    def to_s
      @field.show_hidden_initial ? as_widget + as_hidden(nil, true) : as_widget
    end

    def errors
      @form.errors.fetch(@name, @form.error_class.new)
    end

    def as_widget(widget=nil, attrs=nil, only_initial=false)
      widget ||= @field.widget
      attrs ||= {}
      auto_id = self.auto_id
      attrs[:id] ||= auto_id if auto_id && !widget.attrs.key?(:id)

      if !@form.bound?
        data = @form.initial.fetch(@name, @field.initial)
        data = data.call if data.respond_to?(:call)
      else
        if @field.is_a?(Fields::FileField) && @data.nil?
          data = @form.initial.fetch(@name, @field.initial)
        else
          data = self.data
        end
      end

      name = only_initial ? @html_initial_name : @html_name

      widget.render(name, data, attrs)
    end

    def as_text(attrs=nil, only_initial=false)
      as_widget(Widgets::TextInput.new, attrs, only_initial)
    end

    def as_textarea(attrs=nil, only_initial=false)
      as_widget(Widgets::Textarea.new, attrs, only_initial)
    end

    def as_hidden(attrs=nil, only_initial=false)
      as_widget(@field.hidden_widget, attrs, only_initial)
    end

    def data
      @field.widget.value_from_datahash(@form.data, @form.files, @html_name)
    end

    def label_tag(contents=nil, attrs=nil)
      contents ||= conditional_escape(@label)
      widget = @field.widget
      id_ = widget.attrs[:id] || self.auto_id

      if id_
        attrs = attrs ? flattatt(attrs) : ''
        contents = "<label for=\"#{Widgets::Widget.id_for_label(id_)}\"#{attrs}>#{contents}</label>"
      end

      mark_safe(contents)
    end

    def hidden?
      @field.widget.hidden?
    end

    def auto_id
      fauto_id = @form.auto_id
      fauto_id ? fauto_id % @html_name : ''
    end
  end

  class Form
    include Utils
    include Validation

    class << self
      attr_accessor :base_fields
      def field(name, field_obj)
        base_fields[name] = field_obj
      end

      # Copy data to the child class
      def inherited(c)
        super(c)
        c.base_fields = base_fields.dup
      end
    end

    @base_fields = OrderedHash.new

    attr_accessor :error_class, :auto_id, :initial, :data, :files, :cleaned_data

    def bound? ; @is_bound; end

    def initialize(data=nil, options={})
      @is_bound = !data.nil?
      @data = data || {}
      @files = options.fetch(:files, {})
      @auto_id = options.fetch(:auto_id, 'id_%s')
      @prefix = options[:prefix]
      @initial = options.fetch(:initial, {})
      @error_class = options.fetch(:error_class, Fields::ErrorList)
      @label_suffix = options.fetch(:label_suffix, ':')
      @empty_permitted = options.fetch(:empty_permitted, false)
      @errors = nil
      @changed_data = nil

      @fields = self.class.base_fields.dup
      @fields.each { |key, value| @fields[key] = value.dup }
    end

    def to_s
      as_table<commit_msg>Create Form's base_fields the first time it is accessed.<commit_after>require 'bureaucrat/utils'
require 'bureaucrat/validation'
require 'bureaucrat/widgets'
require 'bureaucrat/fields'

module Bureaucrat; module Forms
  class BoundField
    include Utils

    attr_accessor :label

    def initialize(form, field, name)
      @form = form
      @field = field
      @name = name
      @html_name = form.add_prefix(name)
      @html_initial_name = form.add_initial_prefix(name)
      @label = @field.label || pretty_name(name)
      @help_text = @field.help_text || ''
    end

    def to_s
      @field.show_hidden_initial ? as_widget + as_hidden(nil, true) : as_widget
    end

    def errors
      @form.errors.fetch(@name, @form.error_class.new)
    end

    def as_widget(widget=nil, attrs=nil, only_initial=false)
      widget ||= @field.widget
      attrs ||= {}
      auto_id = self.auto_id
      attrs[:id] ||= auto_id if auto_id && !widget.attrs.key?(:id)

      if !@form.bound?
        data = @form.initial.fetch(@name, @field.initial)
        data = data.call if data.respond_to?(:call)
      else
        if @field.is_a?(Fields::FileField) && @data.nil?
          data = @form.initial.fetch(@name, @field.initial)
        else
          data = self.data
        end
      end

      name = only_initial ? @html_initial_name : @html_name

      widget.render(name, data, attrs)
    end

    def as_text(attrs=nil, only_initial=false)
      as_widget(Widgets::TextInput.new, attrs, only_initial)
    end

    def as_textarea(attrs=nil, only_initial=false)
      as_widget(Widgets::Textarea.new, attrs, only_initial)
    end

    def as_hidden(attrs=nil, only_initial=false)
      as_widget(@field.hidden_widget, attrs, only_initial)
    end

    def data
      @field.widget.value_from_datahash(@form.data, @form.files, @html_name)
    end

    def label_tag(contents=nil, attrs=nil)
      contents ||= conditional_escape(@label)
      widget = @field.widget
      id_ = widget.attrs[:id] || self.auto_id

      if id_
        attrs = attrs ? flattatt(attrs) : ''
        contents = "<label for=\"#{Widgets::Widget.id_for_label(id_)}\"#{attrs}>#{contents}</label>"
      end

      mark_safe(contents)
    end

    def hidden?
      @field.widget.hidden?
    end

    def auto_id
      fauto_id = @form.auto_id
      fauto_id ? fauto_id % @html_name : ''
    end
  end

  class Form
    include Utils
    include Validation

    class << self
      attr_writer :base_fields

      def base_fields
        @base_fields ||= Utils::OrderedHash.new
      end

      def field(name, field_obj)
        base_fields[name] = field_obj
      end

      # Copy data to the child class
      def inherited(c)
        super(c)
        c.base_fields = base_fields.dup
      end
    end

    attr_accessor :error_class, :auto_id, :initial, :data, :files, :cleaned_data

    def bound? ; @is_bound; end

    def initialize(data=nil, options={})
      @is_bound = !data.nil?
      @data = data || {}
      @files = options.fetch(:files, {})
      @auto_id = options.fetch(:auto_id, 'id_%s')
      @prefix = options[:prefix]
      @initial = options.fetch(:initial, {})
      @error_class = options.fetch(:error_class, Fields::ErrorList)
      @label_suffix = options.fetch(:label_suffix, ':')
      @empty_permitted = options.fetch(:empty_permitted, false)
      @errors = nil
      @changed_data = nil

      @fields = self.class.base_fields.dup
      @fields.each { |key, value| @fields[key] = value.dup }
    end

    def to_s
      as_table
{'fraction_non_alphanumeric': 0.1186901186901187, 'fraction_numerical': 0.0, 'mean_word_length': 2.6656184486373165, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4404448', 'n_tokens_mistral': 2352, 'n_tokens_neox': 2303, 'n_words': 482}