blacklight_range_limit 7.9.1 → 8.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 68ba781f0cbb0071d01c7c4f271e2f313acb1d9c12b867ccc49fdc707c886b4f
4
- data.tar.gz: 9653d4141da91db97aa7130563fe5048dab111e5e42ccc46ec820aa1477d3d84
3
+ metadata.gz: b8c8deb666a17d47f0972d7d85098ec88b0d980c12d92cd7fa554b943ee36ff6
4
+ data.tar.gz: 7696cd12ba7d0c1b2ce4c4c451190ca36398edbae08edb2966dcb1575aa63692
5
5
  SHA512:
6
- metadata.gz: 7ea0eac18d3819f38f2b92fc103cca7023553d9d8c3cac27561b8d8c188825f46f6d6f5f270876162c46864a53d7fb4902cd2d7855dcd58b74790156993eb0bb
7
- data.tar.gz: 35295bea937bb314c4354d20f1f0d7962f702096af42c079bd74b76feb985019d21513b12049dd52e3578245ffd04e1aa79a731e12bd70e34cff58b71ff77775
6
+ metadata.gz: 935f5b470677a89d09bd510b84be8319675ce0873da638218083dd54f328138737b39a0b1f0d0912e4ca18a163f47cd90b77136199a29eaadd662bed7e863d00
7
+ data.tar.gz: 763fdb463b094db59d12ead36b0e44a487aeb3ca85e6608479de898868aa669a78ed52ca2c5e01aaf6651cefc780a2b8940aec576939a798c6f0104e75e25e9a
@@ -0,0 +1,76 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: CI
9
+
10
+ on:
11
+ push:
12
+ branches: [ master ]
13
+ pull_request:
14
+ branches: [ master ]
15
+
16
+ jobs:
17
+ test:
18
+ runs-on: ubuntu-latest
19
+ strategy:
20
+ matrix:
21
+ rails_version: [6.1.1]
22
+ ruby: [2.7, 3.0]
23
+ env:
24
+ RAILS_VERSION: ${{ matrix.rails_version }}
25
+ steps:
26
+ - uses: actions/checkout@v2
27
+ - name: Set up Ruby
28
+ uses: ruby/setup-ruby@v1
29
+ with:
30
+ ruby-version: ${{ matrix.ruby }}
31
+ - name: Install dependencies with Rails ${{ matrix.rails_version }}
32
+ run: bundle install
33
+ - name: Run tests
34
+ run: bundle exec rake
35
+ env:
36
+ ENGINE_CART_RAILS_OPTIONS: '--skip-git --skip-listen --skip-spring --skip-keeps --skip-action-cable --skip-coffee --skip-test'
37
+ test_rails6_0:
38
+ runs-on: ubuntu-latest
39
+ strategy:
40
+ matrix:
41
+ ruby: [2.6]
42
+ steps:
43
+ - uses: actions/checkout@v2
44
+ - name: Set up Ruby
45
+ uses: ruby/setup-ruby@v1
46
+ with:
47
+ ruby-version: ${{ matrix.ruby }}
48
+ - name: Install dependencies
49
+ run: bundle install
50
+ env:
51
+ RAILS_VERSION: 6.0.3.4
52
+ - name: Run tests
53
+ run: bundle exec rake
54
+ env:
55
+ RAILS_VERSION: 6.0.3.4
56
+ ENGINE_CART_RAILS_OPTIONS: '--skip-git --skip-listen --skip-spring --skip-keeps --skip-action-cable --skip-coffee --skip-test'
57
+ test_rails5_2:
58
+ runs-on: ubuntu-latest
59
+ strategy:
60
+ matrix:
61
+ ruby: [2.5]
62
+ steps:
63
+ - uses: actions/checkout@v2
64
+ - name: Set up Ruby
65
+ uses: ruby/setup-ruby@v1
66
+ with:
67
+ ruby-version: ${{ matrix.ruby }}
68
+ - name: Install dependencies
69
+ run: bundle install
70
+ env:
71
+ RAILS_VERSION: 5.2.4.2
72
+ - name: Run tests
73
+ run: bundle exec rake
74
+ env:
75
+ RAILS_VERSION: 5.2.4.2
76
+ ENGINE_CART_RAILS_OPTIONS: '--skip-git --skip-listen --skip-spring --skip-keeps --skip-action-cable --skip-coffee --skip-test'
data/Gemfile CHANGED
@@ -36,13 +36,6 @@ else
36
36
  case ENV['RAILS_VERSION']
37
37
  when /^5.[12]/, /^6.0/
38
38
  gem 'sass-rails', '~> 5.0'
39
- when /^4.2/
40
- gem 'responders', '~> 2.0'
41
- gem 'sass-rails', '>= 5.0'
42
- gem 'coffee-rails', '~> 4.1.0'
43
- gem 'json', '~> 1.8'
44
- when /^4.[01]/
45
- gem 'sass-rails', '< 5.0'
46
39
  end
47
40
  end
48
41
  # END ENGINE_CART BLOCK
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  BlacklightRangeLimit: integer range limiting and profiling for Blacklight applications
2
2
 
