spree_core 3.3.6 → 3.4.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (230) hide show
  1. checksums.yaml +4 -4
  2. data/app/helpers/spree/base_helper.rb +17 -18
  3. data/app/helpers/spree/products_helper.rb +5 -5
  4. data/app/models/concerns/spree/calculated_adjustments.rb +4 -3
  5. data/app/models/concerns/spree/default_price.rb +4 -5
  6. data/app/models/concerns/spree/display_money.rb +1 -1
  7. data/app/models/concerns/spree/named_type.rb +1 -1
  8. data/app/models/concerns/spree/ransackable_attributes.rb +5 -6
  9. data/app/models/concerns/spree/user_address.rb +6 -6
  10. data/app/models/concerns/spree/user_methods.rb +3 -3
  11. data/app/models/concerns/spree/user_payment_source.rb +4 -2
  12. data/app/models/concerns/spree/user_reporting.rb +1 -1
  13. data/app/models/spree/ability.rb +3 -3
  14. data/app/models/spree/address.rb +13 -9
  15. data/app/models/spree/adjustable/adjuster/promotion.rb +1 -1
  16. data/app/models/spree/adjustable/adjustments_updater.rb +2 -2
  17. data/app/models/spree/adjustable/promotion_accumulator.rb +6 -4
  18. data/app/models/spree/adjustment.rb +2 -3
  19. data/app/models/spree/app_configuration.rb +5 -6
  20. data/app/models/spree/base.rb +1 -1
  21. data/app/models/spree/calculator/default_tax.rb +4 -5
  22. data/app/models/spree/calculator/flat_percent_item_total.rb +1 -1
  23. data/app/models/spree/calculator/flat_rate.rb +3 -3
  24. data/app/models/spree/calculator/flexi_rate.rb +5 -5
  25. data/app/models/spree/calculator/price_sack.rb +9 -9
  26. data/app/models/spree/calculator/shipping/flat_percent_item_total.rb +1 -1
  27. data/app/models/spree/calculator/shipping/flat_rate.rb +3 -3
  28. data/app/models/spree/calculator/shipping/flexi_rate.rb +7 -7
  29. data/app/models/spree/calculator/shipping/per_item.rb +2 -2
  30. data/app/models/spree/calculator/shipping/price_sack.rb +4 -4
  31. data/app/models/spree/calculator/tiered_flat_rate.rb +3 -2
  32. data/app/models/spree/calculator/tiered_percent.rb +4 -3
  33. data/app/models/spree/calculator.rb +4 -4
  34. data/app/models/spree/classification.rb +2 -2
  35. data/app/models/spree/credit_card.rb +1 -1
  36. data/app/models/spree/exchange.rb +4 -5
  37. data/app/models/spree/gateway/bogus.rb +20 -20
  38. data/app/models/spree/gateway/bogus_simple.rb +2 -4
  39. data/app/models/spree/gateway.rb +4 -4
  40. data/app/models/spree/image.rb +3 -3
  41. data/app/models/spree/inventory_unit.rb +30 -30
  42. data/app/models/spree/line_item.rb +7 -9
  43. data/app/models/spree/option_type.rb +1 -1
  44. data/app/models/spree/order/checkout.rb +5 -5
  45. data/app/models/spree/order/currency_updater.rb +1 -4
  46. data/app/models/spree/order/payments.rb +4 -4
  47. data/app/models/spree/order/store_credit.rb +2 -2
  48. data/app/models/spree/order.rb +11 -29
  49. data/app/models/spree/order_contents.rb +6 -5
  50. data/app/models/spree/order_inventory.rb +3 -4
  51. data/app/models/spree/order_updater.rb +13 -14
  52. data/app/models/spree/payment/processing.rb +25 -26
  53. data/app/models/spree/payment.rb +72 -79
  54. data/app/models/spree/payment_capture_event.rb +1 -1
  55. data/app/models/spree/payment_method/check.rb +1 -1
  56. data/app/models/spree/payment_method/store_credit.rb +5 -5
  57. data/app/models/spree/payment_method.rb +7 -7
  58. data/app/models/spree/preferences/configuration.rb +6 -9
  59. data/app/models/spree/preferences/preferable.rb +11 -11
  60. data/app/models/spree/preferences/preferable_class_methods.rb +2 -3
  61. data/app/models/spree/preferences/scoped_store.rb +6 -5
  62. data/app/models/spree/preferences/store.rb +9 -14
  63. data/app/models/spree/price.rb +1 -1
  64. data/app/models/spree/product/scopes.rb +49 -49
  65. data/app/models/spree/product.rb +16 -16
  66. data/app/models/spree/promotion/actions/create_item_adjustments.rb +2 -1
  67. data/app/models/spree/promotion/actions/free_shipping.rb +1 -1
  68. data/app/models/spree/promotion/rules/first_order.rb +7 -6
  69. data/app/models/spree/promotion/rules/item_total.rb +3 -5
  70. data/app/models/spree/promotion/rules/one_use_per_user.rb +1 -2
  71. data/app/models/spree/promotion/rules/option_value.rb +14 -6
  72. data/app/models/spree/promotion/rules/product.rb +4 -4
  73. data/app/models/spree/promotion/rules/taxon.rb +6 -6
  74. data/app/models/spree/promotion/rules/user.rb +3 -3
  75. data/app/models/spree/promotion/rules/user_logged_in.rb +1 -1
  76. data/app/models/spree/promotion.rb +15 -16
  77. data/app/models/spree/promotion_action.rb +1 -1
  78. data/app/models/spree/promotion_handler/cart.rb +3 -2
  79. data/app/models/spree/promotion_handler/free_shipping.rb +1 -3
  80. data/app/models/spree/promotion_handler/page.rb +3 -3
  81. data/app/models/spree/promotion_rule.rb +5 -4
  82. data/app/models/spree/refund.rb +8 -8
  83. data/app/models/spree/reimbursement/credit.rb +1 -1
  84. data/app/models/spree/reimbursement/reimbursement_type_engine.rb +1 -3
  85. data/app/models/spree/reimbursement.rb +4 -8
  86. data/app/models/spree/reimbursement_performer.rb +0 -5
  87. data/app/models/spree/reimbursement_tax_calculator.rb +5 -12
  88. data/app/models/spree/reimbursement_type.rb +2 -2
  89. data/app/models/spree/return_authorization.rb +22 -26
  90. data/app/models/spree/return_item/eligibility_validator/default.rb +3 -3
  91. data/app/models/spree/return_item/eligibility_validator/inventory_shipped.rb +2 -2
  92. data/app/models/spree/return_item/eligibility_validator/no_reimbursements.rb +2 -2
  93. data/app/models/spree/return_item/eligibility_validator/order_completed.rb +2 -2
  94. data/app/models/spree/return_item/eligibility_validator/rma_required.rb +2 -3
  95. data/app/models/spree/return_item/eligibility_validator/time_since_purchase.rb +2 -2
  96. data/app/models/spree/return_item.rb +15 -19
  97. data/app/models/spree/returns_calculator.rb +1 -2
  98. data/app/models/spree/shipment.rb +14 -35
  99. data/app/models/spree/shipment_handler.rb +10 -12
  100. data/app/models/spree/shipping_calculator.rb +5 -6
  101. data/app/models/spree/shipping_method.rb +3 -3
  102. data/app/models/spree/shipping_rate.rb +2 -2
  103. data/app/models/spree/state.rb +2 -2
  104. data/app/models/spree/stock/availability_validator.rb +1 -1
  105. data/app/models/spree/stock/content_item.rb +2 -3
  106. data/app/models/spree/stock/coordinator.rb +3 -2
  107. data/app/models/spree/stock/differentiator.rb +3 -2
  108. data/app/models/spree/stock/estimator.rb +7 -5
  109. data/app/models/spree/stock/package.rb +5 -5
  110. data/app/models/spree/stock/packer.rb +1 -1
  111. data/app/models/spree/stock/prioritizer.rb +5 -7
  112. data/app/models/spree/stock/quantifier.rb +0 -1
  113. data/app/models/spree/stock/splitter/backordered.rb +2 -4
  114. data/app/models/spree/stock/splitter/base.rb +3 -2
  115. data/app/models/spree/stock/splitter/shipping_category.rb +2 -1
  116. data/app/models/spree/stock_item.rb +1 -1
  117. data/app/models/spree/stock_location.rb +12 -11
  118. data/app/models/spree/stock_movement.rb +1 -3
  119. data/app/models/spree/stock_transfer.rb +1 -1
  120. data/app/models/spree/store.rb +4 -4
  121. data/app/models/spree/store_credit.rb +3 -3
  122. data/app/models/spree/tax_category.rb +1 -1
  123. data/app/models/spree/tax_rate.rb +10 -10
  124. data/app/models/spree/taxon.rb +13 -13
  125. data/app/models/spree/taxonomy.rb +9 -8
  126. data/app/models/spree/validations/db_maximum_length_validator.rb +2 -3
  127. data/app/models/spree/variant.rb +30 -41
  128. data/app/models/spree/zone.rb +10 -10
  129. data/app/validators/db_maximum_length_validator.rb +5 -5
  130. data/config/initializers/acts_as_taggable_on.rb +3 -3
  131. data/config/initializers/assets.rb +1 -1
  132. data/config/initializers/friendly_id.rb +1 -1
  133. data/config/initializers/premailer_assets.rb +1 -1
  134. data/config/locales/en.yml +8 -2
  135. data/db/default/spree/states.rb +1 -0
  136. data/lib/generators/spree/custom_user/custom_user_generator.rb +12 -15
  137. data/lib/generators/spree/install/install_generator.rb +45 -32
  138. data/lib/spree/core/components.rb +3 -3
  139. data/lib/spree/core/controller_helpers/auth.rb +5 -10
  140. data/lib/spree/core/controller_helpers/common.rb +2 -3
  141. data/lib/spree/core/controller_helpers/order.rb +3 -7
  142. data/lib/spree/core/controller_helpers/respond_with.rb +4 -4
  143. data/lib/spree/core/engine.rb +3 -3
  144. data/lib/spree/core/environment/calculators.rb +0 -1
  145. data/lib/spree/core/environment_extension.rb +8 -8
  146. data/lib/spree/core/importer/order.rb +64 -67
  147. data/lib/spree/core/importer/product.rb +10 -9
  148. data/lib/spree/core/product_filters.rb +17 -18
  149. data/lib/spree/core/routes.rb +2 -6
  150. data/lib/spree/core/search/base.rb +62 -59
  151. data/lib/spree/core/version.rb +1 -1
  152. data/lib/spree/core.rb +4 -6
  153. data/lib/spree/i18n.rb +3 -5
  154. data/lib/spree/localized_number.rb +0 -2
  155. data/lib/spree/migrations.rb +8 -7
  156. data/lib/spree/money.rb +3 -7
  157. data/lib/spree/permitted_attributes.rb +2 -2
  158. data/lib/spree/responder.rb +4 -5
  159. data/lib/spree/testing_support/authorization_helpers.rb +3 -3
  160. data/lib/spree/testing_support/caching.rb +5 -5
  161. data/lib/spree/testing_support/capybara_ext.rb +16 -18
  162. data/lib/spree/testing_support/common_rake.rb +8 -9
  163. data/lib/spree/testing_support/controller_requests.rb +6 -6
  164. data/lib/spree/testing_support/extension_rake.rb +2 -3
  165. data/lib/spree/testing_support/factories/address_factory.rb +1 -1
  166. data/lib/spree/testing_support/factories/adjustment_factory.rb +1 -1
  167. data/lib/spree/testing_support/factories/calculator_factory.rb +1 -1
  168. data/lib/spree/testing_support/factories/country_factory.rb +1 -1
  169. data/lib/spree/testing_support/factories/credit_card_factory.rb +1 -1
  170. data/lib/spree/testing_support/factories/customer_return_factory.rb +1 -3
  171. data/lib/spree/testing_support/factories/image_factory.rb +2 -2
  172. data/lib/spree/testing_support/factories/inventory_unit_factory.rb +1 -1
  173. data/lib/spree/testing_support/factories/line_item_factory.rb +2 -2
  174. data/lib/spree/testing_support/factories/options_factory.rb +1 -1
  175. data/lib/spree/testing_support/factories/order_factory.rb +1 -1
  176. data/lib/spree/testing_support/factories/payment_factory.rb +1 -1
  177. data/lib/spree/testing_support/factories/payment_method_factory.rb +4 -4
  178. data/lib/spree/testing_support/factories/price_factory.rb +1 -1
  179. data/lib/spree/testing_support/factories/product_factory.rb +1 -1
  180. data/lib/spree/testing_support/factories/product_option_type_factory.rb +1 -1
  181. data/lib/spree/testing_support/factories/product_property_factory.rb +1 -1
  182. data/lib/spree/testing_support/factories/promotion_category_factory.rb +1 -2
  183. data/lib/spree/testing_support/factories/promotion_factory.rb +1 -2
  184. data/lib/spree/testing_support/factories/promotion_rule_factory.rb +1 -1
  185. data/lib/spree/testing_support/factories/property_factory.rb +1 -1
  186. data/lib/spree/testing_support/factories/prototype_factory.rb +1 -1
  187. data/lib/spree/testing_support/factories/refund_factory.rb +1 -1
  188. data/lib/spree/testing_support/factories/reimbursement_factory.rb +2 -2
  189. data/lib/spree/testing_support/factories/reimbursement_type_factory.rb +1 -1
  190. data/lib/spree/testing_support/factories/return_authorization_factory.rb +1 -1
  191. data/lib/spree/testing_support/factories/return_item_factory.rb +1 -1
  192. data/lib/spree/testing_support/factories/role_factory.rb +1 -1
  193. data/lib/spree/testing_support/factories/shipment_factory.rb +2 -2
  194. data/lib/spree/testing_support/factories/shipping_category_factory.rb +1 -1
  195. data/lib/spree/testing_support/factories/shipping_method_factory.rb +3 -3
  196. data/lib/spree/testing_support/factories/state_factory.rb +1 -1
  197. data/lib/spree/testing_support/factories/stock_factory.rb +1 -1
  198. data/lib/spree/testing_support/factories/stock_item_factory.rb +1 -1
  199. data/lib/spree/testing_support/factories/stock_location_factory.rb +2 -2
  200. data/lib/spree/testing_support/factories/stock_movement_factory.rb +1 -1
  201. data/lib/spree/testing_support/factories/store_credit_category_factory.rb +2 -2
  202. data/lib/spree/testing_support/factories/store_credit_event_factory.rb +1 -1
  203. data/lib/spree/testing_support/factories/store_credit_factory.rb +1 -1
  204. data/lib/spree/testing_support/factories/store_credit_type_factory.rb +1 -1
  205. data/lib/spree/testing_support/factories/store_factory.rb +1 -1
  206. data/lib/spree/testing_support/factories/tag_factory.rb +1 -1
  207. data/lib/spree/testing_support/factories/tax_category_factory.rb +2 -2
  208. data/lib/spree/testing_support/factories/tax_rate_factory.rb +1 -1
  209. data/lib/spree/testing_support/factories/taxon_factory.rb +1 -1
  210. data/lib/spree/testing_support/factories/taxonomy_factory.rb +1 -1
  211. data/lib/spree/testing_support/factories/tracker_factory.rb +1 -1
  212. data/lib/spree/testing_support/factories/user_factory.rb +1 -1
  213. data/lib/spree/testing_support/factories/variant_factory.rb +1 -2
  214. data/lib/spree/testing_support/factories/zone_factory.rb +1 -1
  215. data/lib/spree/testing_support/factories/zone_member_factory.rb +1 -1
  216. data/lib/spree/testing_support/factories.rb +3 -3
  217. data/lib/spree/testing_support/flash.rb +1 -3
  218. data/lib/spree/testing_support/i18n.rb +5 -6
  219. data/lib/spree/testing_support/kernel.rb +1 -2
  220. data/lib/spree/testing_support/order_walkthrough.rb +12 -15
  221. data/lib/spree/testing_support/preferences.rb +0 -1
  222. data/lib/tasks/core.rake +47 -56
  223. data/lib/tasks/email.rake +2 -2
  224. data/lib/tasks/exchanges.rake +5 -5
  225. data/spree_core.gemspec +1 -1
  226. metadata +5 -9
  227. data/app/models/spree/calculator/percent_per_item.rb +0 -51
  228. data/config/initializers/premailer_rails.rb +0 -3
  229. data/lib/spree/core/delegate_belongs_to.rb +0 -99
  230. data/lib/spree/testing_support/microdata.rb +0 -192
