algoliasearch-rails 1.16.3 → 1.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +8 -0
  3. data/Gemfile +6 -1
  4. data/Gemfile.lock +3 -3
  5. data/README.md +153 -94
  6. data/VERSION +1 -1
  7. data/algoliasearch-rails.gemspec +1 -1
  8. data/lib/algoliasearch-rails.rb +75 -36
  9. data/spec/spec_helper.rb +7 -0
  10. data/vendor/assets/javascripts/algolia/algoliasearch.angular.js +23 -12
  11. data/vendor/assets/javascripts/algolia/algoliasearch.angular.min.js +2 -2
  12. data/vendor/assets/javascripts/algolia/algoliasearch.jquery.js +23 -12
  13. data/vendor/assets/javascripts/algolia/algoliasearch.jquery.min.js +2 -2
  14. data/vendor/assets/javascripts/algolia/algoliasearch.js +22 -12
  15. data/vendor/assets/javascripts/algolia/algoliasearch.min.js +2 -2
  16. data/vendor/assets/javascripts/algolia/v2/algoliasearch.angular.js +23 -12
  17. data/vendor/assets/javascripts/algolia/v2/algoliasearch.angular.min.js +2 -2
  18. data/vendor/assets/javascripts/algolia/v2/algoliasearch.jquery.js +23 -12
  19. data/vendor/assets/javascripts/algolia/v2/algoliasearch.jquery.min.js +2 -2
  20. data/vendor/assets/javascripts/algolia/v2/algoliasearch.js +22 -12
  21. data/vendor/assets/javascripts/algolia/v2/algoliasearch.min.js +2 -2
  22. data/vendor/assets/javascripts/algolia/v3/algoliasearch.angular.js +2020 -1301
  23. data/vendor/assets/javascripts/algolia/v3/algoliasearch.angular.min.js +3 -3
  24. data/vendor/assets/javascripts/algolia/v3/algoliasearch.jquery.js +2019 -1300
  25. data/vendor/assets/javascripts/algolia/v3/algoliasearch.jquery.min.js +3 -3
  26. data/vendor/assets/javascripts/algolia/v3/algoliasearch.js +2003 -1284
  27. data/vendor/assets/javascripts/algolia/v3/algoliasearch.min.js +3 -3
  28. metadata +5 -6
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.16.3
1
+ 1.17.0
@@ -77,7 +77,7 @@ Gem::Specification.new do |s|
77
77
 
78
78
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
79
79
  s.add_runtime_dependency(%q<json>, [">= 1.5.1"])
80
- s.add_runtime_dependency(%q<algoliasearch>, ["~> 1.12.1"])
80
+ s.add_runtime_dependency(%q<algoliasearch>, ["~> 1.12.4"])
81
81
  s.add_development_dependency(%q<will_paginate>, [">= 2.3.15"])
82
82
  s.add_development_dependency(%q<kaminari>, [">= 0"])
83
83
  s.add_development_dependency "travis"
@@ -30,6 +30,7 @@ module AlgoliaSearch
30
30
  class NotConfigured < StandardError; end
31
31
  class BadConfiguration < StandardError; end
32
32
  class NoBlockGiven < StandardError; end
33
+ class MixedSlavesAndReplicas < StandardError; end
33
34
 
34
35
  autoload :Configuration, 'algoliasearch/configuration'
35
36
  extend Configuration
@@ -57,13 +58,13 @@ module AlgoliaSearch
57
58
  # AlgoliaSearch settings