3
- [![Build Status](https://travis-ci.org/projectblacklight/blacklight_range_limit.png?branch=v5.0.0)](https://travis-ci.org/projectblacklight/blacklight_range_limit) [![Gem Version](https://badge.fury.io/rb/blacklight_range_limit.png)](http://badge.fury.io/rb/blacklight_range_limit)
3
+ ![Build Status](https://github.com/projectblacklight/blacklight/workflows/CI/badge.svg) [![Gem Version](https://badge.fury.io/rb/blacklight_range_limit.png)](http://badge.fury.io/rb/blacklight_range_limit)
4
4
 
5
5
  ![Screen shot](doc/example-screenshot.png)
6
6
 
@@ -133,6 +133,33 @@ ourselves yet.
133
133
  Also not sure how well the flot select UI works on a touch screen. The slider
134
134
  is probably the best touch UI anyway, if it can be made to work well.
135
135
 
136
+ ## JavaScript Customization
137
+
138
+ There are two main types of JavaScript implemented for BlacklightRangeLimit:
139
+ - Initialization and refresh of Range Limit plugin based off of events
140
+ - Range Limit plugin functionality called from event listeners
141
+
142
+ The second class of range limit functionality is customizable in your local application by overriding the specified function.
143
+
144
+ A simple example of this is overriding the display ratio used to create the histogram
145
+
146
+ ```javascript
147
+ BlacklightRangeLimit.display_ratio = 1
148
+ ```
149
+
150
+ This will now create a square histogram.
151
+
152
+ Not only these variables and functions be customized, you can call them based off of custom events in your application.
153
+
154
+ ```javascript
155
+ $('.custom-class').on('doSomething', function() {
156
+ BlacklightRangeLimit.checkForNeededFacetsToFetch();
157
+ $(".range_limit .profile .range.slider_js").each(function() {
158
+ BlacklightRangeLimit.buildSlider(this);
159
+ });
160
+ });
161
+ ```
162
+
136
163
  # Tests
137
164
 
138
165
  Test coverage is not great, but there are some tests, using rspec. Run `bundle exec rake ci` or just `bundle exec rake` to seed and
data/VERSION CHANGED
@@ -1 +1 @@
1
- 7.9.1
1
+ 8.0.0
@@ -17,4 +17,8 @@
17
17
  //= require 'flot/jquery.flot.selection.js'
18
18
  //= require 'bootstrap-slider'
19
19
 
20
- //= require_tree './blacklight_range_limit'
20
+ // Ensure that range_limit_shared is loaded first
21
+ //= require 'blacklight_range_limit/range_limit_shared'
22
+ //= require 'blacklight_range_limit/range_limit_plotting'
23
+ //= require 'blacklight_range_limit/range_limit_slider'
24
+ //= require 'blacklight_range_limit/range_limit_distro_facets'
@@ -1,23 +1,19 @@
1
1
  // for Blacklight.onLoad:
2
2
 
3
- /* A custom event "plotDrawn.blacklight.rangeLimit" will be sent when flot plot
4
- is (re-)drawn on screen possibly with a new size. target of event will be the DOM element
5
- containing the plot. Used to resize slider to match. */
3
+ /**
4
+ * Closure functions in this file are mainly concerned with initializing, resizing, and updating
5
+ * range limit functionality based off of page load, facet opening, page resizing, and otherwise
6
+ * events.
7
+ */
6
8
 
7
9
  Blacklight.onLoad(function() {
8
- // ratio of width to height for desired display, multiply width by this ratio
9
- // to get height. hard-coded in for now.
10
- var display_ratio = 1/(1.618 * 2); // half a golden rectangle, why not
11
- var redrawnEvent = "plotDrawn.blacklight.rangeLimit";
12
-
13
-
14
10
 
15
11
  // Facets already on the page? Turn em into a chart.
16
12
  $(".range_limit .profile .distribution.chart_js ul").each(function() {
17
- turnIntoPlot($(this).parent());
13
+ BlacklightRangeLimit.turnIntoPlot($(this).parent());
18
14
  });
19
15
 
20
- checkForNeededFacetsToFetch();
16
+ BlacklightRangeLimit.checkForNeededFacetsToFetch();
21
17
 
22
18
  // Listen for twitter bootstrap collapsible open events, to render flot
23
19
  // in previously hidden divs on open, if needed.
@@ -31,66 +27,23 @@ Blacklight.onLoad(function() {
31
27
  // have width -- right away on show.bs is too soon, but
32
28
  // shown.bs is later than we want, we want to start rendering
33
29
  // while animation is still in progress.
34
- turnIntoPlot(container, 1100);
30
+ BlacklightRangeLimit.turnIntoPlot(container, 1100);
35
31
  }
36
32
  });
37
33
 
38
34
  // When loaded in a modal
39
35
  $(Blacklight.modal.modalSelector).on('shown.bs.modal', function() {
40
36
  $(this).find(".range_limit .profile .distribution.chart_js ul").each(function() {
41
- turnIntoPlot($(this).parent());
37
+ BlacklightRangeLimit.turnIntoPlot($(this).parent());
42
38
  });
43
39
 
44
40
  // Case when there is no currently selected range
45
- checkForNeededFacetsToFetch();
41
+ BlacklightRangeLimit.checkForNeededFacetsToFetch();
46
42
  });
47
43
 
48
- // Add AJAX fetched range facets if needed, and add a chart to em
49
- function checkForNeededFacetsToFetch() {
50
- $(".range_limit .profile .distribution a.load_distribution").each(function() {
51
- var container = $(this).parent('div.distribution');
52
-
53
- $(container).load($(this).attr('href'), function(response, status) {
54
- if ($(container).hasClass("chart_js") && status == "success" ) {
55
- turnIntoPlot(container);
56
- }
57
- });
58
- });
59
- }
60
-
61
-
62
- // after a collapsible facet contents is fully shown,
63
- // resize the flot chart to current conditions. This way, if you change
64
- // browser window size, you can get chart resized to fit by closing and opening
65
- // again, if needed.
66
-
67
- function redrawPlot(container) {
68
- if (container && container.width() > 0) {
69
- // resize the container's height, since width may have changed.
70
- container.height( container.width() * display_ratio );
71
-
72
- // redraw the chart.
73
- var plot = container.data("plot");
74
- if (plot) {
75
- // how to redraw after possible resize?
76
- // Cribbed from https://github.com/flot/flot/blob/master/jquery.flot.resize.js
77
- plot.resize();
78
- plot.setupGrid();
79
- plot.draw();
80
- // plus trigger redraw of the selection, which otherwise ain't always right
81
- // we'll trigger a fake event on one of the boxes
82
- var form = $(container).closest(".limit_content").find("form.range_limit");
83
- form.find("input.range_begin").trigger("change");
84
-
85
- // send our custom event to trigger redraw of slider
86
- $(container).trigger(redrawnEvent);
87
- }
88
- }
89
- }
90
-
91
44
  $("body").on("shown.bs.collapse", function(event) {
92
45
  var container = $(event.target).filter(".facet-content").find(".chart_js");
93
- redrawPlot(container);
46
+ BlacklightRangeLimit.redrawPlot(container);
94
47
  });
95
48
 
96
49
  // debouce borrowed from underscore
@@ -115,197 +68,7 @@ Blacklight.onLoad(function() {
115
68
 
116
69
  $(window).on("resize", debounce(function() {
117
70
  $(".chart_js").each(function(i, container) {
118
- redrawPlot($(container));
71
+ BlacklightRangeLimit.redrawPlot($(container));
119
72
  });
120
73
  }, 350));
121
-
122
- // second arg, if provided, is a number of ms we're willing to
123
- // wait for the container to have width before giving up -- we'll
124
- // set 50ms timers to check back until timeout is expired or the
125
- // container is finally visible. The timeout is used when we catch
126
- // bootstrap show event, but the animation hasn't barely begun yet -- but
127
- // we don't want to wait until it's finished, we want to start rendering
128
- // as soon as we can.
129
- //
130
- // We also will
131
- function turnIntoPlot(container, wait_for_visible) {
132
- // flot can only render in a a div with a defined width.
133
- // for instance, a hidden div can't generally be rendered in (although if you set
134
- // an explicit width on it, it might work)
135
- //
136
- // We'll count on later code that catch bootstrap collapse open to render
137
- // on show, for currently hidden divs.
138
-
139
- // for some reason width sometimes return negative, not sure
140
- // why but it's some kind of hidden.
141
- if (container.width() > 0) {
142
- var height = container.width() * display_ratio;
143
-
144
- // Need an explicit height to make flot happy.
145
- container.height( height )
146
-
147
- areaChart($(container));
148
-
149
- $(container).trigger(redrawnEvent);
150
- }
151
- else if (wait_for_visible > 0) {
152
- setTimeout(function() {
153
- turnIntoPlot(container, wait_for_visible - 50);
154
- }, 50);
155
- }
156
- }
157
-
158
- // Takes a div holding a ul of distribution segments produced by
159
- // blacklight_range_limit/_range_facets and makes it into
160
- // a flot area chart.
161
- function areaChart(container) {
162
- //flot loaded? And canvas element supported.
163
- if ( domDependenciesMet() ) {
164
-
165
- // Grab the data from the ul div
166
- var series_data = new Array();
167
- var pointer_lookup = new Array();
168
- var x_ticks = new Array();
169
- var min = BlacklightRangeLimit.parseNum($(container).find("ul li:first-child span.from").first().data('blrlBegin'));
170
- var max = BlacklightRangeLimit.parseNum($(container).find("ul li:last-child span.to").first().data('blrlEnd'));
171
-
172
- $(container).find("ul li").each(function() {
173
- var from = BlacklightRangeLimit.parseNum($(this).find("span.from").first().data('blrlBegin'));
174
- var to = BlacklightRangeLimit.parseNum($(this).find("span.to").first().data('blrlEnd'));
175
- var count = BlacklightRangeLimit.parseNum($(this).find("span.count").text());
176
- var avg = (count / (to - from + 1));
177
-
178
-
179
- //We use the avg as the y-coord, to make the area of each
180
- //segment proportional to how many documents it holds.
181
- series_data.push( [from, avg ] );
182
- series_data.push( [to+1, avg] );
183
-
184
- x_ticks.push(from);
185
-
186
- pointer_lookup.push({'from': from, 'to': to, 'count': count, 'label': $(this).find(".facet_select").html() });
187
- });
188
- var max_plus_one = BlacklightRangeLimit.parseNum($(container).find("ul li:last-child span.to").text())+1;
189
- x_ticks.push( max_plus_one );
190
-
191
-
192
-
193
- var plot;
194
- var config = $(container).closest('.blrl-plot-config').data('plot-config') || $(container).closest('.facet-limit').data('plot-config') || {};
195
-
196
- try {
197
- plot = $.plot($(container), [series_data],
198
- $.extend(true, config, {
199
- yaxis: { ticks: [], min: 0, autoscaleMargin: 0.1},
200
- //xaxis: { ticks: x_ticks },
201
- xaxis: { tickDecimals: 0 }, // force integer ticks
202
- series: { lines: { fill: true, steps: true }},
203
- grid: {clickable: true, hoverable: true, autoHighlight: false, margin: { left: 0, right: 0 }},
204
- selection: {mode: "x"}
205
- }));
206
- }
207
- catch(err) {
208
- alert(err);
209
- }
210
-
211
- find_segment_for = function_for_find_segment(pointer_lookup);
212
- var last_segment = null;
213
- $(container).tooltip({'html': true, 'placement': 'bottom', 'trigger': 'manual', 'delay': { show: 0, hide: 100}});
214
-
215
- $(container).bind("plothover", function (event, pos, item) {
216
- segment = find_segment_for(pos.x);
217
-
218
- if(segment != last_segment) {
219
- var title = find_segment_for(pos.x).label + ' (' + BlacklightRangeLimit.parseNum(segment.count) + ')';
220
- $(container).attr("title", title).tooltip("_fixTitle").tooltip("show");
221
-
222
- last_segment = segment;
223
- }
224
- });
225
-
226
- $(container).bind("mouseout", function() {
227
- last_segment = null;
228
- $(container).tooltip('hide');
229
- });
230
- $(container).bind("plotclick", function (event, pos, item) {
231
- if ( plot.getSelection() == null) {
232
- segment = find_segment_for(pos.x);
233
- plot.setSelection( normalized_selection(segment.from, segment.to));
234
- }
235
- });
236
- $(container).bind("plotselected plotselecting", function(event, ranges) {
237
- if (ranges != null ) {
238
- var from = Math.floor(ranges.xaxis.from);
239
- var to = Math.floor(ranges.xaxis.to);
240
-
241
- var form = $(container).closest(".limit_content").find("form.range_limit");
242
- form.find("input.range_begin").val(from);
243
- form.find("input.range_end").val(to);
244
-
245
- var slider_placeholder = $(container).closest(".limit_content").find("[data-slider-placeholder]");
246
- if (slider_placeholder) {
247
- slider_placeholder.slider("setValue", [from, to+1]);
248
- }
249
- }
250
- });
251
-
252
- var form = $(container).closest(".limit_content").find("form.range_limit");
253
- form.find("input.range_begin, input.range_end").change(function () {
254
- plot.setSelection( form_selection(form, min, max) , true );
255
- });
256
- $(container).closest(".limit_content").find(".profile .range").on("slide", function(event, ui) {
257
- var values = $(event.target).data("slider").getValue();
258
- form.find("input.range_begin").val(values[0]);
259
- form.find("input.range_end").val(values[1]);
260
- plot.setSelection( normalized_selection(values[0], Math.max(values[0], values[1]-1)), true);
261
- });
262
-
263
- // initially entirely selected, to match slider
264
- plot.setSelection( {xaxis: { from:min, to:max+0.9999}} );
265
- }
266
- }
267
-
268
-
269
- // Send endpoint to endpoint+0.99999 to have display
270
- // more closely approximate limiting behavior esp
271
- // at small resolutions. (Since we search on whole numbers,
272
- // inclusive, but flot chart is decimal.)
273
- function normalized_selection(min, max) {
274
- max += 0.99999;
275
-
276
- return {xaxis: { 'from':min, 'to':max}}
277
- }
278
-
279
- function form_selection(form, min, max) {
280
- var begin_val = BlacklightRangeLimit.parseNum($(form).find("input.range_begin").val());
281
- if (isNaN(begin_val) || begin_val < min) {
282
- begin_val = min;
283
- }
284
- var end_val = BlacklightRangeLimit.parseNum($(form).find("input.range_end").val());
285
- if (isNaN(end_val) || end_val > max) {
286
- end_val = max;
287
- }
288
-
289
- return normalized_selection(begin_val, end_val);
290
- }
291
-
292
- function function_for_find_segment(pointer_lookup_arr) {
293
- return function(x_coord) {
294
- for (var i = pointer_lookup_arr.length-1 ; i >= 0 ; i--) {
295
- var hash = pointer_lookup_arr[i];
296
- if (x_coord >= hash.from)
297
- return hash;
298
- }
299
- return pointer_lookup_arr[0];
300
- };
301
- }
302
-
303
- // Check if Flot is loaded, and if browser has support for
304
- // canvas object, either natively or via IE excanvas.
305
- function domDependenciesMet() {
306
- var flotLoaded = (typeof $.plot != "undefined");
307
- var canvasAvailable = ((typeof(document.createElement('canvas').getContext) != "undefined") || (typeof window.CanvasRenderingContext2D != 'undefined' || typeof G_vmlCanvasManager != 'undefined'));
308
-
309
- return (flotLoaded && canvasAvailable);
310
- }
311
74
  });
@@ -0,0 +1,173 @@
1
+ // second arg, if provided, is a number of ms we're willing to
2
+ // wait for the container to have width before giving up -- we'll
3
+ // set 50ms timers to check back until timeout is expired or the
4
+ // container is finally visible. The timeout is used when we catch
5
+ // bootstrap show event, but the animation hasn't barely begun yet -- but
6
+ // we don't want to wait until it's finished, we want to start rendering
7
+ // as soon as we can.
8
+ //
9
+ // We also will
10
+ BlacklightRangeLimit.turnIntoPlot = function turnIntoPlot(container, wait_for_visible) {
11
+ // flot can only render in a a div with a defined width.
12
+ // for instance, a hidden div can't generally be rendered in (although if you set
13
+ // an explicit width on it, it might work)
14
+ //
15
+ // We'll count on later code that catch bootstrap collapse open to render
16
+ // on show, for currently hidden divs.
17
+
18
+ // for some reason width sometimes return negative, not sure
19
+ // why but it's some kind of hidden.
20
+ if (container.width() > 0) {
21
+ var height = container.width() * BlacklightRangeLimit.display_ratio;
22
+
23
+ // Need an explicit height to make flot happy.
24
+ container.height( height )
25
+
26
+ BlacklightRangeLimit.areaChart($(container));
27
+
28
+ $(container).trigger(BlacklightRangeLimit.redrawnEvent);
29
+ }
30
+ else if (wait_for_visible > 0) {
31
+ setTimeout(function() {
32
+ BlacklightRangeLimit.turnIntoPlot(container, wait_for_visible - 50);
33
+ }, 50);
34
+ }
35
+ }
36
+
37
+ // Takes a div holding a ul of distribution segments produced by
38
+ // blacklight_range_limit/_range_facets and makes it into
39
+ // a flot area chart.
40
+ BlacklightRangeLimit.areaChart = function areaChart(container) {
41
+ //flot loaded? And canvas element supported.
42
+ if ( BlacklightRangeLimit.domDependenciesMet() ) {
43
+
44
+ // Grab the data from the ul div
45
+ var series_data = new Array();
46
+ var pointer_lookup = new Array();
47
+ var x_ticks = new Array();
48
+ var min = BlacklightRangeLimit.parseNum($(container).find("ul li:first-child span.from").first().data('blrlBegin'));
49
+ var max = BlacklightRangeLimit.parseNum($(container).find("ul li:last-child span.to").first().data('blrlEnd'));
50
+
51
+ $(container).find("ul li").each(function() {
52
+ var from = BlacklightRangeLimit.parseNum($(this).find("span.from").first().data('blrlBegin'));
53
+ var to = BlacklightRangeLimit.parseNum($(this).find("span.to").first().data('blrlEnd'));
54
+ var count = BlacklightRangeLimit.parseNum($(this).find("span.count").text());
55
+ var avg = (count / (to - from + 1));
56
+
57
+
58
+ //We use the avg as the y-coord, to make the area of each
59
+ //segment proportional to how many documents it holds.
60
+ series_data.push( [from, avg ] );
61
+ series_data.push( [to+1, avg] );
62
+
63
+ x_ticks.push(from);
64
+
65
+ pointer_lookup.push({'from': from, 'to': to, 'count': count, 'label': $(this).find(".facet_select").html() });
66
+ });
67
+ var max_plus_one = BlacklightRangeLimit.parseNum($(container).find("ul li:last-child span.to").text())+1;
68
+ x_ticks.push( max_plus_one );
69
+
70
+
71
+
72
+ var plot;
73
+ var config = $(container).closest('.blrl-plot-config').data('plot-config') || $(container).closest('.facet-limit').data('plot-config') || {};
74
+
75
+ try {
76
+ plot = $.plot($(container), [series_data],
77
+ $.extend(true, config, {
78
+ yaxis: { ticks: [], min: 0, autoscaleMargin: 0.1},
79
+ //xaxis: { ticks: x_ticks },
80
+ xaxis: { tickDecimals: 0 }, // force integer ticks
81
+ series: { lines: { fill: true, steps: true }},
82
+ grid: {clickable: true, hoverable: true, autoHighlight: false, margin: { left: 0, right: 0 }},
83
+ selection: {mode: "x"}
84
+ }));
85
+ }
86
+ catch(err) {
87
+ alert(err);
88
+ }
89
+
90
+ var find_segment_for = BlacklightRangeLimit.function_for_find_segment(pointer_lookup);
91
+ var last_segment = null;
92
+ $(container).tooltip({'html': true, 'placement': 'bottom', 'trigger': 'manual', 'delay': { show: 0, hide: 100}});
93
+
94
+ $(container).bind("plothover", function (event, pos, item) {
95
+ var segment = find_segment_for(pos.x);
96
+
97
+ if(segment != last_segment) {
98
+ var title = find_segment_for(pos.x).label + ' (' + BlacklightRangeLimit.parseNum(segment.count) + ')';
99
+ $(container).attr("title", title).tooltip("_fixTitle").tooltip("show");
100
+
101
+ last_segment = segment;
102
+ }
103
+ });
104
+
105
+ $(container).bind("mouseout", function() {
106
+ last_segment = null;
107
+ $(container).tooltip('hide');
108
+ });
109
+ $(container).bind("plotclick", function (event, pos, item) {
110
+ if ( plot.getSelection() == null) {
111
+ segment = find_segment_for(pos.x);
112
+ plot.setSelection(BlacklightRangeLimit.normalized_selection(segment.from, segment.to));
113
+ }
114
+ });
115
+ $(container).bind("plotselected plotselecting", function(event, ranges) {
116
+ if (ranges != null ) {
117
+ var from = Math.floor(ranges.xaxis.from);
118
+ var to = Math.floor(ranges.xaxis.to);
119
+
120
+ var form = $(container).closest(".limit_content").find("form.range_limit");
121
+ form.find("input.range_begin").val(from);
122
+ form.find("input.range_end").val(to);
123
+
124
+ var slider_placeholder = $(container).closest(".limit_content").find("[data-slider-placeholder]");
125
+ if (slider_placeholder) {
126
+ slider_placeholder.slider("setValue", [from, to+1]);
127
+ }
128
+ }
129
+ });
130
+
131
+ var form = $(container).closest(".limit_content").find("form.range_limit");
132
+ form.find("input.range_begin, input.range_end").change(function () {
133
+ plot.setSelection( BlacklightRangeLimit.form_selection(form, min, max) , true );
134
+ });
135
+ $(container).closest(".limit_content").find(".profile .range").on("slide", function(event, ui) {
136
+ var values = $(event.target).data("slider").getValue();
137
+ form.find("input.range_begin").val(values[0]);
138
+ form.find("input.range_end").val(values[1]);
139
+ plot.setSelection(BlacklightRangeLimit.normalized_selection(values[0], Math.max(values[0], values[1]-1)), true);
140
+ });
141
+
142
+ // initially entirely selected, to match slider
143
+ plot.setSelection( {xaxis: { from:min, to:max+0.9999}} );
144
+ }
145
+ }
146
+
147
+ // after a collapsible facet contents is fully shown,
148
+ // resize the flot chart to current conditions. This way, if you change
149
+ // browser window size, you can get chart resized to fit by closing and opening
150
+ // again, if needed.
151
+ BlacklightRangeLimit.redrawPlot = function redrawPlot(container) {
152
+ if (container && container.width() > 0) {
153
+ // resize the container's height, since width may have changed.
154
+ container.height( container.width() * BlacklightRangeLimit.display_ratio );
155
+
156
+ // redraw the chart.
157
+ var plot = container.data("plot");
158
+ if (plot) {
159
+ // how to redraw after possible resize?
160
+ // Cribbed from https://github.com/flot/flot/blob/master/jquery.flot.resize.js
161
+ plot.resize();
162
+ plot.setupGrid();
163
+ plot.draw();
164
+ // plus trigger redraw of the selection, which otherwise ain't always right
165
+ // we'll trigger a fake event on one of the boxes
166
+ var form = $(container).closest(".limit_content").find("form.range_limit");
167
+ form.find("input.range_begin").trigger("change");
168
+
169
+ // send our custom event to trigger redraw of slider
170
+ $(container).trigger(BlacklightRangeLimit.redrawnEvent);
171
+ }
172
+ }
173
+ }
@@ -1,6 +1,6 @@
1
-
2
- // takes a string and parses into an integer, but throws away commas first, to avoid truncation when there is a comma
3
- // use in place of javascript's native parseInt
1
+ /**
2
+ * Global BlacklightRangeLimit module setup.
3
+ */
4
4
  !function(global) {
5
5
  'use strict';
6
6
 
@@ -10,11 +10,75 @@
10
10
  this.options = options || {};
11
11
  }
12
12
 
13
+ BlacklightRangeLimit.display_ratio = 1/(1.618 * 2); // half a golden rectangle, why not
14
+ /* A custom event "plotDrawn.blacklight.rangeLimit" will be sent when flot plot
15
+ is (re-)drawn on screen possibly with a new size. target of event will be the DOM element
16
+ containing the plot. Used to resize slider to match. */
17
+ BlacklightRangeLimit.redrawnEvent = "plotDrawn.blacklight.rangeLimit";
18
+
19
+ // takes a string and parses into an integer, but throws away commas first, to avoid truncation when there is a comma
20
+ // use in place of javascript's native parseInt
13
21
  BlacklightRangeLimit.parseNum = function parseNum(str) {
14
22
  str = String(str).replace(/[^0-9-]/g, '');
15
23
  return parseInt(str, 10);
16
24
  };
17
25
 
26
+ BlacklightRangeLimit.form_selection = function form_selection(form, min, max) {
27
+ var begin_val = BlacklightRangeLimit.parseNum($(form).find("input.range_begin").val());
28
+ if (isNaN(begin_val) || begin_val < min) {
29
+ begin_val = min;
30
+ }
31
+ var end_val = BlacklightRangeLimit.parseNum($(form).find("input.range_end").val());
32
+ if (isNaN(end_val) || end_val > max) {
33
+ end_val = max;
34
+ }
35
+
36
+ return BlacklightRangeLimit.normalized_selection(begin_val, end_val);
37
+ }
38
+
39
+ // Add AJAX fetched range facets if needed, and add a chart to em
40
+ BlacklightRangeLimit.checkForNeededFacetsToFetch = function checkForNeededFacetsToFetch() {
41
+ $(".range_limit .profile .distribution a.load_distribution").each(function() {
42
+ var container = $(this).parent('div.distribution');
43
+
44
+ $(container).load($(this).attr('href'), function(response, status) {
45
+ if ($(container).hasClass("chart_js") && status == "success" ) {
46
+ BlacklightRangeLimit.turnIntoPlot(container);
47
+ }
48
+ });
49
+ });
50
+ }
51
+
52
+ BlacklightRangeLimit.function_for_find_segment = function function_for_find_segment(pointer_lookup_arr) {
53
+ return function(x_coord) {
54
+ for (var i = pointer_lookup_arr.length-1 ; i >= 0 ; i--) {
55
+ var hash = pointer_lookup_arr[i];
56
+ if (x_coord >= hash.from)
57
+ return hash;
58
+ }
59
+ return pointer_lookup_arr[0];
60
+ };
61
+ }
62
+
63
+ // Send endpoint to endpoint+0.99999 to have display
64
+ // more closely approximate limiting behavior esp
65
+ // at small resolutions. (Since we search on whole numbers,
66
+ // inclusive, but flot chart is decimal.)
67
+ BlacklightRangeLimit.normalized_selection = function normalized_selection(min, max) {
68
+ max += 0.99999;
69
+
70
+ return {xaxis: { 'from':min, 'to':max}}
71
+ }
72
+
73
+ // Check if Flot is loaded, and if browser has support for
74
+ // canvas object, either natively or via IE excanvas.
75
+ BlacklightRangeLimit.domDependenciesMet = function domDependenciesMet() {
76
+ var flotLoaded = (typeof $.plot != "undefined");
77
+ var canvasAvailable = ((typeof(document.createElement('canvas').getContext) != "undefined") || (typeof window.CanvasRenderingContext2D != 'undefined' || typeof G_vmlCanvasManager != 'undefined'));
78
+
79
+ return (flotLoaded && canvasAvailable);
80
+ }
81
+
18
82
  BlacklightRangeLimit.noConflict = function noConflict() {
19
83
  global.BlacklightRangeLimit = previousBlacklightRangeLimit;
20
84
  return BlacklightRangeLimit;
@@ -3,65 +3,64 @@
3
3
  Blacklight.onLoad(function() {
4
4
 
5
5
  $(".range_limit .profile .range.slider_js").each(function() {
6
- buildSlider(this);
6
+ BlacklightRangeLimit.buildSlider(this);
7
7
  });
8
8
 
9
9
  $(Blacklight.modal.modalSelector).on('shown.bs.modal', function() {
10
10
  $(this).find(".range_limit .profile .range.slider_js").each(function() {
11
- buildSlider(this);
11
+ BlacklightRangeLimit.buildSlider(this);
12
12
  });
13
13
  });
14
14
 
15
- // catch event for redrawing chart, to redraw slider to match width
16
- $("body").on("plotDrawn.blacklight.rangeLimit", function(event) {
17
- var area = $(event.target).closest(".limit_content.range_limit");
18
- var plot = area.find(".chart_js").data("plot");
19
- var slider_el = area.find(".slider");
15
+ // catch event for redrawing chart, to redraw slider to match width
16
+ $("body").on("plotDrawn.blacklight.rangeLimit", function(event) {
17
+ var area = $(event.target).closest(".limit_content.range_limit");
18
+ var plot = area.find(".chart_js").data("plot");
19
+ var slider_el = area.find(".slider");
20
20
 
21
- if (plot && slider_el) {
21
+ if (plot && slider_el) {
22
22
  slider_el.width(plot.width());
23
23
  slider_el.css("display", "block")
24
- }
24
+ }
25
+ });
25
26
  });
26
27
 
27
28
  // returns two element array min/max as numbers. If there is a limit applied,
28
29
  // it's boundaries are are limits. Otherwise, min/max in current result
29
30
  // set as sniffed from HTML. Pass in a DOM element for a div.range
30
31
  // Will return NaN as min or max in case of error or other weirdness.
31
- function min_max(range_element) {
32
- var current_limit = $(range_element).closest(".limit_content.range_limit").find(".current")
33
-
34
-
35
-
36
- var min = max = BlacklightRangeLimit.parseNum(current_limit.find(".single").data('blrlSingle'))
37
- if ( isNaN(min)) {
38
- min = BlacklightRangeLimit.parseNum(current_limit.find(".from").first().data('blrlBegin'));
39
- max = BlacklightRangeLimit.parseNum(current_limit.find(".to").first().data('blrlEnd'));
40
- }
41
-
42
- if (isNaN(min) || isNaN(max)) {
43
- //no current limit, take from results min max included in spans
44
- min = BlacklightRangeLimit.parseNum($(range_element).find(".min").first().text());
45
- max = BlacklightRangeLimit.parseNum($(range_element).find(".max").first().text());
46
- }
47
- return [min, max]
32
+ BlacklightRangeLimit.min_max = function min_max(range_element) {
33
+ var current_limit = $(range_element).closest(".limit_content.range_limit").find(".current")
34
+
35
+ var min = max = BlacklightRangeLimit.parseNum(current_limit.find(".single").data('blrlSingle'))
36
+ if ( isNaN(min)) {
37
+ min = BlacklightRangeLimit.parseNum(current_limit.find(".from").first().data('blrlBegin'));
38
+ max = BlacklightRangeLimit.parseNum(current_limit.find(".to").first().data('blrlEnd'));
39
+ }
40
+
41
+ if (isNaN(min) || isNaN(max)) {
42
+ //no current limit, take from results min max included in spans
43
+ min = BlacklightRangeLimit.parseNum($(range_element).find(".min").first().text());
44
+ max = BlacklightRangeLimit.parseNum($(range_element).find(".max").first().text());
45
+ }
46
+ return [min, max]
48
47
  }
49
48
 
50
49
 
51
50
  // Check to see if a value is an Integer
52
51
  // see: http://stackoverflow.com/questions/3885817/how-to-check-if-a-number-is-float-or-integer
53
- function isInt(n) {
52
+ BlacklightRangeLimit.isInt = function isInt(n) {
54
53
  return n % 1 === 0;
55
54
  }
56
55
 
57
- function buildSlider(thisContext) {
56
+ BlacklightRangeLimit.buildSlider = function buildSlider(thisContext) {
58
57
  var range_element = $(thisContext);
59
58
 
60
- var boundaries = min_max(thisContext);
59
+ var boundaries = BlacklightRangeLimit.min_max(thisContext);
61
60
  var min = boundaries[0];
62
61
  var max = boundaries[1];
63
62
 
64
- if (isInt(min) && isInt(max)) {
63
+ if (BlacklightRangeLimit.isInt(min) && BlacklightRangeLimit.isInt(max)) {
65
64
  $(thisContext).contents().wrapAll('<div class="sr-only" />');
66
65
 
67
66
  var range_element = $(thisContext);
@@ -137,4 +136,3 @@ function isInt(n) {
137
136
  placeholder_input.slider("setValue", values);
138
137
  });
139
138
  }
140
- });
@@ -24,8 +24,9 @@ Gem::Specification.new do |s|
24
24
  s.add_development_dependency 'capybara', '~> 3'
25
25
  s.add_development_dependency 'sqlite3'
26
26
  s.add_development_dependency 'launchy'
27
- s.add_development_dependency 'solr_wrapper', '~> 2.0'
27
+ s.add_development_dependency 'solr_wrapper'
28
28
  s.add_development_dependency 'engine_cart', '~> 2.1'
29
29
  s.add_development_dependency 'selenium-webdriver', '>= 3.13.1'
30
30
  s.add_development_dependency 'webdrivers', '~>3.0'
31
+ s.add_development_dependency 'rexml' # pending https://github.com/SeleniumHQ/selenium/issues/9001
31
32
  end
@@ -1,3 +1,2 @@
1
1
  gem 'rails-controller-testing'
2
- gem 'thor', '~> 0.20'
3
2
  gem 'blacklight', ENV['BLACKLIGHT_VERSION'] if ENV['BLACKLIGHT_VERSION']
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blacklight_range_limit
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.9.1
4
+ version: 8.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Rochkind
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-08-24 00:00:00.000000000 Z
12
+ date: 2021-02-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: blacklight
@@ -99,16 +99,16 @@ dependencies:
99
99
  name: solr_wrapper
100
100
  requirement: !ruby/object:Gem::Requirement
101
101
  requirements:
102
- - - "~>"
102
+ - - ">="
103
103
  - !ruby/object:Gem::Version
104
- version: '2.0'
104
+ version: '0'
105
105
  type: :development
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
- - - "~>"
109
+ - - ">="
110
110
  - !ruby/object:Gem::Version
111
- version: '2.0'
111
+ version: '0'
112
112
  - !ruby/object:Gem::Dependency
113
113
  name: engine_cart
114
114
  requirement: !ruby/object:Gem::Requirement
@@ -151,6 +151,20 @@ dependencies:
151
151
  - - "~>"
152
152
  - !ruby/object:Gem::Version
153
153
  version: '3.0'
154
+ - !ruby/object:Gem::Dependency
155
+ name: rexml
156
+ requirement: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ type: :development
162
+ prerelease: false
163
+ version_requirements: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
154
168
  description:
155
169
  email:
156
170
  - blacklight-development@googlegroups.com
@@ -158,10 +172,10 @@ executables: []
158
172
  extensions: []
159
173
  extra_rdoc_files: []
160
174
  files:
175
+ - ".github/workflows/ruby.yml"
161
176
  - ".gitignore"
162
177
  - ".rspec"
163
178
  - ".solr_wrapper.yml"
164
- - ".travis.yml"
165
179
  - Gemfile
166
180
  - LICENSE
167
181
  - README.md
@@ -169,6 +183,7 @@ files:
169
183
  - VERSION
170
184
  - app/assets/javascripts/blacklight_range_limit.js
171
185
  - app/assets/javascripts/blacklight_range_limit/range_limit_distro_facets.js
186
+ - app/assets/javascripts/blacklight_range_limit/range_limit_plotting.js
172
187
  - app/assets/javascripts/blacklight_range_limit/range_limit_shared.js
173
188
  - app/assets/javascripts/blacklight_range_limit/range_limit_slider.js
174
189
  - app/assets/stylesheets/blacklight_range_limit.css.scss
@@ -256,7 +271,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
256
271
  - !ruby/object:Gem::Version
257
272
  version: '0'
258
273
  requirements: []
259
- rubygems_version: 3.1.2
274
+ rubygems_version: 3.1.4
260
275
  signing_key:
261
276
  specification_version: 4
262
277
  summary: Blacklight Range Limit plugin
data/.travis.yml DELETED
@@ -1,30 +0,0 @@
1
- dist: bionic
2
- language: ruby
3
- addons:
4
- chrome: stable
5
- before_install:
6
- - google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost &
7
-
8
- notifications:
9
- email: false
10
-
11
- matrix:
12
- include:
13
- - rvm: 2.6.5
14
- env: "RAILS_VERSION=6.0.0 ENGINE_CART_RAILS_OPTIONS=\"--skip-webpack-install\""
15
- - rvm: 2.6.5
16
- env: "RAILS_VERSION=5.2.3"
17
- - rvm: 2.6.5
18
- env: "RAILS_VERSION=5.2.3 BLACKLIGHT_VERSION=7.6.0"
19
- - rvm: 2.5.7
20
- env: "RAILS_VERSION=5.1.7"
21
-
22
- notifications:
23
- irc: "irc.freenode.org#blacklight"
24
- email:
25
- - blacklight-commits@googlegroups.com
26
-
27
- global_env:
28
- - NOKOGIRI_USE_SYSTEM_LIBRARIES=true
29
-
30
- jdk: openjdk11