iiif-presentation 1.4.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +8 -1
  3. data/.standard.yml +1 -0
  4. data/Gemfile +5 -5
  5. data/README.md +1 -1
  6. data/Rakefile +4 -2
  7. data/VERSION +1 -1
  8. data/bin/standardrb +16 -0
  9. data/iiif-presentation.gemspec +23 -23
  10. data/lib/iiif/hash_behaviours.rb +29 -33
  11. data/lib/iiif/ordered_hash.rb +33 -33
  12. data/lib/iiif/presentation/abstract_resource.rb +17 -22
  13. data/lib/iiif/presentation/annotation.rb +9 -11
  14. data/lib/iiif/presentation/annotation_list.rb +8 -10
  15. data/lib/iiif/presentation/canvas.rb +11 -13
  16. data/lib/iiif/presentation/collection.rb +7 -9
  17. data/lib/iiif/presentation/image_resource.rb +33 -35
  18. data/lib/iiif/presentation/layer.rb +8 -10
  19. data/lib/iiif/presentation/manifest.rb +9 -12
  20. data/lib/iiif/presentation/range.rb +8 -10
  21. data/lib/iiif/presentation/resource.rb +5 -7
  22. data/lib/iiif/presentation/sequence.rb +8 -11
  23. data/lib/iiif/presentation/service.rb +1 -2
  24. data/lib/iiif/presentation.rb +7 -7
  25. data/lib/iiif/service.rb +121 -102
  26. data/lib/iiif/v3/abstract_resource.rb +132 -144
  27. data/lib/iiif/v3/presentation/annotation.rb +20 -21
  28. data/lib/iiif/v3/presentation/annotation_collection.rb +7 -9
  29. data/lib/iiif/v3/presentation/annotation_page.rb +14 -15
  30. data/lib/iiif/v3/presentation/canvas.rb +21 -22
  31. data/lib/iiif/v3/presentation/choice.rb +14 -15
  32. data/lib/iiif/v3/presentation/collection.rb +7 -8
  33. data/lib/iiif/v3/presentation/image_resource.rb +21 -22
  34. data/lib/iiif/v3/presentation/manifest.rb +18 -19
  35. data/lib/iiif/v3/presentation/nav_place.rb +125 -29
  36. data/lib/iiif/v3/presentation/range.rb +10 -10
  37. data/lib/iiif/v3/presentation/resource.rb +4 -5
  38. data/lib/iiif/v3/presentation/sequence.rb +10 -11
  39. data/lib/iiif/v3/presentation/service.rb +12 -13
  40. data/lib/iiif/v3/presentation.rb +8 -8
  41. data/spec/integration/iiif/presentation/image_resource_spec.rb +54 -58
  42. data/spec/integration/iiif/service_spec.rb +76 -77
  43. data/spec/integration/iiif/v3/abstract_resource_spec.rb +73 -73
  44. data/spec/integration/iiif/v3/presentation/image_resource_spec.rb +53 -56
  45. data/spec/spec_helper.rb +56 -64
  46. data/spec/unit/iiif/hash_behaviours_spec.rb +384 -387
  47. data/spec/unit/iiif/ordered_hash_spec.rb +86 -91
  48. data/spec/unit/iiif/presentation/abstract_resource_spec.rb +64 -70
  49. data/spec/unit/iiif/presentation/annotation_list_spec.rb +1 -3
  50. data/spec/unit/iiif/presentation/annotation_spec.rb +1 -3
  51. data/spec/unit/iiif/presentation/canvas_spec.rb +11 -14
  52. data/spec/unit/iiif/presentation/collection_spec.rb +26 -33
  53. data/spec/unit/iiif/presentation/image_resource_spec.rb +4 -6
  54. data/spec/unit/iiif/presentation/layer_spec.rb +16 -20
  55. data/spec/unit/iiif/presentation/manifest_spec.rb +45 -48
  56. data/spec/unit/iiif/presentation/range_spec.rb +18 -22
  57. data/spec/unit/iiif/presentation/resource_spec.rb +3 -6
  58. data/spec/unit/iiif/presentation/sequence_spec.rb +58 -63
  59. data/spec/unit/iiif/presentation/shared_examples/abstract_resource_only_keys.rb +4 -10
  60. data/spec/unit/iiif/presentation/shared_examples/any_type_keys.rb +5 -9
  61. data/spec/unit/iiif/presentation/shared_examples/array_only_keys.rb +9 -17
  62. data/spec/unit/iiif/presentation/shared_examples/int_only_keys.rb +6 -14
  63. data/spec/unit/iiif/presentation/shared_examples/string_only_keys.rb +6 -13
  64. data/spec/unit/iiif/service_spec.rb +8 -13
  65. data/spec/unit/iiif/v3/abstract_resource_define_methods_for_spec.rb +39 -37
  66. data/spec/unit/iiif/v3/abstract_resource_spec.rb +128 -143
  67. data/spec/unit/iiif/v3/presentation/annotation_collection_spec.rb +14 -17
  68. data/spec/unit/iiif/v3/presentation/annotation_page_spec.rb +71 -69
  69. data/spec/unit/iiif/v3/presentation/annotation_spec.rb +249 -233
  70. data/spec/unit/iiif/v3/presentation/canvas_spec.rb +211 -193
  71. data/spec/unit/iiif/v3/presentation/choice_spec.rb +81 -77
  72. data/spec/unit/iiif/v3/presentation/collection_spec.rb +24 -29
  73. data/spec/unit/iiif/v3/presentation/image_resource_spec.rb +70 -71
  74. data/spec/unit/iiif/v3/presentation/manifest_spec.rb +248 -237
  75. data/spec/unit/iiif/v3/presentation/nav_place_spec.rb +249 -49
  76. data/spec/unit/iiif/v3/presentation/range_spec.rb +28 -29
  77. data/spec/unit/iiif/v3/presentation/resource_spec.rb +83 -82
  78. data/spec/unit/iiif/v3/presentation/sequence_spec.rb +126 -120
  79. data/spec/unit/iiif/v3/presentation/service_spec.rb +123 -124
  80. data/spec/unit/iiif/v3/presentation/shared_examples/abstract_resource_only_keys.rb +4 -8
  81. data/spec/unit/iiif/v3/presentation/shared_examples/any_type_keys.rb +5 -7
  82. data/spec/unit/iiif/v3/presentation/shared_examples/array_only_keys.rb +9 -13
  83. data/spec/unit/iiif/v3/presentation/shared_examples/hash_only_keys.rb +9 -13
  84. data/spec/unit/iiif/v3/presentation/shared_examples/int_only_keys.rb +6 -10
  85. data/spec/unit/iiif/v3/presentation/shared_examples/numeric_only_keys.rb +6 -10
  86. data/spec/unit/iiif/v3/presentation/shared_examples/string_only_keys.rb +6 -10
  87. data/spec/unit/iiif/v3/presentation/shared_examples/uri_only_keys.rb +9 -13
  88. metadata +27 -69