58
59
  OPTIONS = [:minWordSizefor1Typo, :minWordSizefor2Typos, :typoTolerance,
59
60
  :hitsPerPage, :attributesToRetrieve,
60
- :attributesToHighlight, :attributesToSnippet, :attributesToIndex,
61
+ :attributesToHighlight, :attributesToSnippet, :attributesToIndex, :searchableAttributes,
61
62
  :highlightPreTag, :highlightPostTag,
62
63
  :ranking, :customRanking, :queryType, :attributesForFaceting,
63
64
  :separatorsToIndex, :optionalWords, :attributeForDistinct,
64
65
  :synonyms, :placeholders, :removeWordsIfNoResults, :replaceSynonymsInHighlight,
65
66
  :unretrievableAttributes, :disableTypoToleranceOnWords, :disableTypoToleranceOnAttributes, :altCorrections,
66
- :ignorePlurals, :maxValuesPerFacet, :distinct, :numericAttributesToIndex,
67
+ :ignorePlurals, :maxValuesPerFacet, :distinct, :numericAttributesToIndex, :numericAttributesForFiltering,
67
68
  :allowTyposOnNumericTokens, :allowCompressionOfIntegerArray,
68
69
  :advancedSyntax]
69
70
  OPTIONS.each do |k|
@@ -79,7 +80,7 @@ module AlgoliaSearch
79
80
 
80
81
  def attribute(*names, &block)
81
82
  raise ArgumentError.new('Cannot pass multiple attribute names if block given') if block_given? and names.length > 1
82
- raise ArgumentError.new('Cannot specify additional attributes on a slave index') if @options[:slave]
83
+ raise ArgumentError.new('Cannot specify additional attributes on a replica index') if @options[:slave] || @options[:replica]
83
84
  @attributes ||= {}
84
85
  names.flatten.each do |name|
85
86
  @attributes[name.to_s] = block_given? ? Proc.new { |o| o.instance_eval(&block) } : Proc.new { |o| o.send(name) }
@@ -89,7 +90,7 @@ module AlgoliaSearch
89
90
 
90
91
  def add_attribute(*names, &block)
91
92
  raise ArgumentError.new('Cannot pass multiple attribute names if block given') if block_given? and names.length > 1
92
- raise ArgumentError.new('Cannot specify additional attributes on a slave index') if @options[:slave]
93
+ raise ArgumentError.new('Cannot specify additional attributes on a replica index') if @options[:slave] || @options[:replica]
93
94
  @additional_attributes ||= {}
94
95
  names.each do |name|
95
96
  @additional_attributes[name.to_s] = block_given? ? Proc.new { |o| o.instance_eval(&block) } : Proc.new { |o| o.send(name) }
@@ -201,14 +202,14 @@ module AlgoliaSearch
201
202
  end
202
203
 
203
204
  def geoloc(lat_attr, lng_attr)
204
- raise ArgumentError.new('Cannot specify additional attributes on a slave index') if @options[:slave]
205
+ raise ArgumentError.new('Cannot specify additional attributes on a replica index') if @options[:slave] || @options[:replica]
205
206
  add_attribute :_geoloc do |o|
206
207
  { :lat => o.send(lat_attr).to_f, :lng => o.send(lng_attr).to_f }
207
208
  end
208
209
  end
209
210
 
210
211
  def tags(*args, &block)
211
- raise ArgumentError.new('Cannot specify additional attributes on a slave index') if @options[:slave]
212
+ raise ArgumentError.new('Cannot specify additional attributes on a replica index') if @options[:slave] || @options[:replica]
212
213
  add_attribute :_tags do |o|
213
214
  v = block_given? ? o.instance_eval(&block) : args
214
215
  v.is_a?(Array) ? v : [v]
@@ -225,25 +226,41 @@ module AlgoliaSearch
225
226
  v = get_setting(k)
226
227
  settings[k] = v if !v.nil?
227
228
  end
