This file is indexed.

/usr/lib/ruby/vendor_ruby/ramaze/helper/blue_form.rb is in ruby-ramaze 2012.12.08-3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
require 'ramaze'
require 'ramaze/gestalt'

module Ramaze
  module Helper
    ##
    # The BlueForm helper tries to be an even better way to build forms
    # programmatically. By using a simple block you can quickly create all the
    # required elements for your form.
    #
    # See {Ramaze::Helper::BlueForm::Form} for all the available methods.
    #
    # ## Form Data
    #
    # As stated earlier it's possible to pass an object to the form_for()
    # method. What kind of object this is, a database result object or an
    # OpenStruct object doesn't matter as long as the attributes can be accessed
    # outside of the object (this can be done using attr_readers). This makes it
    # extremely easy to directly pass a result object from your favourite ORM.
    # Example:
    #
    #     @data = User[1]
    #
    #     form_for(@data, :method => :post) do |f|
    #       f.input_text 'Username', :username
    #     end
    #
    # The object comes handy when you want to do server-side form validation:
    # if the form can not be validated, just send back the object with keys
    # containing what the user has filled. The fields will be populated with
    # these values, so the user doesn't have to retype everything.
    #
    # If you don't want to use an object you can simply set the first parameter
    # to nil.
    #
    # ## HTML Output
    #
    # The form helper uses Gestalt, Ramaze's custom HTML builder that works
    # somewhat like Erector. The output is very minimalistic, elements such as
    # legends and fieldsets have to be added manually.
    #
    # If you need to add elements not covered by Form methods (e.g. `<div>`
    # tags), you can access the form Gestalt instance with the g() method and
    # generate your tags like this :
    #
    #     form_for(@result, :method => :post) do |f|
    #       f.g.div(:class => "awesome") do
    #         ...
    #       end
    #     end
    #
    # Each combination of a label and input element will be wrapped in
    # `<p>` tags.
    #
    # When using the form helper as a block in your templates it's important to
    # remember that the result is returned and not displayed in the browser
    # directly. When using Etanni this would result in something like the
    # following:
    #
    #     #{form_for(@result, :method => :post) do |f|
    #       f.input_text 'Text label', :textname, 'Chunky bacon!'
    #     end}
    #
    # @example Creating a basic form
    #  form_for(@data, :method => :post) do |f|
    #    f.input_text 'Username', :username
    #  end
    #
    # @example Adding custom elements inside a form
    #  form_for(@result, :method => :post) do |f|
    #    f.fieldset do
    #      f.g.div(:class => "control-group") do
    #        f.input_text 'Text label', :textname, { :placeholder => 'Chunky bacon!',
    #                                                :class       => :bigsize }
    #      end
    #    end
    #  end
    #
    module BlueForm
      ##
      # The form method generates the basic structure of the form. It should be
      # called using a block and it's return value should be manually sent to
      # the browser (since it does not echo the value).
      #
      # @param [Object] form_values Object containing the values for each form
      #  field.
      # @param [Hash] options Hash containing any additional form attributes
      #  such as the method, action, enctype and so on.
      # @param [Block] block Block containing the elements of the form such as
      #  password fields, textareas and so on.
      #
      def form_for(form_values, options = {}, &block)
        form = Form.new(form_values, options)
        form.build(form_errors, &block)
        form
      end

      ##
      # Manually add a new error to the form_errors key in the flash hash. The
      # first parameter is the name of the form field and the second parameter
      # is the custom message.
      #
      # @param [String] name The name of the form field to which the error
      #  belongs.
      # @param [String] message The custom error message to show.
      #
      def form_error(name, message)
        if respond_to?(:flash)
          old = flash[:form_errors] || {}
          flash[:form_errors] = old.merge(name.to_s => message.to_s)
        else
          form_errors[name.to_s] = message.to_s
        end
      end

      ##
      # Returns the hash containing all existing errors and allows other methods
      # to set new errors by using this method as if it were a hash.
      #
      # @return [Array] All form errors.
      #
      def form_errors
        if respond_to?(:flash)
          flash[:form_errors] ||= {}
        else
          @form_errors ||= {}
        end
      end

      ##
      # Retrieve all the form errors for the specified model and add them to the
      # flash hash.
      #
      # @param [Object] obj An object of a model that contains form errors.
      #
      def form_errors_from_model(obj)
        if obj.respond_to?(:errors)
          obj.errors.each do |key, value|
            if value.respond_to?(:first)
              value = value.first
            end

            form_error(key.to_s, value % key)
          end
        end
      end

      ##
      # Main form class that contains all the required methods to generate form
      # specific tags, such as textareas and select boxes. Do note that this
      # class is not thread-safe so you should modify it only within one thread
      # of execution.
      #
      class Form
        attr_reader :g
        attr_reader :form_values

        ##
        # Constructor method that generates an instance of the Form class.
        #
        # @param [Object] form_values Object containing the values for each form
        #  field.
        # @param [Hash] options A hash containing any additional form attributes.
        # @return [Object] An instance of the Form class.
        #
        def initialize(form_values, options)
          @form_values  = form_values
          @form_args    = options.dup
          @g            = Gestalt.new
        end

        ##
        # Builds the form by generating the opening/closing tags and executing
        # the methods in the block.
        #
        # @param [Hash] form_errors Hash containing all form errors (if any).
        #
        def build(form_errors = {})
          # Convert all the keys in form_errors to strings and
          # retrieve the correct values in case
          @form_errors = {}

          form_errors.each do |key, value|
            if value.respond_to?(:first)
              value = value.first
            end

            @form_errors[key.to_s] = value
          end

          @g.form(@form_args) do
            if block_given?
              yield self
            end
          end
        end

        ##
        # Generate a `<legend>` tag.
        #
        # @param [String] text The text to display inside the legend tag.
        # @example
        #   form_for(@data, :method => :post) do |f|
        #     f.legend 'Ramaze rocks!'
        #   end
        #
        def legend(text)
          @g.legend(text)
        end

        ##
        # Generate a fieldset tag.
        #
        # @param [Proc] block The form elements to display inside the fieldset.
        # @example
        #  form_for(@data, :method => :post) do |f|
        #    f.fieldset do
        #      f.legend 'Hello, world!'
        #    end
        #  end
        #
        def fieldset(&block)
          @g.fieldset(&block)
        end

        ##
        # Generate an input tag with a type of "text" along with a label tag.
        # This method also has the alias "text" so feel free to use that one
        # instead of input_text.
        #
        # @param [String] label The text to display inside the label tag.
        # @param [String Symbol] name The name of the text field.
        # @param [Hash] args Any additional HTML attributes along with their
        #  values.
        # @example
        #   form_for(@data, :method => :post) do |f|
        #     f.input_text 'Username', :username
        #   end
        #
        def input_text(label, name, args = {})
          # The ID can come from 2 places, id_for and the args hash
          id   = args[:id] ? args[:id] : id_for(name)
          args = args.merge(:type => :text, :name => name, :id => id)

          if !args[:value] and @form_values.respond_to?(name)
            args[:value] = @form_values.send(name)
          end

          @g.p do
            label_for(id, label, name)
            @g.input(args)
          end
        end
        alias text input_text

        ##
        # Generate an input tag with a type of "password" along with a label.
        # Password fields are pretty much the same as text fields except that
        # the content of these fields is replaced with dots. This method has the
        # following alias: "password".
        #
        # @param [String] label The text to display inside the label tag.
        # @param [String Symbol] name The name of the password field.
        # @param [Hash] args Any additional HTML attributes along with their
        #  values.
        # @example
        #  form_for(@data, :method => :post) do |f|
        #    f.input_password 'My password', :password
        #  end
        #
        def input_password(label, name, args = {})
          # The ID can come from 2 places, id_for and the args hash
          id   = args[:id] ? args[:id] : id_for(name)
          args = args.merge(:type => :password, :name => name, :id => id)

          if !args[:value] and @form_values.respond_to?(name)
            args[:value] = @form_values.send(name)
          end

          @g.p do
            label_for(id, label, name)
            @g.input(args)
          end
        end
        alias password input_password

        ##
        # Generate a submit tag (without a label). A submit tag is a button that
        # once it's clicked will send the form data to the server.
        #
        # @param [String] value The text to display in the button.
        # @param [Hash] args Any additional HTML attributes along with their
        #  values.
        # @example
        #  form_for(@data, :method => :post) do |f|
        #    f.input_submit 'Save'
        #  end
        #
        def input_submit(value = nil, args = {})
          args         = args.merge(:type => :submit)
          args[:value] = value unless value.nil?

          @g.p do
            @g.input(args)
          end
        end
        alias submit input_submit

        ##
        # Generate an input tag with a type of "checkbox".
        #
        # If you want to have multiple checkboxes you can either use an array or
        # a hash.  In the case of an array the values will also be used as text
        # for each checkbox.  When using a hash the key will be displayed and
        # the value will be the value of the checkbox. Example:
        #
        #     @data = Class.new
        #       attr_reader :gender_arr
        #       attr_reader :gender_hash
        #
        #       def initialize
        #         @gender_arr  = ['male', 'female']
        #         @gender_hash = {"Male" => "male", "Female" => "female"}
        #       end
        #     end.new
        #
        #     form_for(@data, :method => :post) do |f|
        #       f.input_checkbox "Gender", :gender_arr
        #       f.input_checkbox "Gender", :gender_hash
        #     end
        #
        # @example
        #  form_for(@data, :method => :post) do |f|
        #    f.input_checkbox 'Remember me', :remember_user
        #  end
        #
        # @param [String] label The text to display inside the label tag.
        # @param [String Symbol] name The name of the checkbox.
        # @param [String/Array] checked String or array that indicates which
        #  value(s) should be checked.
        # @param [Hash] args Any additional HTML attributes along with their
        #  values.
        # @option args [String/Symbol] :id The value to use for the ID attribute.
        # @option args [Array] :values An array containing the possible values
        #  for the checkboxes.
        # @option args [String/Symbol] :span_class The class to use for the
        #  `<span>` element that's wrapped around the checkbox.
        # @option args [TrueClass/FalseClass] :show_value When set to false the
        #  value of each checkbox won't be displayed to the right of the
        #  checkbox. This option is set to true by default.
        # @option args [TrueClass/FalseClass] :show_label When set to true
        #  (default) the label for the checkbox will be displayed. Setting this
        #  to false will hide it.
        #
        def input_checkbox(label, name, checked = nil, args = {})
          id = args[:id] ? args[:id] : "#{id_for(name)}_0"

          # Determine whether or not to show the value of the checkbox
          if args.key?(:show_value)
            show_value = args.delete(:show_value)
          else
            show_value = true
          end

          # Determine whether or not to show the label
          if args.key?(:show_label)
            show_label = args.delete(:show_label)
          else
            show_label = true
          end

          # Get the checkbox value from either the args hash or from
          # the form object (as specified in the form_for() method).
          if !args[:values] and @form_values.respond_to?(name)
            args[:values] = @form_values.send(name)
          end

          # That class for each element wrapper (a span tag) can be customized
          # using :span_class => "a_class".
          if args[:span_class]
            span_class = args[:span_class]
            args.delete(:span_class)
          else
            span_class = "checkbox_wrap"
          end

          # Get the type from the args hash instead of pre-defining it. Doing so
          # means we can use this method for the input_radio method.
          args[:type] = :checkbox if !args[:type]

          # Convert the values to an array if it's something we can't use in a loop
          # (e.g. a string).
          if args[:values].class != Hash and args[:values].class != Array
            args[:values] = [args[:values]]
          end

          # Create a checkbox for each value
          if !args[:values].empty?
            @g.p do
              # Let's create the label and the hidden field
              if show_label === true
                label_for(id, label, name)
              end

              # Loop through all the values. Each checkbox will have an ID of
              # "form-NAME-INDEX". Each name will be NAME followed by [] to
              # indicate it's an array (since multiple values are possible).
              args[:values].each_with_index do |value, index|
                id = args[:id] ? args[:id] : "#{id_for(name)}_#{index}"

                if args[:type] == :checkbox
                  checkbox_name = "#{name}[]"
                else
                  checkbox_name = name
                end

                # Copy all additional attributes and their values except the
                # values array.
                opts = args.clone
                opts.delete(:values)

                # Get the value and text to display for each checkbox
                if value.class == Array
                  checkbox_text  = value[0]
                  checkbox_value = value[1]
                else
                  checkbox_text = checkbox_value = value
                end

                # Let's see if the current item is checked
                if checked.class == Array
                  if checked.include?(checkbox_value)
                    opts[:checked] = 'checked'
                  end
                else
                  if checkbox_value == checked
                    opts[:checked] = 'checked'
                  end
                end

                # And we're done, easy wasn't it?
                opts = opts.merge(
                  :name => checkbox_name, :id => id, :value => checkbox_value
                )

                # Generate the following HTML:
                #
                # <span class="#{span_class}">
                #   <input type="checkbox" name="#{checkbox_name}" id="#{id}"
                #   value="#{value}" /> #{value}
                # </span>
                #
                @g.span(:class => span_class) do
                  @g.input(opts)
                  " #{checkbox_text}" if show_value === true
                end
              end
            end
          end
        end
        alias checkbox input_checkbox

        ##
        # Generate an input tag with a type of "radio".
        #
        # If you want to generate multiple radio buttons you can use an array
        # just like you can with checkboxes. Example:
        #
        #     @data = Class.new
        #       attr_reader :gender_arr
        #       attr_reader :gender_hash
        #
        #       def initialize
        #         @gender_arr  = ['male', 'female']
        #         @gender_hash = {"Male" => "male", "Female" => "female"}
        #       end
        #     end.new
        #
        #     form_for(@data, :method => :post) do |f|
        #       f.input_radio "Gender", :gender_arr
        #       f.input_radio "Gender", :gender_hash
        #     end
        #
        # For more information see the input_checkbox() method.
        #
        # @param [String] label The text to display inside the label tag.
        # @param [String Symbol] name The name of the radio button.
        # @param [String] checked String that indicates if (and which) radio
        #  button should be checked.
        # @param [Hash] args Any additional HTML attributes along with their
        #  values.
        # @see input_checkbox()
        # @example
        #  form_for(@data, :method => :post) do |f|
        #    f.input_radio 'Gender', :gender
        #  end
        #
        def input_radio(label, name, checked = nil, args = {})
          # Force a type of "radio"
          args[:type] = :radio

          if !args[:span_class]
            args[:span_class] = "radio_wrap"
          end

          self.input_checkbox(label, name, checked, args)
        end
        alias radio input_radio

        ##
        # Generate a field for uploading files.
        #
        # @param [String] label The text to display inside the label tag.
        # @param [String Symbol] name The name of the radio tag.
        # @param [Hash] args Any additional HTML attributes along with their
        #  values.
        # @example
        #  form_for(@data, :method => :post) do |f|
        #    f.input_file 'Image', :image
        #  end
        #
        def input_file(label, name, args = {})
          id   = args[:id] ? args[:id] : id_for(name)
          args = args.merge(:type => :file, :name => name, :id => id)

          @g.p do
            label_for(id, label, name)
            @g.input(args)
          end
        end
        alias file input_file

        ##
        # Generate a hidden field. Hidden fields are essentially the same as
        # text fields except that they aren't displayed in the browser.
        #
        # @param [String Symbol] name The name of the hidden field tag.
        # @param [String] value The value of the hidden field
        # @param [Hash] args Any additional HTML attributes along with their
        #  values.
        # @example
        #  form_for(@data, :method => :post) do |f|
        #    f.input_hidden :user_id
        #  end
        #
        def input_hidden(name, value = nil, args = {})
          args = args.merge(:type => :hidden, :name => name)

          if !value and @form_values.respond_to?(name)
            args[:value] = @form_values.send(name)
          else
            args[:value] = value
          end

          @g.input(args)
        end
        alias hidden input_hidden

        ##
        # Generate a text area.
        #
        # @param [String] label The text to display inside the label tag.
        # @param [String Symbol] name The name of the textarea.
        # @param [Hash] args Any additional HTML attributes along with their
        #  values.
        # @example
        #  form_for(@data, :method => :post) do |f|
        #    f.textarea 'Description', :description
        #  end
        #
        def textarea(label, name, args = {})
          id = args[:id] ? args[:id] : id_for(name)

          # Get the value of the textarea
          if !args[:value] and @form_values.respond_to?(name)
            value = @form_values.send(name)
          else
            value = args[:value]
            args.delete(:value)
          end

          args = args.merge(:name => name, :id => id)

          @g.p do
            label_for(id, label, name)
            @g.textarea(args){ value }
          end
        end

        ##
        # Generate a select tag along with the option tags and a label.
        #
        # @param [String] label The text to display inside the label tag.
        # @param [String Symbol] name The name of the select tag.
        # @param [Hash] args Hash containing additional HTML attributes.
        # @example
        #  form_for(@data, :method => :post) do |f|
        #    f.select 'Country', :country_list
        #  end
        #
        def select(label, name, args = {})
          id              = args[:id] ? args[:id] : id_for(name)
          multiple, size  = args.values_at(:multiple, :size)

          # Get all the values
          if !args[:values] and @form_values.respond_to?(name)
            values = @form_values.send(name)
          else
            values = args[:values]
            args.delete(:values)
          end

          args[:multiple] = 'multiple' if multiple
          args[:size]     = (size || values.count || 1).to_i
          args[:name]     = multiple ? "#{name}[]" : name
          args            = args.merge(:id => id)

          # Retrieve the selected value
          has_selected, selected = args.key?(:selected), args[:selected]
                        selected = [selected] if !selected.is_a?(Array)
          args.delete(:selected)

          @g.p do
            label_for(id, label, name)
            @g.select args do
              values.each do |value, o_name|
                o_name ||= value
                o_args = {:value => value}

                if has_selected and selected.include?(value)
                  o_args[:selected] = 'selected'
                end

                @g.option(o_args){ o_name }
              end
            end
          end
        end

        ##
        # Method used for converting the results of the BlueForm helper to a
        # string
        #
        # @return [String] The form output
        #
        def to_s
          @g.to_s
        end

        private

        ##
        # Generate a label based on the id and value.
        #
        # @param [String] id The ID to which the label belongs.
        # @param [String] value The text to display inside the label tag.
        # @param [String] name The name of the field to which the label belongs.
        #
        def label_for(id, value, name)
          if error = @form_errors.delete(name.to_s)
            @g.label("#{value} ", :for => id){ @g.span(:class => :error){ error } }
          else
            @g.label(value, :for => id)
          end
        end

        ##
        # Generate a value for an ID tag based on the field's name.
        #
        # @param  [String] field_name The name of the field.
        # @return [String] The ID for the specified field name.
        #
        def id_for(field_name)
          if name = @form_args[:name]
            "#{name}_#{field_name}".downcase.gsub(/-/, '_')
          else
            "form_#{field_name}".downcase.gsub(/-/, '_')
          end
        end
      end # Form
    end # BlueForm
  end # Helper
end # Ramaze