@@ -2,68 +2,67 @@ module IIIF
2
2
  module V3
3
3
  module Presentation
4
4
  class Annotation < IIIF::V3::AbstractResource
5
-
6
- TYPE = 'Annotation'.freeze
5
+ TYPE = "Annotation".freeze
7
6
 
8
7
  def required_keys
9
- super + %w{ id motivation target }
8
+ super + %w[id motivation target]
10
9
  end
11
10
 
12
11
  def prohibited_keys
13
12
  super + CONTENT_RESOURCE_PROPERTIES + PAGING_PROPERTIES +
14
- %w{ nav_date viewing_direction start_canvas content_annotations }
13
+ %w[nav_date viewing_direction start_canvas content_annotations]
15
14
  end
16
15
 
17
16
  def any_type_keys
18
- super + %w{ body target }
17
+ super + %w[body target]
19
18
  end
20
19
 
21
20
  def uri_only_keys
22
- super + %w{ id }
21
+ super + %w[id]
23
22
  end
24
23
 
25
24
  def string_only_keys
26
- super + %w{ motivation time_mode }
25
+ super + %w[motivation time_mode]
27
26
  end
28
27
 
29
28
  def legal_time_mode_values
30
- %w{ trim scale loop }.freeze
29
+ %w[trim scale loop].freeze
31
30
  end
32
31
 
33
32
  def legal_viewing_hint_values
34
- super + %w{ none }
33
+ super + %w[none]
35
34
  end
36
35
 