228
- settings[:slaves] = additional_indexes.select { |options, s| options[:slave] }.map do |options, s|
229
- name = options[:index_name]
230
- name = "#{name}_#{Rails.env.to_s}" if options[:per_environment]
231
- name
232
- end if !@options[:slave]
229
+ if !@options[:slave] && !@options[:replica]
230
+ settings[:slaves] = additional_indexes.select { |opts, s| opts[:slave] }.map do |opts, s|
231
+ name = opts[:index_name]
232
+ name = "#{name}_#{Rails.env.to_s}" if opts[:per_environment]
233
+ name
234
+ end
235
+ settings.delete(:slaves) if settings[:slaves].empty?
236
+ settings[:replicas] = additional_indexes.select { |opts, s| opts[:replica] }.map do |opts, s|
237
+ name = opts[:index_name]
238
+ name = "#{name}_#{Rails.env.to_s}" if opts[:per_environment]
239
+ name
240
+ end
241
+ settings.delete(:replicas) if settings[:replicas].empty?
242
+ end
233
243
  settings
234
244
  end
235
245
 
236
246
  def add_index(index_name, options = {}, &block)
237
- raise ArgumentError.new('Cannot specify additional index on a slave index') if @options[:slave]
247
+ raise ArgumentError.new('Cannot specify additional index on a replica index') if @options[:slave] || @options[:replica]
238
248
  raise ArgumentError.new('No block given') if !block_given?
239
249
  raise ArgumentError.new('Options auto_index and auto_remove cannot be set on nested indexes') if options[:auto_index] || options[:auto_remove]
240
- options[:index_name] = index_name
241
250
  @additional_indexes ||= {}
251
+ raise MixedSlavesAndReplicas.new('Cannot mix slaves and replicas in the same configuration (add_slave is deprecated)') if (options[:slave] && @additional_indexes.any? { |opts, _| opts[:replica] }) || (options[:replica] && @additional_indexes.any? { |opts, _| opts[:slave] })
252
+ options[:index_name] = index_name
242
253
  @additional_indexes[options] = IndexSettings.new(options, Proc.new)
243
254
  end
244
255
 
256
+ def add_replica(index_name, options = {}, &block)
257
+ raise ArgumentError.new('Cannot specify additional replicas on a replica index') if @options[:slave] || @options[:replica]
258
+ raise ArgumentError.new('No block given') if !block_given?
259
+ add_index(index_name, options.merge({ :replica => true }), &block)
260
+ end
261
+
245
262
  def add_slave(index_name, options = {}, &block)
246
- raise ArgumentError.new('Cannot specify additional slaves on a slave index') if @options[:slave]
263
+ raise ArgumentError.new('Cannot specify additional slaves on a slave index') if @options[:slave] || @options[:replica]
247
264
  raise ArgumentError.new('No block given') if !block_given?
248
265
  add_index(index_name, options.merge({ :slave => true }), &block)
249
266
  end
@@ -287,7 +304,7 @@ module AlgoliaSearch
287
304
 
288
305
  # special handling of get_settings to avoid raising errors on 404
289
306
  def get_settings(*args)
290
- SafeIndex.log_or_throw(:move_index) do
307
+ SafeIndex.log_or_throw(:get_settings) do
291
308
  begin
292
309
  @index.get_settings(*args)
293
310
  rescue Algolia::AlgoliaError => e
@@ -452,7 +469,7 @@ module AlgoliaSearch
452
469
  algolia_configurations.each do |options, settings|
453
470
  next if algolia_indexing_disabled?(options)
454
471
  index = algolia_ensure_init(options, settings)
455
- next if options[:slave]
472
+ next if options[:slave] || options[:replica]
456
473
  last_task = nil
457
474
 
458
475
  algolia_find_in_batches(batch_size) do |group|
@@ -472,7 +489,7 @@ module AlgoliaSearch
472
489
  end
473
490
  last_task = index.save_objects(objects)
474
491
  end
475
- index.wait_task(last_task["taskID"]) if last_task and synchronous == true
492
+ index.wait_task(last_task["taskID"]) if last_task and (synchronous || options[:synchronous])
476
493
  end
477
494
  nil
478
495
  end
@@ -482,16 +499,18 @@ module AlgoliaSearch
482
499
  return if @algolia_without_auto_index_scope
