PageSourceSearch

https://www.jhrl.com/sites/all/modules/bluetent/riot_solr/js/mixins.js?tlse4v

js jhrl.com collected 2026-10-06 13:17:48 UTC 33,374 bytes, 1,106 lines download raw bytes

1/**
2 * Init some global vars.
3 * @var RiotSolrCookieStore - this is the default browser storage mechanism for
4 * the RiotSolrFlag system. See it as an example of how you can implement your own.
5 * Storage mechanism will be instantiated via "new window['MyStorageVar']". So it's
6 * important to declare them in the global namespace. To add your own storage instance,
7 * you'll also need to implement hook_riot_solr_flag_stores_alter().
8 *
9 * @var RiotSolrCreateInstance - Super compact helper for calling constructors from a string.
10 *
11 * @var RiotSolrItemSortHandlers - Callback functions for sorting items.
12 *
13 * @var RiotSolrIntObs - Singular instance intersection observer
14 *
15 */
16var RiotSolrCookieStore, RiotSolrCreateInstance, RiotSolrItemSortHandlers,
17  RiotSolrIntObs = (typeof IntersectionObserver == 'undefined' || RiotTagsUtils.detectIE()) ? undefined : new IntersectionObserver(function(entries) {
18    for(ind in entries) {
19      if (entries[ind].target._tag) {
20        entries[ind].target._tag.trigger('RiotSolrIntersect', entries[ind])
21      }
22    }
23  }, {rootMargin: "80px 0px 80px 0px"});
24
25(function($) {
26  /**
27   *
28   * @type {{init: init, RiotSolrGetFacets: RiotSolrGetFacets, RiotSolrInitManager: RiotSolrInitManager}}
29   */
30  var RiotSolrConnection = {
31    init: function() {
32      var self = this;
33      if (!self.opts.solr) {
34        return;
35      }
36      self.RiotSolrInitManager();
37      if (typeof self.RiotSolrManager != 'undefined') {
38        self.RiotSolrManager.observable.on('RiotSolrRequestStart', function() {
39          $(self.root).addClass('pending');
40        });
41
42        self.RiotSolrManager.observable.on('RiotSolrRequestStop', function() {
43          $(self.root).removeClass('pending');
44        });
45
46        self.getChildExtraOptions = function(c) {
47          return {
48            manager: self.RiotSolrManager,
49            facets: self.RiotSolrFacets,
50          };
51        };
52      }
53
54      self.on('RiotSolrUpdate', function() {
55        self.RiotSolrManager.firstRequest = true;
56      });
57    },
58
59    RiotSolrGetFacets: function(options) {
60      var facets = [],
61        w,
62        f;
63      for (f in options.facets) {
64        if (options.facets.hasOwnProperty(f)) {
65          w = options.facets[f]['settings']['settings']['widget'];
66          if (this.RiotSolrManager.facetWidgetMap && typeof this.RiotSolrManager.facetWidgetMap[w] !== 'undefined') {
67            facets.push({
68              definition: options.facets[f],
69              field: options.fields[f]['solr_field'],
70              label: options.fields[f]['name'],
71              htmlTagName: this.RiotSolrManager.facetWidgetMap[w]['tag'],
72            });
73          }
74        }
75      }
76      return facets;
77    },
78
79    RiotSolrInitManager: function() {
80      var self = this,
81        name,
82        params = {
83          facet: true,
84          rows: self.opts.solr.max_rows,
85          'facet.range': [],
86          'facet.mincount': 1,
87          'json.nl': 'map',
88        },
89        constructorArgs = {
90          observable: self,
91          proxyUrl: self.opts.solr.url,
92          indexId: self.opts.solr.index,
93          bundles: self.opts.solr.bundles,
94          entityType: self.opts.solr.entity_type,
95          docCache: self.opts.solr.doc_cache,
96          requestCache: self.opts.solr.doc_cache,
97          exposedParams: self.opts.solr.exposed_params,
98          siteHash: self.opts.solr.hash,
99          facetWidgetMap: self.opts.facet_widget_map,
100          widgets: [],
101        };
102
103      if (self.opts.solr.index === 'inherit' || typeof self.opts.solr.index == 'undefined') {
104        if (typeof self.parent !== 'undefined') {
105          self.RiotSolrManager = self.parent.RiotSolrManager;
106        } else if (typeof self.opts.manager !== 'undefined') {
107          self.RiotSolrManager = self.opts.manager;
108        }
109      }
110
111      if (self.RiotSolrManager) {
112        if (!self.RiotSolrFacets && self.opts.facets) {
113          self.RiotSolrFacets = self.opts.facets;
114        } else {
115          self.RiotSolrFacets = [];
116        }
117      } else if (self.opts.solr.index != 'inherit' && typeof self.opts.solr.index != 'undefined') {
118        self.RiotSolrManager = new AjaxSolr.Manager(constructorArgs);
119        self.RiotSolrFacets = self.RiotSolrGetFacets(self.opts.solr);
120        self.RiotSolrManager.observable.on('RiotSolrBoot', function() {
121          self.RiotSolrManager.observable.trigger('RiotSolrAddWidgets', self.RiotSolrManager);
122          self.RiotSolrManager.init();
123          self.RiotSolrManager.observable.trigger('RiotSolrInit', self.RiotSolrManager, params);
124          if (self.RiotSolrManager.store.storedString() == '' && self.opts.solr.default_q) {
125            params['q'] = self.opts.solr.default_q;
126          }
127          if (!self.RiotSolrManager.store.get('boost').value && self.opts.solr.default_boost) {
128            if(!self.RiotSolrManager.store.get('bq') || !self.RiotSolrManager.store.get('bq').value) {
129              params['boost'] = self.opts.solr.default_boost;
130            }
131            params['defType'] = 'edismax';
132          }
133
134          if (self.opts.solr.params) {
135            params = $.extend(params, self.opts.solr.params);
136          }
137          for (name in params) {
138            self.RiotSolrManager.store.addByValue(name, params[name]);
139          }
140          if (self.opts.solr.max_rows > 0) {
141            self.RiotSolrManager.doRequest();
142          }
143          self.RiotSolrManager.observable.trigger('RiotSolrReady', self.RiotSolrManager);
144          RiotTagsDispatch.trigger('RiotSolrReady', self.RiotSolrManager.observable, self.RiotSolrManager);
145        });
146        self.one('updated', function() {
147          self.RiotSolrManager.observable.trigger('RiotSolrBoot');
148        });
149      }
150    },
151  };
152
153  riot.mixin('RiotSolrConnection', RiotSolrConnection);
154
155  /**
156   * Abstracts initializing a facet, maintaining a map of Drupal UI facet types to
157   * RiotSolr facet types.
158   * @type {{clickHandler: RiotSolrFacetProvider.clickHandler}}
159   */
160  var RiotSolrFacetProvider = {
161    init: function() {
162      var self = this;
163      self.mixin('RiotSolrConnection');
164
165      self.on(self.opts.widget + 'Update', function(results) {
166        self.items = this.FacetProcessItems(results);
167        self.update();
168      });
169
170      self.RiotSolrManager.observable.on('RiotSolrAddWidgets', function(manager) {
171        self.FacetBuildWidget(manager);
172      });
173    },
174
175    FacetGetDefinition: function() {
176      for (var f in this.RiotSolrFacets) {
177        if (this.RiotSolrFacets[f].definition.data.field === this.opts.facet_field) {
178          return this.RiotSolrFacets[f];
179        }
180      }
181      return false;
182    },
183
184    FacetClickHandler: function(value) {
185      if (value.item.active) {
186        this.FacetRemove(value);
187      } else {
188        this.FacetAdd(value);
189      }
190    },
191
192    FacetProcessParams: function(params) {
193      return params;
194    },
195
196    FacetFilterChars: function(str) {
197      return str.replace(/[\[\]\{\}\(\)\*\+\?\.\\]/g,"");
198    },
199
200    FacetBuildWidget: function(manager) {
201      var facetOpts = this.FacetGetDefinition(),
202        facetArgs,
203        realmSettings,
204        def = facetOpts.definition,
205        label = '';
206
207      for (var o in facetOpts) {
208        this.opts[o] = facetOpts[o];
209      }
210
211      if (typeof def == 'undefined') {
212        return;
213      }
214
215      if (typeof def.settings.settings['riot_solr'] !== 'undefined') {
216        realmSettings = def.settings.settings['riot_solr'];
217      }
218
219      if (
220        typeof realmSettings !== 'undefined' &&
221        typeof realmSettings.facet_label !== 'undefined' &&
222        realmSettings.facet_label !== ''
223      ) {
224        label = realmSettings.facet_label;
225      } else {
226        label = def.settings_global.settings['riotjs_label'];
227      }
228
229      this.opts.label = label;
230
231      facetArgs = {
232        id: this.opts.widget + '-' + this.opts.field,
233        target: '[data-facetId="' + this.opts.widget + '-' + this.opts.field + '"]',
234        field: this.opts.field,
235        label: label,
236        observable: this,
237        operator: def.settings_global.settings['operator'],
238        'facet.limit': def.settings_global.settings['hard_limit'],
239        'facet.field': this.opts.field,
240        'facet.missing': def.settings_global.settings['facet_missing'] > 0 ? 'true' : 'false',
241        multivalue: def.settings_global.settings['limit_active_items'] <= 0,
242      };
243
244      if (def.settings_global.settings['facet_mincount']) {
245        facetArgs['facet.mincount'] = def.settings_global.settings['facet_mincount'];
246      }
247      this.instance = new AjaxSolr[this.opts.widget](this.FacetProcessParams(facetArgs));
248
249      manager.addWidget(this.instance);
250    },
251
252    FacetProcessItems: function(results) {
253      var items = [],
254        self = this,
255        pattern,
256        k;
257      if (results.field === this.opts.field && results.widget === this.opts.widget) {
258        if (this.opts.definition.settings.settings.exclude) {
259          pattern = new RegExp(self.FacetFilterChars(this.opts.definition.settings.settings.exclude));
260          items = results.items.filter(function(item) {
261            return !pattern.test(self.FacetFilterChars(item.facet));
262          });
263        } else {
264          items = results.items;
265        }
266
267        // Process sorting options.
268        this.trigger('RiotSolrFacetProviderSort', {
269          'items': items,
270          'field': results.field,
271          'sortOptions': this.opts.definition.settings.settings.active_sorts,
272          'results': results,
273        });
274        RiotTagsDispatch.trigger('RiotSolrFacetProviderSort', {
275          'items': items,
276          'field': results.field,
277          'sortOptions': this.opts.definition.settings.settings.active_sorts,
278          'results': results,
279        });
280
281        for (k in items) {
282          (function(self) {
283            if (!items.hasOwnProperty(k)) {
284              return;
285            }
286            items[k]['active'] = self.IsActive(items[k].facet);
287          })(this);
288        }
289      }
290      return items;
291    },
292
293    /**
294     * @param value
295     * @constructor
296     */
297    FacetAdd: function(value) {
298      var meth = this.instance.multivalue ? 'add' : 'set';
299      if (this.instance[meth].call(this.instance, value.item.facet)) {
300        this.instance.doRequest();
301      }
302    },
303
304    /**
305     * @param value
306     * @constructor
307     */
308    FacetRemove: function(value) {
309      this.instance.remove(value.item.facet);
310      this.instance.doRequest();
311    },
312
313    /**
314     * @param value
315     * @constructor
316     */
317    FacetReset: function() {
318      this.instance.removeAll();
319      this.instance.doRequest();
320    },
321
322    /**
323     * @param facetValue
324     * @returns {boolean}
325     * @constructor
326     */
327    IsActive: function(facetValue) {
328      return this.instance.isActive(facetValue);
329    },
330  };
331
332  riot.mixin('RiotSolrFacetProvider', RiotSolrFacetProvider);
333
334  var RiotSolrItemsContainer = {
335    init: function() {
336      var self = this;
337
338      this.riotSolrItems = [];
339      this.items = [];
340
341      self.getChildExtraOptions = function() {
342        return {
343          manager: self.RiotSolrManager,
344        };
345      };
346
347      // Override process children
348      var procc = self.processChildren;
349      self.processChildren = function() {
350        procc.apply(self);
351        for (var c in self.children) {
352          if (self.children[c].tag === 'riot-solr-no-results' || self.children[c].tag === 'riot-solr-alternates') {
353            self.noResultsTag = self.children[c];
354            self.children.splice(c, 1);
355          }
356        }
357        if (typeof self.children != 'undefined' && self.children.length > 0) {
358          self.children[0].mounted = true;
359        }
360      };
361
362      (self.numvisible = parseInt(self.opts.numvisible)), (self.pagecount = parseInt(self.opts.numvisible));
363
364      self.RiotSolrManager.observable.on('RiotSolrUpdate', function(data) {
365        if (self.opts.solr.return_full_docs && data.response.getFullDocs) {
366          data.response.getFullDocs().done(function(docs) {
367            data.response.docs = docs;
368            self.RiotSolrManager.triggerEvents(data);
369            self.setRiotSolrItems(data.response.docs);
370          });
371        }
372      });
373      self.RiotSolrManager.observable.on('RiotSolrItemsSorted', function(data) {
374        self.setRiotSolrItems(data.items);
375      });
376
377      self.displayitems = [];
378
379      self.on('RiotSolrItemsUpdated', function() {
380        $.Deferred(function() {
381          self.items = self.getRiotSolrItems();
382          self.numvisible = parseInt(self.opts.numvisible);
383          if (self.numvisible > 0) {
384            self.displayitems = self.items.slice(0, self.numvisible);
385          } else {
386            self.displayitems = self.items;
387          }
388          self.update();
389          RiotTagsDispatch.trigger('RiotSolrItemsUpdated', self, self.items);
390          self.RiotSolrManager.observable.trigger('RiotSolrItemsUpdated', self, self.items);
391        });
392      });
393
394      self.on('RiotSolrItemsSorted', function(sorted) {
395        $.Deferred(function() {
396          self.items = sorted.items;
397          numvisible = self.opts.numvisible;
398          if (numvisible > 0) {
399            self.displayitems = self.items.slice(0, self.numvisible);
400          } else {
401            self.displayitems = self.items;
402          }
403          self.update();
404        });
405      });
406
407      if (self.numvisible > 0) {
408        (function($, tag) {
409          var scrollCallback = function(e) {
410            var resultsWrap = tag.root.querySelector('.result-list');
411            if (
412              resultsWrap &&
413              resultsWrap.lastElementChild !== null &&
414              resultsWrap.lastElementChild.isVisible() &&
415              tag.numvisible < tag.items.length
416            ) {
417              tag.numvisible += parseInt(tag.pagecount);
418              Array.prototype.push.apply(tag.displayitems, tag.items.slice(tag.displayitems.length, tag.numvisible));
419              tag.update();
420            }
421          };
422          // $(tag.root).scroll(scrollCallback);
423          document.addEventListener('scroll', scrollCallback);
424        })(jQuery, self);
425      }
426    },
427    setRiotSolrItems: function(items) {
428      this.riotSolrItems = items;
429      this.trigger('RiotSolrItemsUpdated', items);
430    },
431    getRiotSolrItems: function() {
432      return this.riotSolrItems;
433    },
434  };
435  riot.mixin('RiotSolrItemsContainer', RiotSolrItemsContainer);
436
437  var RiotSolrLinkedItem = {
438    RiotSolrLinkedItem: riot.observable(),
439  };
440  riot.mixin('RiotSolrLinkedItem', RiotSolrLinkedItem);
441
442  var RiotSolrIntersectionObserver = {
443    init: function() {
444      this.observeAfterFirstVisible = true;
445      this.on('mount', function() {
446        this.hasBeenVisible = false;
447        this.observeInt();
448      });
449      this.on('RiotSolrIntersect', function(data) {
450        // When visible first time, loadImages
451        if (data.isIntersecting) {
452          if (!this.hasBeenVisible) {
453            this.hasBeenVisible = true;
454            this.trigger('RiotSolrIntersectFirstVisible', data);
455
456            if (!this.observeAfterFirstVisible) {
457              this.unobserveInt();
458            }
459          }
460        }
461      });
462    },
463    unobserveInt: function() {
464      if (typeof RiotSolrIntObs != 'undefined') {
465        RiotSolrIntObs.unobserve(this.root);
466      }
467    },
468    observeInt: function() {
469      if (typeof RiotSolrIntObs != 'undefined') {
470        RiotSolrIntObs.observe(this.root);
471      }
472    },
473    canObserveInt: function() {
474      return typeof IntersectionObserver != 'undefined' && !RiotTagsUtils.detectIE();
475    },
476  };
477  riot.mixin('RiotSolrIntersectionObserver', RiotSolrIntersectionObserver);
478
479  var RiotSolrLazyImage = {
480    init: function() {
481      this.mixin('RiotSolrIntersectionObserver');
482      this.observeAfterFirstVisible = false;
483      this.on('RiotSolrIntersectFirstVisible', function(data) {
484        // When visible first time, loadImages
485        this.loadImages();
486      });
487    },
488    loadImages: function() {
489      $('img[data-src]:not(.RiotSolrLazyLoaded)', this.root).each(function() {
490        $(this).attr('src', $(this).attr('data-src')).addClass('RiotSolrLazyLoaded');
491      });
492    },
493  };
494  riot.mixin('RiotSolrLazyImage', RiotSolrLazyImage);
495
496  var RiotSolrIf = {
497    _if: function(expr) {
498      return expr ? [expr] : [];
499    },
500  };
501
502  riot.mixin(RiotSolrIf);
503
504  var RiotSolrItem = {
505    init: function() {
506      var self = this,
507        ext = self.getChildExtraOptions;
508      self.getChildExtraOptions = function(c) {
509        var opts = ext.apply(c);
510        opts['item'] = self.RiotSolrGetItem();
511        opts['manager'] = self.RiotSolrManager;
512        return opts;
513      };
514      self.valueOrFirst = function(value) {
515        return Array.isArray(value) ? value[0] : value;
516      };
517
518      this.one('updated', function() {
519        RiotTagsDispatch.trigger('RiotSolrResultItemMounted', self, self.opts);
520      });
521    },
522
523    RiotSolrGetItem: function() {
524      return this.item;
525    },
526  };
527
528  riot.mixin('RiotSolrItem', RiotSolrItem);
529
530  var RiotSolrFlag = {
531    init: function() {
532      var self = this,
533        item = self.opts.item;
534
535      if (self.opts.flag_options) {
536        self.RiotSolrFlagOpts = self.opts.flag_options;
537      }
538
539      if (self.RiotSolrFlagOpts.skip_solr && self.RiotSolrFlagOpts.skip_solr_prefix) {
540        self.flagItemID = self.RiotSolrFlagOpts.skip_solr_prefix + self.opts.eid;
541        self.RiotSolrFlagSetFlag();
542      }
543      else {
544        if (!item) {
545          self.RiotSolrManager.observable.on('RiotSolrReady', function() {
546            self.RiotSolrManager.getDocumentsByKeys([self.opts.eid]).done(function(docs) {
547              self.RiotSolrFlagSetItem(docs[0]);
548            });
549          });
550        } else {
551          self.one('update', function () {
552            self.RiotSolrFlagSetItem(item);
553          });
554        }
555      }
556
557      /**
558       * When updates come from an outside source
559       */
560      RiotTagsDispatch.on('RiotSolrFlagUpdate', function(tag, namespace) {
561        if (
562          tag._riot_id !== self._riot_id &&
563          self.RiotSolrFlagOpts.namespace === namespace &&
564          self.flagItemID === tag.flagItemID
565        ) {
566          self.RiotSolrFlagClass = tag.RiotSolrFlagClass;
567          self.RiotSolrFlagText = tag.RiotSolrFlagText;
568          self.update();
569        }
570      });
571    },
572
573    RiotSolrFlagSetItem: function(item) {
574      if(item) {
575        this.flagItemID = item[this.RiotSolrFlagOpts.key] + ''; //always force to a string
576        this.RiotSolrFlagSetFlag();
577      }
578    },
579
580    RiotSolrFlagSetFlag: function() {
581      this.RiotSolrFlagInitStore();
582      if (this.RiotSolrFlagStore.has(this.flagItemID)) {
583        this.RiotSolrFlagText = this.RiotSolrFlagOpts.text.unflag;
584        this.RiotSolrFlagClass = this.RiotSolrFlagOpts.classes.unflag;
585      } else {
586        this.RiotSolrFlagText = this.RiotSolrFlagOpts.text.flag;
587        this.RiotSolrFlagClass = this.RiotSolrFlagOpts.classes.flag;
588      }
589      this.update();
590    },
591
592    RiotSolrFlagInitStore: function() {
593      this.RiotSolrFlagStore = RiotSolrCreateInstance(this.RiotSolrFlagOpts.store, this.RiotSolrFlagOpts.namespace);
594    },
595
596    RiotSolrFlagOpts: {
597      text: {
598        flag: 'Flag',
599        unflag: 'Unflag',
600      },
601      classes: {
602        flag: 'rs-flag',
603        unflag: 'rs-unflag',
604      },
605      namespace: 'riot_solr_flag_items',
606      store: 'RiotSolrCookieStore',
607      key: 'id',
608    },
609
610    RiotSolrHandleFlag: function(e) {
611      var self = this,
612        store = self.RiotSolrFlagStore;
613
614      if (store.has(self.flagItemID)) {
615        store.remove(self.flagItemID);
616        self.RiotSolrFlagText = self.RiotSolrFlagOpts.text.flag;
617        self.RiotSolrFlagClass = self.RiotSolrFlagOpts.classes.flag;
618      } else {
619        store.add(self.flagItemID);
620        self.RiotSolrFlagText = self.RiotSolrFlagOpts.text.unflag;
621        self.RiotSolrFlagClass = self.RiotSolrFlagOpts.classes.unflag;
622      }
623      RiotTagsDispatch.trigger('RiotSolrFlagUpdate', this, this.RiotSolrFlagOpts.namespace);
624      self.update();
625    },
626  };
627
628  riot.mixin('RiotSolrFlag', RiotSolrFlag);
629
630  var RiotSolrFlagCounter = {
631    init: function() {
632      var self = this,
633        fcu;
634
635      self.RiotSolrManager.observable.on('RiotSolrInit', function(manager) {
636        self.RiotSolrManager.setStore(new AjaxSolr.ParameterStore());
637        self.RiotSolrManager.store.load(false);
638        self.RiotSolrManager.store.init();
639      });
640
641      if (self.opts.flag_options) {
642        self.RiotSolrFlagOpts = self.opts.flag_options;
643      }
644
645      self.showItems = false;
646
647      self.RiotSolrFlagStore = RiotSolrCreateInstance(self.opts.flag_options.store, self.opts.flag_options.namespace);
648
649      fcu = function() {
650        self.RiotSolrFlagCounterUpdate();
651      };
652
653      RiotTagsDispatch.on('RiotSolrFlagUpdate', fcu);
654
655      self.one('update', function() {
656        self.RiotSolrFlagCount = self.RiotSolrFlagStore.get().length;
657      });
658
659      self.one('updated', function() {
660        self.root.addEventListener('mouseenter', function() {
661          self.showItems = true;
662          fcu();
663        });
664
665        self.root.addEventListener('mouseleave', function() {
666          self.showItems = false;
667          self.update();
668        });
669      });
670
671      self.on('unmount', function() {
672        RiotTagsDispatch.off('RiotSolrFlagUpdate', fcu);
673      });
674    },
675
676    RiotSolrFlagOpts: {
677      text: {
678        flag: 'Flag',
679        unflag: 'Unflag',
680      },
681      classes: {
682        flag: 'rs-flag',
683        unflag: 'rs-unflag',
684      },
685      namespace: 'riot_solr_flag_items',
686      store: 'RiotSolrCookieStore',
687      key: 'id',
688    },
689
690    /**
691     * Override the default handler for RiotSolrFlag. Do everything the default handler does except triggering
692     * RiotSolrUpdate. Doing so would replace the search results data with data for favorites.
693     *
694     * @param response
695     * @constructor
696     */
697    RiotSolrFlagHandler: function(response) {
698      var manager = this.RiotSolrManager,
699        p,
700        docids;
701
702      manager.response = response;
703      docids = response.response.docs.map(function(e) {
704        return e.id;
705      });
706
707      response.getFullDocs = function() {
708        if (!p) {
709          p = manager.getDocuments(docids);
710        }
711        return p;
712      }
713
714      manager.widgets.map(function(widget) {
715        widget.afterRequest();
716      });
717
718      this.setRiotSolrItems(response.response.docs);
719      this.update();
720    },
721
722    RiotSolrFlagCounterUpdate: function() {
723      var ids = this.RiotSolrFlagStore.get(),
724        self = this,
725        string = 'rows=' + ids.length + '&fq=' + self.RiotSolrFlagOpts.key + ':(' + ids.join(' OR ') + ')';
726      self.RiotSolrFlagCount = ids.length;
727      if (ids.length > 0) {
728        self.RiotSolrManager.executeRequest('select', string, this.RiotSolrFlagHandler);
729      } else {
730        self.setRiotSolrItems([]);
731      }
732    },
733
734    RiotSolrFlagCounterViewPage: function() {
735      var path, ids, q;
736
737      if (!this.opts.flag_options.path) {
738        return;
739      }
740
741      ids = this.RiotSolrFlagStore.get();
742      if (ids.length > 0) {
743        path = this.opts.flag_options.path;
744        q = this.RiotSolrFlagOpts.key + ':(' + ids.join(' OR ') + ')';
745        window.location.href = path + '#q=' + q;
746      }
747    },
748  };
749
750  riot.mixin('RiotSolrFlagCounter', RiotSolrFlagCounter);
751
752  /**
753   * GLobal Objects
754   */
755
756  RiotSolrCreateInstance = function(strClass) {
757    var args = Array.prototype.slice.call(arguments, 1);
758    return new window[strClass](args);
759  };
760
761  RiotSolrCookieStore = function(namespace) {
762    // Private vars.
763    var _namespace = namespace,
764      _items = [],
765      cookie;
766
767    // Private update method. This is used to refresh the objects with cookie
768    // data so that collections on multiple open tabs will work properly.
769    var refresh = function() {
770      // Load cookie values.
771      cookie = $.cookie(_namespace);
772      // Populate items from cookie.
773      _items[_namespace] = cookie ? $.parseJSON(cookie) : [];
774    }; // Don't auto-execute so we lazy-load fetching cookie data.
775
776    // Private save method.
777    var save = function() {
778      $.cookie(_namespace, JSON.stringify(_items[_namespace]), { path: '/' });
779    };
780
781    // Public get methd.
782    this.get = function() {
783      refresh();
784      return _items[_namespace];
785    };
786
787    // Public add method.
788    this.add = function(val) {
789      refresh();
790      // Don't add duplicate items.
791      if (_items[_namespace].indexOf(val) === -1) {
792        _items[_namespace].push(val);
793        save();
794      }
795
796      if (typeof ga4 !== 'undefined') {
797        ga4.event({
798          event: 'add_' + _namespace,
799          value: val,
800          eventCategory: 'RiotSolr Flag',
801          eventAction: 'Add ' + _namespace,
802          eventLabel: val,
803        });
804      }
805
806      if (typeof ga !== 'undefined') {
807        ga('send', {
808          hitType: 'event',
809          eventCategory: 'RiotSolr Flag',
810          eventAction: 'Add ' + _namespace,
811          eventLabel: val,
812          nonInteraction: 1,
813        });
814      } else if (typeof _gaq !== 'undefined') {
815        _gaq.push(['_trackEvent', 'RiotSolr Flag', 'Add ' + _namespace, val, 0, true]);
816      }
817    };
818
819    // Public remove method.
820    this.remove = function(val) {
821      refresh();
822      // We can't use this.has() here because we need the index.
823      var index = _items[_namespace].indexOf(val);
824
825      if (index !== -1) {
826        _items[_namespace].splice(index, 1);
827        save();
828      }
829
830      if (typeof ga4 !== 'undefined') {
831        ga4.event({
832          event: 'remove_' + _namespace,
833          value: val,
834          eventCategory: 'RiotSolr Flag',
835          eventAction: 'Remove ' + _namespace,
836          eventLabel: val,
837        });
838      }
839
840      if (typeof ga !== 'undefined') {
841        ga('send', {
842          hitType: 'event',
843          eventCategory: 'RiotSolr Flag',
844          eventAction: 'Remove ' + _namespace,
845          eventLabel: val,
846          nonInteraction: 1,
847        });
848      } else if (typeof _gaq !== 'undefined') {
849        _gaq.push(['_trackEvent', 'RiotSolr Flag', 'Remove ' + _namespace, val, 0, true]);
850      }
851    };
852
853    // Public reset method.
854    this.reset = function() {
855      _items[_namespace] = [];
856      save();
857    };
858
859    // Public lookup method.
860    this.has = function(val) {
861      refresh();
862      // IE 8 and below do not have the Array.prototype.indexOf method.
863      return this.indexOf.call(_items[_namespace], val) !== -1;
864    };
865
866    // Shim for IE8 and below not supporting indexOf natively.
867    // Public so others can use it.
868    this.indexOf = function(needle) {
869      var indexOf;
870
871      if (typeof Array.prototype.indexOf === 'function') {
872        indexOf = Array.prototype.indexOf;
873      } else {
874        indexOf = function(needle) {
875          var i = -1,
876            index = -1;
877
878          for (i = 0; i < this.length; i++) {
879            if (this[i] === needle) {
880              index = i;
881              break;
882            }
883          }
884
885          return index;
886        };
887      }
888
889      return indexOf.call(this, needle);
890    };
891  };
892
893  RiotSolrItemSortHandlers = {
894    sortNumeric: {
895      primer: function(x) {
896        return parseFloat(x);
897      },
898      callback: function(items, field, reverse) {
899        var self = this,
900          r = !reverse ? 1 : -1;
901        items.sort(function(a, b) {
902          return (a = self.primer(a[field])), (b = self.primer(b[field])), r * ((a > b) - (b > a));
903        });
904        return items;
905      },
906    },
907
908    sortLexicographic: {
909      primer: function(x) {
910        if (typeof x === 'string') {
911          return x.trim();
912        } else if (Array.isArray(x)) {
913          return x[0].trim();
914        }
915      },
916      callback: function(items, field, reverse) {
917        var self = this;
918        items.sort(function(a, b) {
919          return (a = self.primer(a[field])), (b = self.primer(b[field])), a.toLowerCase().localeCompare(b);
920        });
921
922        if (reverse) {
923          items.reverse();
924        }
925
926        return items;
927      },
928    },
929
930    sortRandom: {
931      primer: function() {
932        var max = 9999,
933          min = 1;
934        return Math.floor(Math.random() * (max - min)) + min;
935      },
936      callback: function(items, field, reverse) {
937        var self = this,
938          r = !reverse ? 1 : -1;
939        items.sort(function() {
940          return (a = self.primer()), (b = self.primer()), r * ((a > b) - (b > a));
941        });
942        return items;
943      },
944    },
945  };
946
947  /**
948   * Author: Jason Farrell
949   * Author URI: http://useallfive.com/
950   *
951   * Description: Checks if a DOM element is truly visible.
952   * Package URL: https://github.com/UseAllFive/true-visibility
953   */
954  Element.prototype.isVisible = function() {
955    'use strict';
956    /**
957     * Checks if a DOM element is visible. Takes into
958     * consideration its parents and overflow.
959     *
960     * @param (el)      the DOM element to check if is visible
961     *
962     * These params are optional that are sent in recursively,
963     * you typically won't use these:
964     *
965     * @param (t)       Top corner position number
966     * @param (r)       Right corner position number
967     * @param (b)       Bottom corner position number
968     * @param (l)       Left corner position number
969     * @param (w)       Element width number
970     * @param (h)       Element height number
971     */
972    function _isVisible(el, t, r, b, l, w, h) {
973      var p = el.parentNode,
974        VISIBLE_PADDING = 2;
975
976      if (!_elementInViewport(el)) {
977        return false;
978      }
979
980      if (!_elementInDocument(el)) {
981        return false;
982      }
983
984      //-- Return true for document node
985      if (9 === p.nodeType) {
986        return true;
987      }
988
989      //-- Return false if our element is invisible
990      if (
991        '0' === _getStyle(el, 'opacity') ||
992        'none' === _getStyle(el, 'display') ||
993        'hidden' === _getStyle(el, 'visibility')
994      ) {
995        return false;
996      }
997
998      if (
999        'undefined' === typeof t ||
1000        'undefined' === typeof r ||
1001        'undefined' === typeof b ||
1002        'undefined' === typeof l ||
1003        'undefined' === typeof w ||
1004        'undefined' === typeof h
1005      ) {
1006        t = el.offsetTop;
1007        l = el.offsetLeft;
1008        b = t + el.offsetHeight;
1009        r = l + el.offsetWidth;
1010        w = el.offsetWidth;
1011        h = el.offsetHeight;
1012      }
1013      //-- If we have a parent, let's continue:
1014      if (p) {
1015        //-- Check if the parent can hide its children.
1016        if (
1017          'hidden' === _getStyle(p, 'overflow') ||
1018          'scroll' === _getStyle(p, 'overflow') ||
1019          'hidden' === _getStyle(p, 'overflow-y') ||
1020          'scroll' === _getStyle(p, 'overflow-y')
1021        ) {
1022          //-- Only check if the offset is different for the parent
1023          if (
1024            //-- If the target element is to the right of the parent elm
1025            l + VISIBLE_PADDING > p.offsetWidth + p.scrollLeft ||
1026            //-- If the target element is to the left of the parent elm
1027            l + w - VISIBLE_PADDING < p.scrollLeft ||
1028            //-- If the target element is under the parent elm
1029            t + VISIBLE_PADDING > p.offsetHeight + p.scrollTop ||
1030            //-- If the target element is above the parent elm
1031            t + h - VISIBLE_PADDING < p.scrollTop
1032          ) {
1033            //-- Our target element is out of bounds:
1034            return false;
1035          }
1036        }
1037        //-- Add the offset parent's left/top coords to our element's offset:
1038        if (el.offsetParent === p) {
1039          l += p.offsetLeft;
1040          t += p.offsetTop;
1041        }
1042        //-- Let's recursively check upwards:
1043        return _isVisible(p, t, r, b, l, w, h);
1044      }
1045      return true;
1046    }
1047
1048    //-- Cross browser method to get style properties:
1049    function _getStyle(el, property) {
1050      if (window.getComputedStyle) {
1051        return document.defaultView.getComputedStyle(el, null)[property];
1052      }
1053      if (el.currentStyle) {
1054        return el.currentStyle[property];
1055      }
1056    }
1057
1058    function _elementInDocument(element) {
1059      while ((element = element.parentNode)) {
1060        if (element == document) {
1061          return true;
1062        }
1063      }
1064      return false;
1065    }
1066
1067    function _elementInViewport(element) {
1068      var VISIBLE_PADDING = 2;
1069
1070      var br = element.getBoundingClientRect();
1071      var ret =
1072        br.top - VISIBLE_PADDING <= (window.innerHeight || document.documentElement.clientHeight) &&
1073        br.bottom >= 0 - VISIBLE_PADDING &&
1074        br.left - VISIBLE_PADDING <= (window.innerWidth || document.documentElement.clientWidth) &&
1075        br.right >= 0 - VISIBLE_PADDING;
1076      return ret;
1077    }
1078
1079    return _isVisible(this);
1080  };
1081
1082  /**
1083   * A utilities helper object.
1084   *
1085   * Purposefully namespaced to prevent collisions.
1086   */
1087  var RiotSolrUtils = {
1088    RiotSolrUtils: {
1089      debounce: function (func, wait, immediate) {
1090        var timeout;
1091        return function() {
1092          var context = this, args = arguments;
1093          clearTimeout(timeout);
1094          timeout = setTimeout(function() {
1095            timeout = null;
1096            if (!immediate) func.apply(context, args);
1097          }, wait);
1098          if (immediate && !timeout) func.apply(context, args);
1099        };
1100      }
1101    }
1102  }
1103
1104  riot.mixin('RiotSolrUtils', RiotSolrUtils);
1105
1106})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.