@@ -102,7 +102,7 @@ def to_s
102
102
# :stopdoc:
103
103
# TODO verify mime-type character restrictions; I am pretty sure that this is
104
104
# too wide open.
105
- MEDIA_TYPE_RE = %r{([- \w .+]+ )/([- \w .+ ]*)} . freeze
105
+ MEDIA_TYPE_RE = %r{([a-zA-Z][-a-zA-Z0-9+_.]* )/([a-zA-Z0-9][-a-zA-Z0-9+_. ]*)} . freeze
106
106
I18N_RE = /[^[:alnum:]]/ . freeze
107
107
BINARY_ENCODINGS = %w[ base64 8bit ] . freeze
108
108
ASCII_ENCODINGS = %w[ 7bit quoted-printable ] . freeze
@@ -131,6 +131,7 @@ def initialize(content_type) # :yields: self
131
131
@friendly = { }
132
132
@obsolete = @registered = @provisional = false
133
133
@preferred_extension = @docs = @use_instead = @__sort_priority = nil
134
+ self . __extension_priorities
134
135
135
136
self . extensions = [ ]
136
137
@@ -302,7 +303,7 @@ def add_extensions(*extensions)
302
303
# exceptions defined, the first extension will be used.
303
304
#
304
305
# When setting #preferred_extensions, if #extensions does not contain this
305
- # extension, this will be added to #xtensions .
306
+ # extension, this will be added to #extensions .
306
307
#
307
308
# :attr_accessor: preferred_extension
308
309
@@ -313,10 +314,31 @@ def preferred_extension
313
314
314
315
##
315
316
def preferred_extension = ( value ) # :nodoc:
316
- add_extensions ( value ) if value
317
+ if value
318
+ add_extensions ( value )
319
+ set_preferred_extension_priority ( value )
320
+ else
321
+ clear_extension_priority ( @preferred_extension )
322
+ end
317
323
@preferred_extension = value
318
324
end
319
325
326
+ ##
327
+ # Optional extension priorities for this MIME type. This is a relative value
328
+ # similar to nice(1). An explicitly set `preferred_extension` is automatically
329
+ # given a relative priority of `-10`.
330
+ #
331
+ # :attr_reader: extension_priorities
332
+ attr_accessor :extension_priorities
333
+
334
+ ##
335
+ # Returns the priority for the provided extension or extensions. If a priority
336
+ # is not set, the default priority is 0. The range for priorities is -20..20,
337
+ # inclusive.
338
+ def extension_priority ( *exts )
339
+ exts . map { |ext | get_extension_priority ( ext ) } . min
340
+ end
341
+
320
342
##
321
343
# The encoding (+7bit+, +8bit+, <tt>quoted-printable</tt>, or +base64+)
322
344
# required to transport the data of this content type safely across a
@@ -537,7 +559,8 @@ def encode_with(coder)
537
559
coder [ "registered" ] = registered?
538
560
coder [ "provisional" ] = provisional? if provisional?
539
561
coder [ "signature" ] = signature? if signature?
540
- coder [ "__sort_priority" ] = __sort_priority
562
+ coder [ "sort-priority" ] = __sort_priority
563
+ coder [ "extension-priorities" ] = __extension_priorities unless __extension_priorities . empty?
541
564
coder
542
565
end
543
566
@@ -546,6 +569,7 @@ def encode_with(coder)
546
569
#
547
570
# This method should be considered a private implementation detail.
548
571
def init_with ( coder )
572
+ @__sort_priority = 0
549
573
self . content_type = coder [ "content-type" ]
550
574
self . docs = coder [ "docs" ] || ""
551
575
self . encoding = coder [ "encoding" ]
@@ -557,9 +581,11 @@ def init_with(coder)
557
581
self . signature = coder [ "signature" ]
558
582
self . xrefs = coder [ "xrefs" ] || { }
559
583
self . use_instead = coder [ "use-instead" ]
560
- @__sort_priority = coder [ "__sort_priority " ]
584
+ self . extension_priorities = coder [ "extension-priorities " ]
561
585
562
586
friendly ( coder [ "friendly" ] || { } )
587
+
588
+ update_sort_priority
563
589
end
564
590
565
591
def inspect # :nodoc:
@@ -615,6 +641,22 @@ def simplify_matchdata(matchdata, remove_x = false, joiner: "/")
615
641
616
642
private
617
643
644
+ def __extension_priorities
645
+ @extension_priorities ||= { }
646
+ end
647
+
648
+ def clear_extension_priority ( ext )
649
+ __extension_priorities . delete ( ext ) if ext
650
+ end
651
+
652
+ def get_extension_priority ( ext )
653
+ [ [ -20 , __extension_priorities [ ext ] || 0 ] . max , 20 ] . min
654
+ end
655
+
656
+ def set_preferred_extension_priority ( ext )
657
+ __extension_priorities [ ext ] = -10 unless __extension_priorities . has_key? ( ext )
658
+ end
659
+
618
660
def clear_sort_priority
619
661
@__sort_priority = nil
620
662
end
0 commit comments