483
500
  algolia_configurations.each do |options, settings|
484
501
  next if algolia_indexing_disabled?(options)
485
- next if options[:slave]
502
+ next if options[:slave] || options[:replica]
486
503
 
487
504
  # fetch the master settings
488
505
  master_index = algolia_ensure_init(options, settings)
489
506
  master_settings = master_index.get_settings rescue {} # if master doesn't exist yet
490
507
  master_settings.merge!(JSON.parse(settings.to_settings.to_json)) # convert symbols to strings
491
508
 
492
- # remove the slaves of the temporary index
509
+ # remove the replicas of the temporary index
493
510
  master_settings.delete :slaves
494
511
  master_settings.delete 'slaves'
512
+ master_settings.delete :replicas
513
+ master_settings.delete 'replicas'
495
514
 
496
515
  # init temporary index
497
516
  index_name = algolia_index_name(options)
@@ -510,7 +529,7 @@ module AlgoliaSearch
510
529
  end
511
530
 
512
531
  move_task = SafeIndex.move_index(tmp_index.name, index_name)
513
- tmp_index.wait_task(move_task["taskID"]) if synchronous == true
532
+ master_index.wait_task(move_task["taskID"]) if synchronous || options[:synchronous]
514
533
  end
515
534
  nil
516
535
  end
@@ -519,9 +538,9 @@ module AlgoliaSearch
519
538
  algolia_configurations.each do |options, settings|
520
539
  next if algolia_indexing_disabled?(options)
521
540
  index = algolia_ensure_init(options, settings)
522
- next if options[:slave]
541
+ next if options[:slave] || options[:replica]
523
542
  task = index.save_objects(objects.map { |o| settings.get_attributes(o).merge 'objectID' => algolia_object_id_of(o, options) })
524
- index.wait_task(task["taskID"]) if synchronous == true
543
+ index.wait_task(task["taskID"]) if synchronous || options[:synchronous]
525
544
  end
526
545
  end
527
546
 
@@ -531,17 +550,17 @@ module AlgoliaSearch
531
550
  next if algolia_indexing_disabled?(options)
532
551
  object_id = algolia_object_id_of(object, options)
533
552
  index = algolia_ensure_init(options, settings)
534
- next if options[:slave]
553
+ next if options[:slave] || options[:replica]
535
554
  if algolia_indexable?(object, options)
536
555
  raise ArgumentError.new("Cannot index a record with a blank objectID") if object_id.blank?
537
- if synchronous
556
+ if synchronous || options[:synchronous]
538
557
  index.add_object!(settings.get_attributes(object), object_id)
539
558
  else
540
559
  index.add_object(settings.get_attributes(object), object_id)
541
560
  end
542
561
  elsif algolia_conditional_index?(options) && !object_id.blank?
543
562
  # remove non-indexable objects
544
- if synchronous
563
+ if synchronous || options[:synchronous]
545
564
  index.delete_object!(object_id)
546
565
  else
547
566
  index.delete_object(object_id)
@@ -558,8 +577,8 @@ module AlgoliaSearch
558
577
  algolia_configurations.each do |options, settings|
559
578
  next if algolia_indexing_disabled?(options)
560
579
  index = algolia_ensure_init(options, settings)
561
- next if options[:slave]
562
- if synchronous
580
+ next if options[:slave] || options[:replica]
581
+ if synchronous || options[:synchronous]
563
582
  index.delete_object!(object_id)
564
583
  else
565
584
  index.delete_object(object_id)
@@ -572,15 +591,20 @@ module AlgoliaSearch
572
591
  algolia_configurations.each do |options, settings|
573
592
  next if algolia_indexing_disabled?(options)
574
593
  index = algolia_ensure_init(options, settings)
575
- next if options[:slave]
576
- synchronous ? index.clear! : index.clear
594
+ next if options[:slave] || options[:replica]
595
+ synchronous || options[:synchronous] ? index.clear! : index.clear
577
596
  @algolia_indexes[settings] = nil