37
- def initialize(hsh={})
38
- hsh['type'] = TYPE unless hsh.has_key? 'type'
39
- hsh['motivation'] = 'painting' unless hsh.has_key? 'motivation'
40
- super(hsh)
36
+ def initialize(hsh = {})
37
+ hsh["type"] = TYPE unless hsh.has_key? "type"
38
+ hsh["motivation"] = "painting" unless hsh.has_key? "motivation"
39
+ super
41
40
  end
42
41
 
43
42
  def validate
44
43
  super
45
44
 
46
- if self.has_key?('body') && self['body'].kind_of?(IIIF::V3::Presentation::ImageResource)
45
+ if has_key?("body") && self["body"].is_a?(IIIF::V3::Presentation::ImageResource)
47
46
  img_res_class_str = "IIIF::V3::Presentation::ImageResource"
48
47
 
49
- unless self.motivation == 'painting'
48
+ unless motivation == "painting"
50
49
  m = "#{self.class} motivation must be 'painting' when body is a kind of #{img_res_class_str}"
51
50
  raise IIIF::V3::Presentation::IllegalValueError, m
52
51
  end
53
52
 
54
- body_resource = self['body']
55
- body_id = body_resource['id']
53
+ body_resource = self["body"]
54
+ body_id = body_resource["id"]
56
55
  if body_id && body_id =~ /^https?:/
57
- validate_uri(body_id, 'anno body ImageResource id') # can raise IllegalValueError
56
+ validate_uri(body_id, "anno body ImageResource id") # can raise IllegalValueError
58
57
  else
59
58
  m = "when #{self.class} body is a kind of #{img_res_class_str}, ImageResource id must be an http(s) URI"
60
59
  raise IIIF::V3::Presentation::IllegalValueError, m
61
60
  end
62
61
  end
63
62
 
64
- if self.has_key?('time_mode')
65
- unless self.legal_time_mode_values.include?(self['time_mode'])
66
- m = "timeMode for #{self.class} must be one of #{self.legal_time_mode_values}."
63
+ if has_key?("time_mode")
64
+ unless legal_time_mode_values.include?(self["time_mode"])
65
+ m = "timeMode for #{self.class} must be one of #{legal_time_mode_values}."
67
66
  raise IIIF::V3::Presentation::IllegalValueError, m
68
67
  end
69
68
  end
@@ -2,19 +2,18 @@ module IIIF
2
2
  module V3
3
3
  module Presentation
4
4
  class AnnotationCollection < IIIF::V3::AbstractResource
5
-
6
- TYPE = 'AnnotationCollection'.freeze
5
+ TYPE = "AnnotationCollection".freeze
7
6
 
8
7
  def required_keys
9
- super + %w{ id }
8
+ super + %w[id]
10
9
  end
11
10
 
12
11
  def int_only_keys
13
- super + %w{ total }
12
+ super + %w[total]
14
13
  end
15
14
 
16
15
  def array_only_keys
17
- super + %w{ content }
16
+ super + %w[content]
18
17
  end
19
18
 
20
19
  # TODO: paging properties
@@ -27,11 +26,10 @@ module IIIF
27
26
  #
28
27
  # don't forget to validate
29
28
 
30
- def initialize(hsh={})
31
- hsh['type'] = TYPE unless hsh.has_key? 'type'
32
- super(hsh)
29
+ def initialize(hsh = {})
30
+ hsh["type"] = TYPE unless hsh.has_key? "type"
31
+ super
33
32
  end
34
-
35
33
  end
36
34
  end
37
35
  end
@@ -2,47 +2,46 @@ module IIIF
2
2
  module V3
3
3
  module Presentation
4
4
  class AnnotationPage < IIIF::V3::AbstractResource
5
-
6
- TYPE = 'AnnotationPage'.freeze
5
+ TYPE = "AnnotationPage".freeze
7
6
 
8
7
  def required_keys
9
- super + %w{ id }
8
+ super + %w[id]
10
9
  end
11
10
 
12
11
  def prohibited_keys
13
12
  super + CONTENT_RESOURCE_PROPERTIES +
14
- %w{ first last total nav_date viewing_direction start_canvas content_annotations }
13
+ %w[first last total nav_date viewing_direction start_canvas content_annotations]
15
14
  end
16
15
 
17
16
  def uri_only_keys