@@ -1,51 +0,0 @@
1
- module Spree
2
-
3
- # A calculator for promotions that calculates a percent-off discount
4
- # for all matching products in an order. This should not be used as a
5
- # shipping calculator since it would be the same thing as a flat percent
6
- # off the entire order.
7
-
8
- class Calculator::PercentPerItem < Calculator
9
- preference :percent, :decimal, default: 0
10
-
11
- def self.description
12
- Spree.t(:percent_per_item)
13
- end
14
-
15
- def compute(object=nil)
16
- ActiveSupport::Deprecation.warn(<<-EOS, caller)
17
- Spree::Calculator::PercentPerItem will be removed in Spree 3.4
18
- There is now a Promotion Action which deals with these types of promotions instead
19
- EOS
20
- return 0 if object.nil?
21
- object.line_items.reduce(0) do |sum, line_item|
22
- sum += value_for_line_item(line_item)
23
- end
24
- end
25
-
26
- private
27
-
28
- # Returns all products that match this calculator, but only if the calculator
29
- # is attached to a promotion. If attached to a ShippingMethod, nil is returned.
30
- # Copied from per_item.rb
31
- def matching_products
32
- if compute_on_promotion?
33
- self.calculable.promotion.rules.map do |rule|
34
- rule.respond_to?(:products) ? rule.products : []
35
- end.flatten
36
- end
37
- end
38
-
39
- def value_for_line_item(line_item)
40
- if compute_on_promotion?
41
- return 0 unless matching_products.blank? or matching_products.include?(line_item.product)
42
- end
43
- ((line_item.price * line_item.quantity) * preferred_percent) / 100
44
- end
45
-
46
- # Determines wether or not the calculable object is a promotion
47
- def compute_on_promotion?
48
- @compute_on_promotion ||= self.calculable.respond_to?(:promotion)
49
- end
50
- end
51
- end
@@ -1,3 +0,0 @@
1
- if Gem.loaded_specs['premailer-rails'].version >= Gem::Version.create('1.10.0')
2
- Premailer::Rails.config[:strategies] = [:filesystem, :network, :asset_pipeline]
3
- end
@@ -1,99 +0,0 @@
1
- ##
2
- # Creates methods on object which delegate to an association proxy.
3
- # see delegate_belongs_to for two uses
4
- #
5
- # Todo - integrate with ActiveRecord::Dirty to make sure changes to delegate object are noticed
6
- # Should do
7
- # class User < Spree::Base; delegate_belongs_to :contact, :firstname; end
8
- # class Contact < Spree::Base; end
9
- # u = User.first
10
- # u.changed? # => false
11
- # u.firstname = 'Bobby'
12
- # u.changed? # => true
13
- #
14
- # Right now the second call to changed? would return false
15
- #
16
- # Todo - add has_one support. fairly straightforward addition
17
- ##
18
- module DelegateBelongsTo
19
- extend ActiveSupport::Concern
20
-
21
- module ClassMethods
22
-
23
- @@default_rejected_delegate_columns = ['created_at','created_on','updated_at','updated_on','lock_version','type','id','position','parent_id','lft','rgt']
24
- mattr_accessor :default_rejected_delegate_columns
25
-
26
- ##
27
- # Creates methods for accessing and setting attributes on an association. Uses same
28
- # default list of attributes as delegates_to_association.
29
- # @todo Integrate this with ActiveRecord::Dirty, so if you set a property through one of these setters and then call save on this object, it will save the associated object automatically.
30
- # delegate_belongs_to :contact
31
- # delegate_belongs_to :contact, [:defaults] ## same as above, and useless
32
- # delegate_belongs_to :contact, [:defaults, :address, :fullname], class_name: 'VCard'
33
- ##
34
- def delegate_belongs_to(association, *attrs)
35
- ActiveSupport::Deprecation.warn(<<-EOS, caller)
36
- DelegateBelongsTo module is deprecated and will be removed in Spree 3.4
37
- EOS
38
-
39
- opts = attrs.extract_options!
40
- initialize_association :belongs_to, association, opts
41
- attrs = get_association_column_names(association) if attrs.empty?
42
- attrs.concat get_association_column_names(association) if attrs.delete :defaults
43
- attrs.each do |attr|
44
- class_def attr do |*args|
45
- send(:delegator_for, association, attr, *args)
46
- end
47
-
48
- class_def "#{attr}=" do |val|
49
- send(:delegator_for_setter, association, attr, val)
50
- end
51
- end
52
- end
53
-
54
- protected
55
-
56
- def get_association_column_names(association, without_default_rejected_delegate_columns=true)
57
- begin
58
- association_klass = reflect_on_association(association).klass
59
- methods = association_klass.column_names
60
- methods.reject!{|x|default_rejected_delegate_columns.include?(x.to_s)} if without_default_rejected_delegate_columns
61
- return methods
62
- rescue
63
- return []
64
- end
65
- end
66
-
67
- ##
68
- # initialize_association :belongs_to, :contact
69
- def initialize_association(type, association, opts={})
70
- raise 'Illegal or unimplemented association type.' unless [:belongs_to].include?(type.to_s.to_sym)
71
- send type, association, opts if reflect_on_association(association).nil?
72
- end
73
-
74
- private
75
- def class_def(name, method=nil, &blk)
76
- class_eval { method.nil? ? define_method(name, &blk) : define_method(name, method) }
77
- end
78
- end
79
-
80
- def delegator_for(association, attr, *args)
81
- return if self.class.column_names.include?(attr.to_s)
82
- send "build_#{association}" if send(association).nil?
83
- if args.empty?
84
- send(association).send(attr)
85
- else
86
- send(association).send(attr, *args)
87
- end
88
- end
89
-
90
- def delegator_for_setter(association, attr, val)
91
- return if self.class.column_names.include?(attr.to_s)
92
- send "build_#{association}" if send(association).nil?
93
- send(association).send("#{attr}=", val)
94
- end
95
- protected :delegator_for
96
- protected :delegator_for_setter
97
- end
98
-
99
- ActiveRecord::Base.include DelegateBelongsTo
@@ -1,192 +0,0 @@
1
- module Spree
2
- module TestingSupport
3
- module Microdata
4
- # code extracted and modified from 'microdata' gem
5
- class Document
6
- attr_reader :items, :doc
7
-
8
- def initialize(content)
9
- ActiveSupport::Deprecation.warn(<<-EOS, caller)
10
- Spree::TestingSupport::Microdata will be removed in Spree 3.4
11
- EOS
12
- @doc = Nokogiri::HTML(content)
13
- @items = extract_items
14
- end
15
-
16
- def extract_items
17
- itemscopes = @doc.search('//*[@itemscope and not(@itemprop)]')
18
- return nil unless itemscopes
19
-
20
- itemscopes.map do |itemscope|
21
- Item.new(itemscope)
22
- end
23
- end
24
- end
25
-
26
- class Item
27
- attr_reader :type, :properties, :id
28
-
29
- def initialize(top_node)
30
- @top_node = top_node
31
- @type = extract_item_type
32
- @id = extract_item_id
33
- @properties = {}
34
- add_item_ref_properties(@top_node)
35
- parse_elements(extract_elements(@top_node))
36
- end
37
-
38
- def to_hash
39
- hash = {}
40
- hash[:id] = id if id
41
- hash[:type] = type if type
42
- hash[:properties] = {}
43
- properties.each do |name, values|
44
- final_values = values.map do |value|
45
- if value.reponds_to?(:to_hash)
46
- value.to_hash
47
- else
48
- value
49
- end
50
- end
51
- hash[:properties][name] = final_values
52
- end
53
- hash
54
- end
55
-
56
- private
57
-
58
- def extract_elements(node)
59
- node.search('./*')
60
- end
61
-
62
- def extract_item_id
63
- (value = @top_node.attribute('itemid')) ? value.value : nil
64
- end
65
-
66
- def extract_item_type
67
- (value = @top_node.attribute('itemtype')) ? value.value.split(' ') : nil
68
- end
69
-
70
- def parse_elements(elements)
71
- elements.each { |element| parse_element(element) }
72
- end
73
-
74
- def parse_element(element)
75
- item_scope = element.attribute('itemscope')
76
- item_prop = element.attribute('itemprop')
77
- internal_elements = extract_elements(element)
78
- add_item_prop(element) if item_scope || item_prop
79
- parse_elements(internal_elements) if internal_elements && !item_scope
80
- end
81
-
82
- # Add an 'itemprop' to the properties
83
- def add_item_prop(item_prop)
84
- properties = Itemprop.parse(item_prop, @page_url)
85
- properties.each { |name, value| (@properties[name] ||= []) << value }
86
- end
87
-
88
- # Add any properties referred to by 'itemref'
89
- def add_item_ref_properties(element)
90
- item_ref = element.attribute('itemref')
91
- if item_ref
92
- item_ref.value.split(' ').each { |id| parse_elements(find_with_id(id)) }
93
- end
94
- end
95
-
96
- # Find an element with a matching id
97
- def find_with_id(id)
98
- @top_node.search("//*[@id='#{id}']")
99
- end
100
- end
101
-
102
- class Itemprop
103
- NON_TEXTCONTENT_ELEMENTS = {
104
- 'a' => 'href', 'area' => 'href',
105
- 'audio' => 'src', 'embed' => 'src',
106
- 'iframe' => 'src', 'img' => 'src',
107
- 'link' => 'href', 'meta' => 'content',
108
- 'object' => 'data', 'source' => 'src',
109
- 'time' => 'datetime', 'track' => 'src',
110
- 'video' => 'src'
111
- }.freeze
112
- URL_ATTRIBUTES = ['data', 'href', 'src'].freeze
113
-
114
- # A Hash representing the properties.
115
- # Hash is of the form {'property name' => 'value'}
116
- attr_reader :properties
117
-
118
- # Create a new Itemprop object
119
- # [element] The itemprop element to be parsed
120
- # [page_url] The url of the page, including filename, used to form
121
- # absolute urls
122
- def initialize(element, page_url = nil)
123
- @element = element
124
- @page_url = page_url
125
- @properties = extract_properties
126
- end
127
-
128
- # Parse the element and return a hash representing the properties.
129
- # Hash is of the form {'property name' => 'value'}
130
- # [element] The itemprop element to be parsed
131
- # [page_url] The url of the page, including filename, used to form
132
- # absolute urls
133
- def self.parse(element, page_url = nil)
134
- new(element, page_url).properties
135
- end
136
-
137
- private
138
-
139
- def extract_properties
140
- prop_names = extract_property_names
141
- prop_names.each_with_object({}) do |name, memo|
142
- memo[name] = extract_property
143
- end
144
- end
145
-
146
- # This returns an empty string if can't form a valid
147
- # absolute url as per the Microdata spec.
148
-
149
- def make_absolute_url(url)
150
- return url unless URI.parse(url).relative?
151
- begin
152
- URI.parse(@page_url).merge(url).to_s
153
- rescue URI::Error
154
- url
155
- end
156
- end
157
-
158
- def non_textcontent_element?(element)
159
- NON_TEXTCONTENT_ELEMENTS.has_key?(element)
160
- end
161
-
162
- def url_attribute?(attribute)
163
- URL_ATTRIBUTES.include?(attribute)
164
- end
165
-
166
- def extract_property_names
167
- itemprop_attr = @element.attribute('itemprop')
168
- itemprop_attr ? itemprop_attr.value.split : []
169
- end
170
-
171
- def extract_property_value
172
- element = @element.name
173
- if non_textcontent_element?(element)
174
- attribute = NON_TEXTCONTENT_ELEMENTS[element]
175
- value = @element.attribute(attribute).value
176
- url_attribute?(attribute) ? make_absolute_url(value) : value
177
- else
178
- @element.inner_text.strip
179
- end
180
- end
181
-
182
- def extract_property
183
- if @element.attribute('itemscope')
184
- Item.new(@element)
185
- else
186
- extract_property_value
187
- end
188
- end
189
- end
190
- end
191
- end
192
- end