578
597
  end
579
598
  nil
580
599
  end
581
600
 
582
601
  def algolia_raw_search(q, params = {})
583
- index_name = params.delete(:index) || params.delete('index') || params.delete(:slave) || params.delete('slave')
602
+ index_name = params.delete(:index) ||
603
+ params.delete('index') ||
604
+ params.delete(:slave) ||
605
+ params.delete('slave') ||
606
+ params.delete(:replica) ||
607
+ params.delete('replica')
584
608
  index = algolia_index(index_name)
585
609
  index.search(q, Hash[params.map { |k,v| [k.to_s, v.to_s] }])
586
610
  end
@@ -641,7 +665,12 @@ module AlgoliaSearch
641
665
  end
642
666
 
643
667
  def algolia_search_for_facet_values(facet, text, params = {})
644
- index_name = params.delete(:index) || params.delete('index') || params.delete(:slave) || params.delete('slave')
668
+ index_name = params.delete(:index) ||
669
+ params.delete('index') ||
670
+ params.delete(:slave) ||
671
+ params.delete('slave') ||
672
+ params.delete(:replica) ||
673
+ params.delete('replicas')
645
674
  index = algolia_index(index_name)
646
675
  query = Hash[params.map { |k, v| [k.to_s, v.to_s] }]
647
676
  index.search_facet(facet, text, query)['facetHits']
@@ -655,7 +684,7 @@ module AlgoliaSearch
655
684
  algolia_configurations.each do |o, s|
656
685
  return algolia_ensure_init(o, s) if o[:index_name].to_s == name.to_s
657
686
  end
658
- raise ArgumentError.new("Invalid index/slave name: #{name}")
687
+ raise ArgumentError.new("Invalid index/replica name: #{name}")
659
688
  end
660
689
  algolia_ensure_init
661
690
  end
@@ -669,7 +698,7 @@ module AlgoliaSearch
669
698
 
670
699
  def algolia_must_reindex?(object)
671
700
  algolia_configurations.each do |options, settings|
672
- next if options[:slave]
701
+ next if options[:slave] || options[:replica]
673
702
  return true if algolia_object_id_changed?(object, options)
674
703
  settings.get_attribute_names(object).each do |k|
675
704
  changed_method = "#{k}_changed?"
@@ -682,6 +711,10 @@ module AlgoliaSearch
682
711
  changed_method = "#{condition}_changed?"
683
712
  return true if !object.respond_to?(changed_method) || object.send(changed_method)
684
713
  else
714
+ # if the :if, :unless condition is a anything else,
715
+ # we have no idea whether we should reindex or not
716
+ # let's always reindex then
717
+ return true
685
718
  end
686
719
  end
687
720
  end
@@ -700,6 +733,12 @@ module AlgoliaSearch
700
733
  current_settings = @algolia_indexes[settings].get_settings rescue nil # if the index doesn't exist
701
734
  if !algolia_indexing_disabled?(options) && (index_settings || algoliasearch_settings_changed?(current_settings, settings.to_settings))
702
735
  index_settings ||= settings.to_settings
736
+ used_slaves = !current_settings.nil? && !current_settings['slaves'].nil?
737
+ replicas = index_settings.delete(:replicas) ||
738
+ index_settings.delete('replicas') ||
739
+ index_settings.delete(:slaves) ||
740
+ index_settings.delete('slaves')
741
+ index_settings[used_slaves ? :slaves : :replicas] = replicas
703
742
  @algolia_indexes[settings].set_settings(index_settings)
704
743
  end
705
744
  @algolia_indexes[settings]
@@ -851,15 +890,15 @@ module AlgoliaSearch
851
890
 
852
891
  def algolia_enqueue_remove_from_index!(synchronous)
853
892
  if algoliasearch_options[:enqueue]