18
- super + %w{ id }
17
+ super + %w[id]
19
18
  end
20
19
 
21
- def array_only_keys;
22
- super + %w{ items }
20
+ def array_only_keys
21
+ super + %w[items]
23
22
  end
24
23
 
25
24
  def legal_viewing_hint_values
26
- super + %w{ none }
25
+ super + %w[none]
27
26
  end
28
27
 
29
- def initialize(hsh={})
30
- hsh['type'] = TYPE unless hsh.has_key? 'type'
31
- super(hsh)
28
+ def initialize(hsh = {})
29
+ hsh["type"] = TYPE unless hsh.has_key? "type"
30
+ super
32
31
  end
33
32
 
34
33
  def validate
35
34
  super
36
35
 
37
- unless self['id'] =~ /^https?:/
36
+ unless /^https?:/.match?(self["id"])
38
37
  err_msg = "id must be an http(s) URI for #{self.class}"
39
38
  raise IIIF::V3::Presentation::IllegalValueError, err_msg
40
39
  end
41
40
 
42
- items = self['items']
43
- if items && items.any?
41
+ items = self["items"]
42
+ if items&.any?
44
43
  unless items.all? { |entry| entry.instance_of?(IIIF::V3::Presentation::Annotation) }
45
- err_msg = 'All entries in the items list must be a IIIF::V3::Presentation::Annotation'
44
+ err_msg = "All entries in the items list must be a IIIF::V3::Presentation::Annotation"
46
45
  raise IIIF::V3::Presentation::IllegalValueError, err_msg
47
46
  end
48
47
  end
@@ -2,54 +2,53 @@ module IIIF
2
2
  module V3
3
3
  module Presentation
4
4
  class Canvas < IIIF::V3::AbstractResource
5
-
6
- TYPE = 'Canvas'.freeze
5
+ TYPE = "Canvas".freeze
7
6
 
8
7
  def required_keys
9
- super + %w{ id label }
8
+ super + %w[id label]
10
9
  end
11
10
 
12
11
  def prohibited_keys
13
- super + PAGING_PROPERTIES + %w{ viewing_direction format nav_date start_canvas content_annotations }
12
+ super + PAGING_PROPERTIES + %w[viewing_direction format nav_date start_canvas content_annotations]
14
13
  end
15
14
 
16
15
  def int_only_keys
17
- super + %w{ depth }
16
+ super + %w[depth]
18
17
  end
19
18
 
20
19
  def array_only_keys
21
- super + %w{ content }
20
+ super + %w[content]
22
21
  end
23
22
 
24
23
  def legal_viewing_hint_values
25
- super + %w{ paged continuous non-paged facing-pages auto-advance }
24
+ super + %w[paged continuous non-paged facing-pages auto-advance]
26
25
  end
27
26
 
28
- def initialize(hsh={})
29
- hsh['type'] = TYPE unless hsh.has_key? 'type'
30
- super(hsh)
27
+ def initialize(hsh = {})
28
+ hsh["type"] = TYPE unless hsh.has_key? "type"
29
+ super
31
30
  end
32
31
 
33
32
  def validate
34
33
  super
35
34
 
36
- id_uri = URI.parse(self['id'])
37
- unless self['id'] =~ /^https?:/ && id_uri.fragment.nil?
35
+ id_uri = URI.parse(self["id"])
36
+ unless self["id"] =~ /^https?:/ && id_uri.fragment.nil?
38
37
  err_msg = "id must be an http(s) URI without a fragment for #{self.class}"
39
38
  raise IIIF::V3::Presentation::IllegalValueError, err_msg
40
39
  end
41
40
 
42
- content = self['content']
43
- if content && content.any?
41
+ content = self["content"]
42
+ if content&.any?
44
43
  unless content.all? { |entry| entry.instance_of?(IIIF::V3::Presentation::AnnotationPage) }
45
- err_msg = 'All entries in the content list must be a IIIF::V3::Presentation::AnnotationPage'
44
+ err_msg = "All entries in the content list must be a IIIF::V3::Presentation::AnnotationPage"
46
45
  raise IIIF::V3::Presentation::IllegalValueError, err_msg
47
46
  end
48
47
  content.each do |anno_page|