854
- algoliasearch_options[:enqueue].call(self, true)
893
+ algoliasearch_options[:enqueue].call(self, true) unless self.class.send(:algolia_indexing_disabled?, algoliasearch_options)
855
894
  else
856
- algolia_remove_from_index!(synchronous)
895
+ algolia_remove_from_index!(synchronous || algolia_synchronous?)
857
896
  end
858
897
  end
859
898
 
860
899
  def algolia_enqueue_index!(synchronous)
861
900
  if algoliasearch_options[:enqueue]
862
- algoliasearch_options[:enqueue].call(self, false)
901
+ algoliasearch_options[:enqueue].call(self, false) unless self.class.send(:algolia_indexing_disabled?, algoliasearch_options)
863
902
  else
864
903
  algolia_index!(synchronous)
865
904
  end
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'bundler'
3
+ require 'timeout'
3
4
 
4
5
  Bundler.setup :test
5
6
 
@@ -19,6 +20,12 @@ RSpec.configure do |c|
19
20
  c.filter_run :focus => true
20
21
  c.run_all_when_everything_filtered = true
21
22
  c.formatter = 'documentation'
23
+
24
+ c.around(:each) do |example|
25
+ Timeout::timeout(120) {
26
+ example.run
27
+ }
28
+ end
22
29
  end
23
30
 
24
31
  # avoid concurrent access to the same index
@@ -21,7 +21,7 @@
21
21
  * THE SOFTWARE.
22
22
  */
23
23
 
24
- var ALGOLIA_VERSION = '2.9.4';
24
+ var ALGOLIA_VERSION = '2.9.7';
25
25
 