49
- annos = anno_page['items']
50
- if annos && annos.any?
51
- unless annos.all? { |anno| anno.target == self.id }
52
- err_msg = 'URI of the canvas must be repeated in the target field of included Annotations'
48
+ annos = anno_page["items"]
49
+ if annos&.any?
50
+ unless annos.all? { |anno| anno.target == id }
51
+ err_msg = "URI of the canvas must be repeated in the target field of included Annotations"
53
52
  raise IIIF::V3::Presentation::IllegalValueError, err_msg
54
53
  end
55
54
  end
@@ -58,9 +57,9 @@ module IIIF
58
57
 
59
58
  # "A canvas MUST have exactly one width and one height, or exactly one duration.
60
59
  # It may have width, height and duration.""
61
- height = self['height']
62
- width = self['width']
63
- if (!!height ^ !!width) # this is an exclusive or: forces height and width to boolean
60
+ height = self["height"]
61
+ width = self["width"]
62
+ if !!height ^ !!width # this is an exclusive or: forces height and width to boolean
64
63
  extent_err_msg = "#{self.class} requires both height and width or neither"
65
64
  raise IIIF::V3::Presentation::IllegalValueError, extent_err_msg
66
65
  end
@@ -2,45 +2,44 @@ module IIIF
2
2
  module V3
3
3
  module Presentation
4
4
  class Choice < IIIF::V3::AbstractResource
5
-
6
- TYPE = 'Choice'.freeze
5
+ TYPE = "Choice".freeze
7
6
 
8
7
  def prohibited_keys
9
8
  super + CONTENT_RESOURCE_PROPERTIES + PAGING_PROPERTIES +
10
- %w{ nav_date viewing_direction start_canvas content_annotations }
9
+ %w[nav_date viewing_direction start_canvas content_annotations]
11
10
  end
12
11
 
13
12
  def any_type_keys
14
- super + %w{ default }
13
+ super + %w[default]
15
14
  end
16
15
 
17
16
  def string_only_keys
18
- super + %w{ choice_hint }
17
+ super + %w[choice_hint]
19
18
  end
20
19
 
21
- def array_only_keys;
22
- super + %w{ items };
20
+ def array_only_keys
21
+ super + %w[items]
23
22
  end
24
23
 
25
24
  def legal_viewing_hint_values
26
- %w{ none }
25
+ %w[none]
27
26
  end
28
27
 
29
28
  def legal_choice_hint_values
30
- %w{ client user }
29
+ %w[client user]
31
30
  end
32
31
 
33
- def initialize(hsh={})
34
- hsh['type'] = TYPE unless hsh.has_key? 'type'
35
- super(hsh)
32
+ def initialize(hsh = {})
33
+ hsh["type"] = TYPE unless hsh.has_key? "type"
34
+ super
36
35
  end
37
36
 
38
37
  def validate
39
38
  super
40
39
 
41
- if self.has_key?('choice_hint')
42
- unless self.legal_choice_hint_values.include?(self['choice_hint'])
43
- m = "choiceHint for #{self.class} must be one of #{self.legal_choice_hint_values}."
40
+ if has_key?("choice_hint")
41
+ unless legal_choice_hint_values.include?(self["choice_hint"])
42
+ m = "choiceHint for #{self.class} must be one of #{legal_choice_hint_values}."
44
43
  raise IIIF::V3::Presentation::IllegalValueError, m
45
44
  end
46
45
  end
@@ -2,15 +2,14 @@ module IIIF
2
2
  module V3
3
3
  module Presentation
4
4
  class Collection < IIIF::V3::AbstractResource
5
-
6
- TYPE = 'Collection'.freeze
5
+ TYPE = "Collection".freeze
7
6
 
8
7
  def required_keys
9
- super + %w{ id label }
8
+ super + %w[id label]
10
9
  end
11
10
 
12
11
  def array_only_keys
13
- super + %w{ collections manifests }
12
+ super + %w[collections manifests]
14
13
  end
15
14
 
16
15
  # TODO: navDate (collection or manifest only) - The value must be an xsd:dateTime literal in UTC, expressed in the form “YYYY-MM-DDThh:mm:ssZ”; There must be at most one navDate associated with any given resource.
@@ -24,12 +23,12 @@ module IIIF
24
23
  # The value must be a non-negative integer.
25
24
 
26
25
  def legal_viewing_hint_values
27
- %w{ auto-advance together }
26
+ %w[auto-advance together]
28
27
  end
29
28
 
30
- def initialize(hsh={})
31
- hsh['type'] = TYPE unless hsh.has_key? 'type'
32
- super(hsh)
29
+ def initialize(hsh = {})
30
+ hsh["type"] = TYPE unless hsh.has_key? "type"
31
+ super
33
32
  end
34
33
 
35
34
  def validate
@@ -1,20 +1,19 @@
1
- require 'faraday'
1
+ require "faraday"
2
2
 
3
3
  module IIIF
4
4
  module V3
5
5
  module Presentation
6
6
  class ImageResource < Resource
7
+ TYPE = "Image".freeze
7
8
 
8
- TYPE = 'Image'.freeze
9
-
10
- def initialize(hsh={})
11
- hsh['type'] = TYPE unless hsh.has_key? 'type'
12
- super(hsh)
9
+ def initialize(hsh = {})
10
+ hsh["type"] = TYPE unless hsh.has_key? "type"
11
+ super
13
12
  end
14
13
 
15
14
  class << self
16
- IMAGE_API_DEFAULT_PARAMS = '/full/!200,200/0/default.jpg'.freeze
17
- DEFAULT_FORMAT = 'image/jpeg'.freeze
15
+ IMAGE_API_DEFAULT_PARAMS = "/full/!200,200/0/default.jpg".freeze
16
+ DEFAULT_FORMAT = "image/jpeg".freeze
18
17
  # Create a new ImageResource that includes a IIIF Image API Service
19
18
  # See http://iiif.io/api/presentation/2.0/#image-resources
20
19
  #
@@ -54,8 +53,7 @@ module IIIF
54
53
  # "width":1500
55
54
  # }
56
55
  #
57
- def create_image_api_image_resource(params={})
58
-
56
+ def create_image_api_image_resource(params = {})
59
57
  service_id = params.fetch(:service_id)
60
58
  resource_id_default = "#{service_id}#{IMAGE_API_DEFAULT_PARAMS}"
61
59
  resource_id = params.fetch(:resource_id, resource_id_default)
@@ -69,32 +67,33 @@ module IIIF
69
67
 
70
68
  remote_info = get_info(service_id) if !have_whp || copy_info
71
69
 
72
- resource = self.new
73
- resource['id'] = resource_id
70
+ resource = new
71
+ resource["id"] = resource_id
74
72
  resource.format = format
75
- resource.width = width.nil? ? remote_info['width'] : width
76
- resource.height = height.nil? ? remote_info['height'] : height
73
+ resource.width = width.nil? ? remote_info["width"] : width
74
+ resource.height = height.nil? ? remote_info["height"] : height
77
75
  resource_service = Service.new
78
76
  if copy_info
79
77
  resource_service.merge!(remote_info)
80
- resource_service['id'] ||= resource_service.delete('@id')
78
+ resource_service["id"] ||= resource_service.delete("@id")
81
79
  else
82
- resource_service['id'] = service_id
83
- if profile.nil?
84
- if remote_info['profile'].kind_of?(Array)
85
- resource_service['profile'] = remote_info['profile'][0]
80
+ resource_service["id"] = service_id
81
+ resource_service["profile"] = if profile.nil?
82
+ if remote_info["profile"].is_a?(Array)
83
+ remote_info["profile"][0]
86
84
  else
87
- resource_service['profile'] = remote_info['profile']
85
+ remote_info["profile"]
88
86
  end
89
87
  else
90
- resource_service['profile'] = profile
88
+ profile
91
89
  end
92
90
  end
93
91
  resource.service = [resource_service]
94
- return resource
92
+ resource
95
93
  end
96
94
 
97
95
  protected
96
+
98
97
  def get_info(svc_id)
99
98
  conn = Faraday.new("#{svc_id}/info.json") do |c|
100
99
  c.use Faraday::Response::RaiseError
@@ -2,62 +2,61 @@ module IIIF
2
2
  module V3
3
3
  module Presentation
4
4
  class Manifest < IIIF::V3::AbstractResource
5
-
6
- TYPE = 'Manifest'.freeze
5
+ TYPE = "Manifest".freeze
7
6
 
8
7
  def required_keys
9
8
  # NOTE: relaxing requirement for items as Universal Viewer currently only accepts sequences