26
26
  /*
27
27
  * Copyright (c) 2013 Algolia
@@ -106,9 +106,9 @@ var AlgoliaSearch = function(applicationID, apiKey, methodOrOptions, resolveDNS,
106
106
  // If hosts is undefined, initialize it with applicationID
107
107
  if (this._isUndefined(hosts)) {
108
108
  hosts = [
109
- this.applicationID + '-1.algolia.' + tld,
110
- this.applicationID + '-2.algolia.' + tld,
111
- this.applicationID + '-3.algolia.' + tld
109
+ this.applicationID + '-1.algolianet.com',
110
+ this.applicationID + '-2.algolianet.com',
111
+ this.applicationID + '-3.algolianet.com'
112
112
  ];
113
113
  }
114
114
  // detect is we use http or https
@@ -118,16 +118,10 @@ var AlgoliaSearch = function(applicationID, apiKey, methodOrOptions, resolveDNS,
118
118
  } else if (method === 'https' || method === 'HTTPS') {
119
119
  this.host_protocol = 'https://';
120
120
  }
121
- // Add hosts in random order
121
+ // Add protocol to hosts
122
122
  for (var i = 0; i < hosts.length; ++i) {
123
- if (Math.random() > 0.5) {
124
- this.hosts.reverse();
125
- }
126
123
  this.hosts.push(this.host_protocol + hosts[i]);
127
124
  }
128
- if (Math.random() > 0.5) {
129
- this.hosts.reverse();
130
- }
131
125
  // then add Distributed Search Network host if there is one
132
126
  if (this.dsn || this.dsnHost != null) {
133
127
  if (this.dsnHost) {
@@ -143,6 +137,8 @@ var AlgoliaSearch = function(applicationID, apiKey, methodOrOptions, resolveDNS,
143
137
  self.options.angular.$http = $http;
144
138
  }]);
145
139
  }
140
+
141
+ this._ua = this.options._ua || 'Algolia for vanilla JavaScript ' + window.ALGOLIA_VERSION;
146
142
  };
147
143
 
148
144
  // This holds the number of JSONP requests done accross clients
@@ -595,6 +591,7 @@ AlgoliaSearch.prototype = {
595
591
 
596
592
  opts.successiveRetryCount = 0;
597
593
  var impl = function() {
594
+
598
595
  if (opts.successiveRetryCount >= self.hosts.length) {
599
596
  var error = { message: 'Cannot connect the Algolia\'s Search API. Please send an email to support@algolia.com to report the issue.' };
600
597
  if (!self._isUndefined(callback) && callback) {
@@ -665,6 +662,7 @@ AlgoliaSearch.prototype = {
665
662
  if (this.tagFilters) {
666
663
  url += '&X-Algolia-TagFilters=' + encodeURIComponent(this.tagFilters);
667
664
  }
665
+ url += '&X-Algolia-Agent=' + encodeURIComponent(this._ua);
668
666
  for (var i = 0; i < this.extraHeaders.length; ++i) {
669
667
  url += '&' + this.extraHeaders[i].key + '=' + this.extraHeaders[i].value;
670
668
  }
@@ -711,6 +709,7 @@ AlgoliaSearch.prototype = {
711
709
  if (this.tagFilters) {
712
710
  url += '&X-Algolia-TagFilters=' + encodeURIComponent(this.tagFilters);
713
711
  }
712
+ url += '&X-Algolia-Agent=' + encodeURIComponent(this._ua);
714
713
  for (var i = 0; i < this.extraHeaders.length; ++i) {
715
714
  url += '&' + this.extraHeaders[i].key + '=' + this.extraHeaders[i].value;
716
715
  }
@@ -786,6 +785,8 @@ AlgoliaSearch.prototype = {
786
785
  url += '&X-Algolia-UserToken=' + encodeURIComponent(this.userToken);
787
786
  }
788
787
 
788
+ url += '&X-Algolia-Agent=' + encodeURIComponent(this._ua);
789
+
789
790
  for (var i = 0; i < this.extraHeaders.length; ++i) {
790
791
  url += '&' + this.extraHeaders[i].key + '=' + this.extraHeaders[i].value;
791
792
  }
@@ -799,7 +800,7 @@ AlgoliaSearch.prototype = {
799
800
  clean();
800
801
 
801
802
  opts.callback(true, false, { 'message': 'Timeout - Failed to load JSONP script.' });
802
- }, this.requestTimeoutInMs);
803
+ }, this.requestTimeoutInMs * (opts.successiveRetryCount + 1));
803
804
 
804
805
  success = function() {
805
806
  if (done || timedOut) {
@@ -896,6 +897,8 @@ AlgoliaSearch.prototype = {
896
897
  url += '&X-Algolia-TagFilters=' + encodeURIComponent(this.tagFilters);
897
898
  }
898
899
 
900
+ url += '&X-Algolia-Agent=' + encodeURIComponent(this._ua);
901
+
899
902
  for (var i = 0; i < this.extraHeaders.length; ++i) {
900
903
  url += '&' + this.extraHeaders[i].key + '=' + this.extraHeaders[i].value;
901
904
  }
@@ -958,6 +961,13 @@ AlgoliaSearch.prototype = {
958
961
  opts.callback(retry, success, response);
959
962
  };
960
963
 
964
+ // we set an empty onprogress listener
965
+ // so that XDomainRequest on IE9 is not aborted
966
+ // refs:
967
+ // - https://github.com/algolia/algoliasearch-client-js/issues/76
968
+ // - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment
969
+ request.onprogress = function noop() {};
970
+
961
971
  if (this._support.timeout) {
962
972
  // .timeout supported by both XHR and XDR,
963
973
  // we do receive timeout event, tested
@@ -2661,6 +2671,7 @@ angular.module('algoliasearch', [])
2661
2671
  options.angular = {
2662
2672
  '$injector': $injector
2663
2673
  };
2674
+ options._ua = 'Algolia for AngularJS ' + window.ALGOLIA_VERSION;
2664
2675
  return new AlgoliaSearch(applicationID, apiKey, options);
2665
2676
  }
2666
2677
  };