10
9
  # see https://github.com/sul-dlss/osullivan/issues/27, sul-dlss/purl/issues/167
11
10
  # super + %w{ id label items }
12
- super + %w{ id label }
11
+ super + %w[id label]
13
12
  end
14
13
 
15
14
  def prohibited_keys
16
- super + CONTENT_RESOURCE_PROPERTIES + PAGING_PROPERTIES + %w{ start_canvas content_annotation }
15
+ super + CONTENT_RESOURCE_PROPERTIES + PAGING_PROPERTIES + %w[start_canvas content_annotation]
17
16
  end
18
17
 
19
18
  def uri_only_keys
20
- super + %w{ id }
19
+ super + %w[id]
21
20
  end
22
21
 
23
22
  def array_only_keys
24
23
  # NOTE: allowing 'items' or 'sequences' as Universal Viewer currently only accepts sequences
25
24
  # see https://github.com/sul-dlss/osullivan/issues/27, sul-dlss/purl/issues/167
26
25
  # super + %w{ items structures }
27
- super + %w{ items structures sequences }
26
+ super + %w[items structures sequences]
28
27
  end
29
28
 
30
29
  def legal_viewing_hint_values
31
- %w{ individuals paged continuous auto-advance }
30
+ %w[individuals paged continuous auto-advance]
32
31
  end
33
32
 
34
- def initialize(hsh={})
35
- hsh['type'] = TYPE unless hsh.has_key? 'type'
36
- super(hsh)
33
+ def initialize(hsh = {})
34
+ hsh["type"] = TYPE unless hsh.has_key? "type"
35
+ super
37
36
  end
38
37
 
39
38
  def validate
40
39
  super # also checks navDate format
41
40
 
42
- unless self['id'] =~ /^https?:/
41
+ unless /^https?:/.match?(self["id"])
43
42
  err_msg = "id must be an http(s) URI for #{self.class}"
44
43
  raise IIIF::V3::Presentation::IllegalValueError, err_msg
45
44
  end
46
45
 
47
46
  # Items object list
48
- unless self&.[]('items')&.any?
49
- m = 'The items list must have at least one entry (and it must be a IIIF::V3::Presentation::Canvas)'
47
+ unless self&.[]("items")&.any?
48
+ m = "The items list must have at least one entry (and it must be a IIIF::V3::Presentation::Canvas)"
50
49
  raise IIIF::V3::Presentation::MissingRequiredKeyError, m
51
50
  end
52
- validate_items_list(self['items']) if self['items']
51
+ validate_items_list(self["items"]) if self["items"]
53
52
 
54
53
  # TODO: when embedding a sequence without any extensions within a manifest, the sequence must not have the @context field.
55
54
 
56
55
  # TODO: AnnotationLists must not be embedded within the manifest
57
56
 
58
- if self['structures']
59
- unless self['structures'].all? { |entry| entry.instance_of?(IIIF::V3::Presentation::Range)}
60
- m = 'All entries in the structures list must be a IIIF::V3::Presentation::Range'
57
+ if self["structures"]
58
+ unless self["structures"].all? { |entry| entry.instance_of?(IIIF::V3::Presentation::Range) }
59
+ m = "All entries in the structures list must be a IIIF::V3::Presentation::Range"
61
60
  raise IIIF::V3::Presentation::IllegalValueError, m
62
61
  end
63
62
  end
@@ -65,12 +64,12 @@ module IIIF
65
64
 
66
65
  def validate_items_list(items_array)
67
66
  unless items_array.size >= 1
68
- m = 'The items list must have at least one entry (and it must be a IIIF::V3::Presentation::Canvas)'
67
+ m = "The items list must have at least one entry (and it must be a IIIF::V3::Presentation::Canvas)"
69
68
  raise IIIF::V3::Presentation::MissingRequiredKeyError, m
70
69
  end
71
70
 
72
71
  unless items_array.all? { |entry| entry.instance_of?(IIIF::V3::Presentation::Canvas) }
73
- m = 'All entries in the items list must be a IIIF::V3::Presentation::Canvas'
72
+ m = "All entries in the items list must be a IIIF::V3::Presentation::Canvas"
74
73
  raise IIIF::V3::Presentation::IllegalValueError, m
75
74
  end
76
75
  end