diff --git a/.gitignore b/.gitignore
index ffedaf97..3034337e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,22 +25,6 @@ pickle-email-*.html
# Specific configuration files #
################################
-blacklight.yml
-hydra-ldap.yml
-database.yml
-fedora.yml
-solr.yml
-omniauth-facebook.yml
-omniauth-polaris.yml
-role_map_cucumber.yml
-role_map_development.yml
-role_map_production.yml
-role_map_test.yml
-google_analytics.yml
-contact_emails.yml
-iiif_server.yml
-secrets.yml
-blacklight.yml
# remove coveralls.yml once CI server set up
.coveralls.yml
.ruby-version
@@ -63,7 +47,6 @@ blacklight.yml
.config
.yardoc
Gemfile.lock
-/spec/test_app_templates/Gemfile.extra
InstalledFiles
_yardoc
doc/
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index a386b20b..00000000
--- a/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "db/migrate"]
- path = db/migrate
- url = https://github.com/boston-library/commonwealth-db-migrations.git
diff --git a/.rubocop.yml b/.rubocop.yml
new file mode 100644
index 00000000..14ad17bf
--- /dev/null
+++ b/.rubocop.yml
@@ -0,0 +1,746 @@
+require:
+ - rubocop-rspec
+ - rubocop-rails
+ - rubocop-performance
+
+AllCops:
+ Exclude:
+ - 'bin/*'
+ - 'spec/internal/**/*'
+ - 'spec/fixtures/**/'
+ - 'vendor/**/*'
+ - 'lib/generators/commonwealth_vlr_engine/templates/*'
+ - 'Gemfile'
+ DisplayCopNames: true
+ DisabledByDefault: true
+ TargetRubyVersion: 2.6
+
+####################### BUNDLER/GEMSPEC ###############################
+Bundler/OrderedGems:
+ Enabled: true
+
+Bundler/DuplicatedGem:
+ Enabled: true
+
+Gemspec/OrderedDependencies:
+ Enabled: true
+
+####################### LAYOUT ###############################
+Layout/AlignArray:
+ Enabled: true
+
+Layout/BlockAlignment:
+ Enabled: true
+
+Layout/CaseIndentation:
+ Enabled: true
+
+Layout/CommentIndentation:
+ Enabled: true
+
+Layout/AlignArguments:
+ Enabled: true
+
+Layout/ClosingParenthesisIndentation:
+ Enabled: true
+
+Layout/EmptyComment:
+ Enabled: true
+
+Layout/EmptyLineAfterGuardClause:
+ Enabled: true
+
+Layout/EmptyLineAfterMagicComment:
+ Enabled: true
+
+Layout/EmptyLineBetweenDefs:
+ Enabled: true
+
+Layout/EmptyLines:
+ Enabled: true
+
+Layout/EmptyLinesAroundAccessModifier:
+ Enabled: true
+
+Layout/EmptyLinesAroundBlockBody:
+ Enabled: true
+
+Layout/EmptyLinesAroundClassBody:
+ Enabled: true
+
+Layout/EmptyLinesAroundModuleBody:
+ Enabled: true
+
+Layout/EndAlignment:
+ Enabled: true
+
+Layout/ExtraSpacing:
+ Enabled: true
+
+Layout/IndentFirstHashElement:
+ Enabled: true
+ EnforcedStyle: consistent
+
+Layout/IndentationConsistency:
+ Enabled: true
+
+Layout/IndentationWidth:
+ Enabled: true
+
+Layout/LeadingBlankLines:
+ Enabled: true
+
+Layout/LeadingCommentSpace:
+ Enabled: true
+
+Layout/MultilineArrayBraceLayout:
+ Enabled: true
+
+Layout/MultilineMethodCallBraceLayout:
+ Enabled: true
+
+Layout/SpaceAfterComma:
+ Enabled: true
+
+Layout/SpaceAroundEqualsInParameterDefault:
+ Enabled: true
+
+Layout/SpaceAroundOperators:
+ Enabled: true
+
+Layout/SpaceBeforeBlockBraces:
+ Enabled: true
+
+Layout/SpaceBeforeComma:
+ Enabled: true
+
+Layout/SpaceBeforeComment:
+ Enabled: true
+
+Layout/SpaceInsideArrayLiteralBrackets:
+ Enabled: true
+
+Layout/SpaceInsideBlockBraces:
+ Enabled: true
+
+Layout/SpaceInsideHashLiteralBraces:
+ Enabled: true
+
+Layout/SpaceInsideParens:
+ Enabled: true
+
+Layout/TrailingWhitespace:
+ Enabled: true
+
+####################### LINTING ###############################
+
+Lint/AmbiguousOperator:
+ Enabled: true
+
+Lint/AmbiguousRegexpLiteral:
+ Enabled: true
+
+Lint/AssignmentInCondition:
+ Enabled: true
+
+Lint/CircularArgumentReference:
+ Enabled: true
+
+Lint/Debugger:
+ Enabled: true
+
+Lint/DeprecatedClassMethods:
+ Enabled: true
+
+Lint/DuplicateCaseCondition:
+ Enabled: true
+
+Lint/DuplicateMethods:
+ Enabled: true
+
+Lint/DuplicatedKey:
+ Enabled: true
+
+Lint/EachWithObjectArgument:
+ Enabled: true
+
+Lint/ElseLayout:
+ Enabled: true
+
+Lint/EmptyEnsure:
+ Enabled: true
+ AutoCorrect: false
+
+Lint/EmptyExpression:
+ Enabled: true
+
+Lint/EmptyInterpolation:
+ Enabled: true
+
+Lint/EmptyWhen:
+ Enabled: true
+
+Lint/EndInMethod:
+ Enabled: true
+
+Lint/EnsureReturn:
+ Enabled: true
+
+Lint/FlipFlop:
+ Enabled: true
+
+Lint/FloatOutOfRange:
+ Enabled: true
+
+Lint/FormatParameterMismatch:
+ Enabled: true
+
+Lint/HandleExceptions:
+ Enabled: true
+
+Lint/ImplicitStringConcatenation:
+ Enabled: true
+
+Lint/IneffectiveAccessModifier:
+ Enabled: true
+
+Lint/InheritException:
+ Enabled: true
+
+Lint/LiteralAsCondition:
+ Enabled: true
+
+Lint/LiteralInInterpolation:
+ Enabled: true
+
+Lint/Loop:
+ Enabled: true
+
+Lint/MultipleCompare:
+ Enabled: true
+
+Lint/NestedMethodDefinition:
+ Enabled: true
+
+Lint/NextWithoutAccumulator:
+ Enabled: true
+
+Lint/NonLocalExitFromIterator:
+ Enabled: true
+
+Lint/ParenthesesAsGroupedExpression:
+ Enabled: true
+
+Lint/PercentStringArray:
+ Enabled: true
+
+Lint/PercentSymbolArray:
+ Enabled: true
+
+Lint/RandOne:
+ Enabled: true
+
+Lint/RequireParentheses:
+ Enabled: true
+
+Lint/RescueException:
+ Enabled: true
+
+Lint/SafeNavigationChain:
+ Enabled: true
+
+Lint/ShadowedException:
+ Enabled: true
+
+Lint/ShadowingOuterLocalVariable:
+ Enabled: true
+
+Lint/StringConversionInInterpolation:
+ Enabled: true
+
+Lint/UnderscorePrefixedVariableName:
+ Enabled: true
+
+Lint/UnifiedInteger:
+ Enabled: true
+
+Lint/UnneededSplatExpansion:
+ Enabled: true
+
+Lint/UnusedMethodArgument:
+ Enabled: true
+
+Lint/UnusedBlockArgument:
+ Enabled: true
+
+Lint/UnreachableCode:
+ Enabled: true
+
+Lint/UselessAccessModifier:
+ Enabled: true
+
+Lint/UselessAssignment:
+ Enabled: true
+
+Lint/UselessComparison:
+ Enabled: true
+
+Lint/UselessElseWithoutRescue:
+ Enabled: true
+
+Lint/UselessSetterCall:
+ Enabled: true
+
+Lint/Void:
+ Enabled: true
+####################### NAMING ###############################
+
+Naming/AccessorMethodName:
+ Enabled: true
+ Exclude:
+ - 'app/controllers/blacklight_advanced_search/advanced_controller.rb'
+
+####################### STYLE ###############################
+
+Style/Documentation:
+ Enabled: false
+ Exclude:
+ - 'spec/**/*'
+
+Style/AccessModifierDeclarations:
+ Enabled: true
+
+Style/BlockComments:
+ Enabled: true
+
+Style/BlockDelimiters:
+ Enabled: true
+
+Style/ClassAndModuleChildren:
+ Enabled: false
+
+Style/ColonMethodCall:
+ Enabled: true
+
+Style/CommentAnnotation:
+ Enabled: true
+
+Style/DefWithParentheses:
+ Enabled: true
+
+Style/EmptyElse:
+ Enabled: true
+
+Style/EvalWithLocation:
+ Enabled: true
+
+Style/ExpandPathArguments:
+ Enabled: true
+
+Style/FrozenStringLiteralComment:
+ Enabled: true
+
+Style/GuardClause:
+ Enabled: true
+
+# Style/HashSyntax:
+
+Style/IfUnlessModifier:
+ Enabled: true
+ Exclude:
+ - 'app/helpers/citation_helper.rb'
+
+Style/Lambda:
+ Enabled: true
+
+Style/MixinUsage:
+ Enabled: true
+
+Style/MutableConstant:
+ Enabled: true
+
+Style/Next:
+ Enabled: true
+ Exclude:
+ - 'app/helpers/commonwealth_vlr_engine/vlr_blacklight_maps_helper_behavior.rb'
+
+Style/NumericLiterals:
+ Enabled: true
+
+Style/PercentLiteralDelimiters:
+ Enabled: true
+ PreferredDelimiters:
+ default: ()
+ '%i': ()
+ '%I': ()
+ '%w': ()
+ '%W': ()
+
+Style/Proc:
+ Enabled: true
+
+Style/RedundantFreeze:
+ Enabled: true
+
+Style/RedundantSelf:
+ Enabled: true
+ Exclude:
+ - 'app/helpers/commonwealth_vlr_engine/catalog_helper_behavior.rb'
+ - 'app/helpers/commonwealth_vlr_engine/vlr_blacklight_maps_helper_behavior.rb'
+
+Style/RescueStandardError:
+ Enabled: true
+
+Style/SignalException:
+ Enabled: true
+
+Style/SpecialGlobalVars:
+ Enabled: true
+
+Style/StderrPuts:
+ Enabled: true
+
+Style/StringLiterals:
+ Enabled: true
+
+Style/SymbolArray:
+ Enabled: false
+
+Style/WordArray:
+ Enabled: false
+
+Style/UnneededInterpolation:
+ Enabled: true
+
+####################### METRICS ###############################
+
+# REVIEW: Tweak these values at some point low priority
+
+Metrics/AbcSize:
+ Enabled: true
+ Max: 100
+
+Metrics/BlockLength:
+ Enabled: true
+ Max: 90
+ Exclude:
+ - 'spec/**/*'
+ - 'lib/commonwealth-vlr-engine/controller_override.rb'
+
+Metrics/ClassLength:
+ Enabled: true
+ Max: 250
+
+Metrics/CyclomaticComplexity:
+ Enabled: true
+ Max: 15
+ Exclude:
+ - 'app/helpers/citation_helper.rb'
+
+Metrics/MethodLength:
+ Enabled: true
+ Max: 100
+
+Metrics/LineLength:
+ Enabled: true
+ Max: 500
+
+####################### SECURITY ###############################
+
+# Taken From bixby config
+Security/Eval:
+ Enabled: true
+
+Security/JSONLoad:
+ Enabled: true
+ # Autocorrect here will change to a method that may cause crashes depending
+ # on the value of the argument.
+ AutoCorrect: false
+
+Security/MarshalLoad:
+ Enabled: true
+
+Security/YAMLLoad:
+ Enabled: true
+
+####################### RAILS ###############################
+
+Rails/ActionFilter:
+ Enabled: true
+
+Rails/CreateTableWithTimestamps:
+ Enabled: true
+
+Rails/ActiveSupportAliases:
+ Enabled: true
+
+Rails/BelongsTo:
+ Enabled: true
+
+Rails/Blank:
+ Enabled: true
+
+Rails/Date:
+ Enabled: true
+
+Rails/Delegate:
+ Enabled: true
+
+Rails/DelegateAllowBlank:
+ Enabled: true
+
+Rails/DynamicFindBy:
+ Enabled: true
+
+Rails/EnumHash:
+ Enabled: true
+
+Rails/EnumUniqueness:
+ Enabled: true
+
+Rails/EnvironmentComparison:
+ Enabled: true
+
+Rails/Exit:
+ Enabled: true
+
+Rails/InverseOf:
+ Enabled: true
+
+Rails/HasManyOrHasOneDependent:
+ Enabled: true
+
+Rails/Presence:
+ Enabled: true
+
+Rails/Present:
+ Enabled: true
+
+Rails/Output:
+ Enabled: true
+ Exclude:
+ - 'lib/commonwealth-vlr-engine/engine.rb'
+
+Rails/ReflectionClassName:
+ Enabled: false
+
+Rails/SafeNavigation:
+ Enabled: true
+
+Rails/ScopeArgs:
+ Enabled: true
+
+Rails/TimeZone:
+ Enabled: true
+
+Rails/UnknownEnv:
+ Enabled: true
+
+Rails/Validation:
+ Enabled: true
+
+####################### PERFORMANCE ###############################
+
+# Taken From Bixby
+
+Performance/Casecmp:
+ Enabled: true
+
+Performance/CaseWhenSplat:
+ Enabled: true
+
+Performance/Count:
+ # This cop has known compatibility issues with `ActiveRecord` and other
+ # frameworks. ActiveRecord's `count` ignores the block that is passed to it.
+ # For more information, see the documentation in the cop itself.
+ # If you understand the known risk, you can disable `SafeMode`.
+ SafeAutoCorrect: true
+ Enabled: true
+
+Performance/Detect:
+ # This cop has known compatibility issues with `ActiveRecord` and other
+ # frameworks. `ActiveRecord` does not implement a `detect` method and `find`
+ # has its own meaning. Correcting `ActiveRecord` methods with this cop
+ # should be considered unsafe.
+ SafeAutoCorrect: true
+ Enabled: true
+
+Performance/DoubleStartEndWith:
+ Enabled: true
+
+Performance/EndWith:
+ # This will change to a new method call which isn't guaranteed to be on the
+ # object. Switching these methods has to be done with knowledge of the types
+ # of the variables which rubocop doesn't have.
+ AutoCorrect: false
+ Enabled: true
+
+Performance/FixedSize:
+ Enabled: true
+
+Performance/FlatMap:
+ Enabled: true
+ EnabledForFlattenWithoutParams: false
+ # If enabled, this cop will warn about usages of
+ # `flatten` being called without any parameters.
+ # This can be dangerous since `flat_map` will only flatten 1 level, and
+ # `flatten` without any parameters can flatten multiple levels.
+
+Performance/InefficientHashSearch:
+ Enabled: true
+
+Performance/RangeInclude:
+ Enabled: true
+
+Performance/RedundantBlockCall:
+ Enabled: true
+
+Performance/RedundantMatch:
+ Enabled: true
+
+Performance/RedundantMerge:
+ Enabled: true
+
+Performance/RegexpMatch:
+ Enabled: true
+
+Performance/ReverseEach:
+ Enabled: true
+
+Performance/Size:
+ Enabled: true
+
+Performance/StartWith:
+ Enabled: true
+
+Performance/StringReplacement:
+ Enabled: true
+
+Performance/TimesMap:
+ Enabled: true
+
+Performance/UnfreezeString:
+ Enabled: true
+
+####################### RSPEC ###############################
+RSpec/AlignLeftLetBrace:
+ Enabled: false
+
+RSpec/AlignRightLetBrace:
+ Enabled: false
+
+RSpec/AnyInstance:
+ Enabled: true
+
+RSpec/BeforeAfterAll:
+ Enabled: false
+
+RSpec/Be:
+ Enabled: true
+
+RSpec/BeEql:
+ Enabled: true
+
+RSpec/ContextMethod:
+ Enabled: true
+
+RSpec/DescribedClass:
+ Enabled: true
+
+RSpec/EmptyLineAfterExample:
+ Enabled: true
+
+RSpec/EmptyLineAfterExampleGroup:
+ Enabled: true
+
+RSpec/EmptyLineAfterFinalLet:
+ Enabled: false
+
+RSpec/EmptyLineAfterHook:
+ Enabled: true
+
+RSpec/EmptyLineAfterSubject:
+ Enabled: true
+
+RSpec/ExpectChange:
+ Enabled: true
+
+RSpec/ExpectInHook:
+ Enabled: false
+
+RSpec/ExpectOutput:
+ Enabled: true
+
+RSpec/HookArgument:
+ Enabled: true
+ EnforcedStyle: each
+
+RSpec/HooksBeforeExamples:
+ Enabled: true
+
+RSpec/InstanceVariable:
+ Enabled: false
+
+RSpec/InvalidPredicateMatcher:
+ Enabled: true
+
+RSpec/ItBehavesLike:
+ Enabled: true
+
+RSpec/IteratedExpectation:
+ Enabled: true
+
+RSpec/LeadingSubject:
+ Enabled: true
+
+RSpec/LeakyConstantDeclaration:
+ Enabled: true
+
+RSpec/LetBeforeExamples:
+ Enabled: false
+
+RSpec/LetSetup:
+ Enabled: true
+
+RSpec/MessageExpectation:
+ Enabled: false
+
+RSpec/MissingExampleGroupArgument:
+ Enabled: true
+
+RSpec/MultipleDescribes:
+ Enabled: true
+
+RSpec/MultipleExpectations:
+ Enabled: true
+ Max: 5
+
+RSpec/OverwritingSetup:
+ Enabled: true
+
+RSpec/PredicateMatcher:
+ Enabled: false
+
+RSpec/RepeatedDescription:
+ Enabled: true
+
+RSpec/RepeatedExample:
+ Enabled: true
+
+RSpec/ReturnFromStub:
+ Enabled: true
+
+RSpec/ScatteredLet:
+ Enabled: false
+
+RSpec/ScatteredSetup:
+ Enabled: true
+
+RSpec/SharedContext:
+ Enabled: true
+
+RSpec/SharedExamples:
+ Enabled: true
+
+RSpec/VoidExpect:
+ Enabled: true
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..2f620a62
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,19 @@
+language: ruby
+sudo: false
+dist: bionic
+
+addons:
+ chrome: stable
+
+before_install:
+ - google-chrome-stable --headless --disable-gpu --no-sandbox --remote-debugging-port=9222 http://localhost &
+
+global_env:
+ - NOKOGIRI_USE_SYSTEM_LIBRARIES=true
+ - ENGINE_CART_RAILS_OPTIONS='--skip-git --skip-listen --skip-spring --skip-keeps --skip-action-cable --skip-coffee --skip-test'
+
+matrix:
+ include:
+ - rvm: 2.6.6
+ env: "RAILS_VERSION=6.0.3.4"
+ fast_finish: true
diff --git a/Gemfile b/Gemfile
index b7994c28..356bad08 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/boston-library/#{repo}.git" }
@@ -5,11 +7,21 @@ git_source(:github) { |repo| "https://github.com/boston-library/#{repo}.git" }
# Specify your gem's dependencies in commonwealth-vlr-engine.gemspec
gemspec
+group :development, :test do
+ gem 'rubocop', '~> 0.75.1', require: false
+ gem 'rubocop-performance', '~> 1.5', require: false
+ gem 'rubocop-rails', '~> 2.4.2', require: false
+ gem 'rubocop-rspec', require: false
+end
+
group :test do
gem 'coveralls', require: false
- gem 'rails-controller-testing'
gem 'database_cleaner'
+ gem 'puffing-billy'
+ gem 'rails-controller-testing'
+ gem 'vcr', '~> 6.0'
gem 'webdrivers', '~> 3.0'
+ gem 'webmock', '~> 3.8'
end
# BEGIN ENGINE_CART BLOCK
# engine_cart: 2.3.0
@@ -49,3 +61,5 @@ else
end
end
# END ENGINE_CART BLOCK
+
+eval_gemfile File.expand_path("spec/test_app_templates/Gemfile.extra", File.dirname(__FILE__))
diff --git a/README.md b/README.md
index 4cf5b138..f8362bf1 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# CommonwealthVlrEngine
-[![Coverage Status](https://coveralls.io/repos/boston-library/commonwealth-vlr-engine/badge.svg?branch=master&service=github)](https://coveralls.io/github/boston-library/commonwealth-vlr-engine?branch=master)
+[![Build Status](https://travis-ci.com/boston-library/commonwealth-vlr-engine.svg?branch=master)](https://travis-ci.com/boston-library/commonwealth-vlr-engine) [![Coverage Status](https://coveralls.io/repos/boston-library/commonwealth-vlr-engine/badge.svg?branch=master&service=github)](https://coveralls.io/github/boston-library/commonwealth-vlr-engine?branch=master)
A virtual local repository is an application that provides digital object discovery and display functionality without the overhead of actual asset management, pulling content via APIs from a larger repository managed elsewhere. The subset of content to be displayed can be based on any valid repository search or facet query parameters for descriptive, administrative, or technical metadata.
@@ -20,20 +20,28 @@ $ cd app_name
```
Add Commonwealth-VLR-Engine to your Gemfile:
```ruby
-gem 'commonwealth-vlr-engine', :git => 'https://github.com/boston-library/commonwealth-vlr-engine'
+gem 'commonwealth-vlr-engine', git: 'https://github.com/boston-library/commonwealth-vlr-engine'
```
Run the VLR-Engine install:
```
+$ bundle install
$ rails generate commonwealth_vlr_engine:install
+# Note: if you want to include user functionality (bookmarks, folders, saved searches, etc) via Devise and Bpluser use:
+# $ rails generate commonwealth_vlr_engine:install --bpluser
$ rake db:migrate
```
-You will then need to configure various YAML files to point to existing Solr, Fedora, and IIIF image servers.
+You will then need to configure various ENV vars to point to existing Solr, Fedora, and IIIF image servers.
+(See `.env.example` generated into your app's home directory.)
+
+The installer will ask to overwrite your app's local `config/locales/blacklight.en.yml` (and `config/locales/devise.en.yml` if you run the install with `--bpluser`).
+If you choose not to overwrite these files during the installation, you can refer to `lib/generators/commonwealth_vlr_engine/templates/config` for an example of what values are expected in your app.
## Blacklight Version Compatibility
The table below indicates which versions of Commonwealth-VLR-Engine are compatible with which versions of Blacklight.
VLR-Engine version | works with Blacklight version
----------------------- | ---------------------
+0.1.0 | >= 7.12.1 to < 8.*
0.0.7 | >= 6.3.0 to < 7.*
0.0.2 | >= 6.1.0 to < 6.3
0.0.1 | >= 5.14.0 to < 6.*
@@ -46,25 +54,18 @@ After cloning the repository, and running `bundle install`, run `bundle exec rak
3. Start Solr and index the sample Solr docs from `spec/fixtures`
4. Run all specs
-NOTE: Many of the specs will fail initially. Check the YAML files in `.internal_test_app/conig` (especially `fedora.yml` and `iiif_server.yml`) and make sure they're pointing to the correct URLs.
-
### Useful Development commands
Generate the test application at `.internal_test_app`:
```
$ rake engine_cart:generate
```
-NOTE: after running this you need to delete these two lines lin the `.internal_test_app` `Gemfile`s :test group
-```
- gem 'selenium-webdriver'
- gem 'chromedriver-helper'
-```
-Re-run `bundle install` in the root of `.internal_test_app`
+
Destroy the test application at `.internal_test_app`:
```
$ rake engine_cart:clean
```
-Start Solr (run in new terminal from project home):
+Start Solr (run in new terminal from `.internal_test_app` home):
```
$ solr_wrapper
```
@@ -81,7 +82,7 @@ Index sample Solr docs (run from `internal_test_app`):
# Solr must be running
$ RAILS_ENV=test bundle exec rake commonwealth_vlr_engine:test_index:seed
```
-Run specs (Solr and BPL Dev IIIF image server must be running):
+Run specs (Solr must be running):
```
# run all tests
$ bundle exec rake spec
diff --git a/Rakefile b/Rakefile
index 256d60f1..e8549dfc 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rubygems'
begin
require 'bundler/setup'
@@ -29,12 +31,21 @@ require 'solr_wrapper'
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new
-desc 'Run test suite'
-task ci: ['engine_cart:generate'] do
+require 'rubocop/rake_task'
+RuboCop::RakeTask.new(:rubocop) do |task|
+ task.requires << 'rubocop-rails'
+ task.requires << 'rubocop-rspec'
+ task.requires << 'rubocop-performance'
+ task.fail_on_error = true
+ # WARNING: Make sure the bottom 3 lines are always commented out before committing
+ # task.options << '--safe-auto-correct'
+ # task.options << '--disable-uncorrectable'
+ # task.options << '-d'
+end
+
+desc 'Lint, set up test app, spin up Solr, and run test suite'
+task ci: [:rubocop, 'engine_cart:generate'] do
SolrWrapper.wrap do |solr|
- Dir.glob(File.join(__dir__, 'lib', 'generators', 'commonwealth_vlr_engine', 'templates', 'solr', 'conf', '*.xml')) do |file|
- puts FileUtils.cp file, solr.config.collection_options[:dir]
- end
solr.with_collection do
within_test_app do
system 'RAILS_ENV=test rake commonwealth_vlr_engine:test_index:seed'
diff --git a/app/assets/javascripts/blacklight_google_analytics/blacklight_google_analytics.js.erb b/app/assets/javascripts/blacklight_google_analytics/blacklight_google_analytics.js.erb
index 2ebf1921..4c963e7d 100644
--- a/app/assets/javascripts/blacklight_google_analytics/blacklight_google_analytics.js.erb
+++ b/app/assets/javascripts/blacklight_google_analytics/blacklight_google_analytics.js.erb
@@ -21,156 +21,134 @@ $(function() {
return identifier;
};
- var category = $('body').attr('class').split(' ')[1].toString().replace(/blacklight-/,'').replace(/-/,'#');
+ BlacklightGoogleAnalytics.track_event = function(category, action, label) {
+ if (category === undefined) {
+ category = $('body').attr('class').split(' ')[1].toString().replace(/blacklight-/,'').replace(/-/,'#');
+ }
+ // uncomment below for logging in development
+ // console.log(category, action, label);
+ ga('send', 'event', category, action, label);
+ };
- // generic link tracking
- $('a').click(function () {
+ BlacklightGoogleAnalytics.track_link_clicks = function(element, category) {
+ var link = $(element);
try {
- var action = BlacklightGoogleAnalytics.this_or_parent_id($(this));
- var label = ($(this).text() || $(this).children('img:first').attr('alt'));
- if (action === 'facets-collapse') { // for facets, make the action the facet heading
- var action = 'facet_' + $(this).parents("div:first").find("h5:first").text().trim();
- } else if (action === 'documents') { // search results
- var action = 'result_' + $(this).parents("div:first").attr('class');
- if ($(this).data('counter')) {
- var label = $(this).data('counter');
+ var action = BlacklightGoogleAnalytics.this_or_parent_id(link);
+ var label = (link.text() || link.children('img:first').attr('alt'));
+ if (action === 'documents') { // search results
+ action = 'result_' + link.parents("div:first").attr('class');
+ if (link.data('counter')) {
+ label = link.data('counter');
}
} else if (action === 'item_metadata') { // catalog#show metadata links
- var label = $(this).parent().prev("dt").text().replace(/:/,'');
+ label = link.parent().prev("dt").text().replace(/:/,'');
} else if (action === 'item_breadcrumb') { // catalog#show breadcrumb
- var label = $(this).attr('class');
+ label = link.attr('class');
} else if (action === 'institution_site_link') { // institutions#show external site URL
- var label = $('img.institution_img_show').attr('alt');
+ label = $('img.institution_img_show').attr('alt');
}
-
- ga('send', 'event', category, action, label);
+ BlacklightGoogleAnalytics.track_event(category, action, label);
} catch (err) {
BlacklightGoogleAnalytics.console_log_error(err, [category, action, label]);
}
- //BlacklightGoogleAnalytics.pause();
- });
-
- // "more" facet ajax-modal clicks
- BlacklightGoogleAnalytics.track_modal_facet_clicks = function () {
- $("#ajax-modal").find('a').click(function () {
- try {
- var action = 'facet_' + $('div.modal-header').find('h3').text();
- var label = $(this).text();
- ga('send', 'event', category, action, label);
- } catch (err) {
- BlacklightGoogleAnalytics.console_log_error(err, [category, action, label]);
- }
- });
};
- // modal form submission
- BlacklightGoogleAnalytics.track_modal_form = function () {
- $("#ajax-modal").find('form').submit(function () {
- try{
- var action = 'submit_' + BlacklightGoogleAnalytics.this_or_parent_id($(this));
- ga('send', 'event', category, action);
- } catch(err) {
- BlacklightGoogleAnalytics.console_log_error(err, [category, action]);
- }
- });
- };
-
- // OAI item clicks
- $("#oai_img_show_container").find("a").off("click").click(function(){
+ BlacklightGoogleAnalytics.track_form_submit = function(element, category) {
try{
- var action = 'oai_item_link';
- var label = $('#item_breadcrumb').find("a.institution_breadcrumb").text();
- ga('send', 'event', category, action, label);
+ var action = BlacklightGoogleAnalytics.this_or_parent_id($(element));
+ var label = "";
+ if (action === "folder_item_toggle") { // add item to bookmarks
+ label = "Bookmarks";
+ } else if (action === "item_actions_form") { // bookmarks/folders item delete
+ action = "removeLink";
+ label = "Remove"
+ } else if (action === "hero_search_form") { // home page search
+ label = $("#search_field").val();
+ }
+ BlacklightGoogleAnalytics.track_event(category, action, label);
} catch(err) {
BlacklightGoogleAnalytics.console_log_error(err, [category, action, label]);
}
+ };
+
+ // generic link tracking
+ $('a').click(function () {
+ BlacklightGoogleAnalytics.track_link_clicks(this);
+ });
+
+ // form submissions
+ $("form").submit(function() {
+ BlacklightGoogleAnalytics.track_form_submit(this);
});
// saved searches clicks
- $("#searches_content").find("a").off("click").click(function(){
+ $("#searches_content").find("a").off("click").click(function() {
try{
if ($(this).attr('class')) {
var action = $(this).attr('class');
} else {
var action = 'link_to_saved_search';
}
- ga('send', 'event', category, action);
+ BlacklightGoogleAnalytics.track_event(undefined, action, '');
} catch(err) {
- BlacklightGoogleAnalytics.console_log_error(err, [category, action]);
+ BlacklightGoogleAnalytics.console_log_error(err, [action]);
}
});
// search history clicks
- $("#searches_list").find("a").off("click").click(function(){
+ $("#searches_list").find("a").off("click").click(function() {
try{
var action = 'link_to_previous_search';
- ga('send', 'event', category, action);
+ BlacklightGoogleAnalytics.track_event(undefined, action, '');
} catch(err) {
- BlacklightGoogleAnalytics.console_log_error(err, [category, action]);
+ BlacklightGoogleAnalytics.console_log_error(err, [action]);
}
});
- // collections#show series clicks
- $("#series_wrapper").find("a").off("click").click(function(){
+ // search history save search
+ $("#searches_list").find("form").off("submit").submit(function() {
try{
- var action = 'series_' + $(this).parents("div:first").attr('class');
- var label = ($(this).text() || $(this).children('img:first').attr('alt'));
- ga('send', 'event', category, action, label);
+ var action = 'save_search';
+ BlacklightGoogleAnalytics.track_event(undefined, action, '');
} catch(err) {
- BlacklightGoogleAnalytics.console_log_error(err, [category, action, label]);
+ BlacklightGoogleAnalytics.console_log_error(err, [action]);
}
});
- // institutions#show collection clicks
- $("#institution_collections").find("a").off("click").click(function(){
+ // collections#show series clicks
+ $("#series_wrapper").find("a").off("click").click(function() {
try{
- var action = 'collections_' + $(this).parents("div:first").attr('class');
+ var action = 'series_' + $(this).parents("div:first").attr('class');
var label = ($(this).text() || $(this).children('img:first').attr('alt'));
- ga('send', 'event', category, action, label);
+ BlacklightGoogleAnalytics.track_event(undefined, action, label);
} catch(err) {
- BlacklightGoogleAnalytics.console_log_error(err, [category, action, label]);
+ BlacklightGoogleAnalytics.console_log_error(err, [action, label]);
}
});
- // form submissions
- $("form").submit(function(){
+ // institutions#show collection clicks
+ $("#institution_collections").find("a").off("click").click(function() {
try{
- var action = BlacklightGoogleAnalytics.this_or_parent_id($(this));
- var label = "";
- if (action === "folder_item_toggle") { // add item to bookmarks
- var label = "Bookmarks";
- } else if (action === "item_actions_form") { // bookmarks/folders item delete
- var action = "removeLink";
- var label = "Remove"
- } else if (action === "hero_search_form") { // home page search
- var label = $("#search_field").val();
- }
- ga('send', 'event', category, action, label);
+ var action = 'collections_' + $(this).parents("div:first").attr('class');
+ var label = ($(this).text() || $(this).children('img:first').attr('alt'));
+ BlacklightGoogleAnalytics.track_event(undefined, action, label);
} catch(err) {
- BlacklightGoogleAnalytics.console_log_error(err, [category, action, label]);
+ BlacklightGoogleAnalytics.console_log_error(err, [action, label]);
}
});
// image_viewer#book_viewer button clicks
- $("#viewer").find("button").click(function(){
+ // DEPRECATED, but leave here for possible future use:
+ // https://github.com/boston-library/commonwealth-vlr-engine/issues/6
+ /*
+ $("#viewer").find("button").click(function() {
try{
var action = BlacklightGoogleAnalytics.this_or_parent_id($(this));
var label = '';
- ga('send', 'event', category, action, label);
+ BlacklightGoogleAnalytics.track_event(undefined, action, label);
} catch(err) {
BlacklightGoogleAnalytics.console_log_error(err, [category, action, label]);
}
})
-
- // start download button clicks
- $("#downloads_start_links").find("a").off("click").click(function(){
- try{
- var action = 'trigger_download';
- var label = $(this).attr('class').split(' ').pop();
- ga('send', 'event', category, action, label);
- } catch(err) {
- BlacklightGoogleAnalytics.console_log_error(err, [category, action, label]);
- }
- })
-
+ */
});
diff --git a/app/assets/javascripts/bootstrap-accessibility-plugin/bootstrap-accessibility.js b/app/assets/javascripts/bootstrap-accessibility-plugin/bootstrap-accessibility.js
deleted file mode 100644
index 8b816d19..00000000
--- a/app/assets/javascripts/bootstrap-accessibility-plugin/bootstrap-accessibility.js
+++ /dev/null
@@ -1,586 +0,0 @@
-/* modified to remove code relating to Bootstrap JS components not used by
- Blacklight or CommonwealthVLREngine (tab)
- otherwise default version of this script throws errors like:
- "Uncaught TypeError: Cannot read property 'Constructor' of undefined" about tab
-*/
-/* ========================================================================
- * Extends Bootstrap v3.1.1
-
- * Copyright (c) <2015> PayPal
-
- * All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
-
- * Neither the name of PayPal or any of its subsidiaries or affiliates nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
-
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- * ======================================================================== */
-
-
-(function($) {
- "use strict";
-
- // GENERAL UTILITY FUNCTIONS
- // ===============================
-
- var uniqueId = function(prefix) {
- return (prefix || 'ui-id') + '-' + Math.floor((Math.random()*1000)+1)
- }
-
-
- var removeMultiValAttributes = function (el, attr, val) {
- var describedby = (el.attr( attr ) || "").split( /\s+/ )
- , index = $.inArray(val, describedby)
- if ( index !== -1 ) {
- describedby.splice( index, 1 )
- }
- describedby = $.trim( describedby.join( " " ) )
- if (describedby ) {
- el.attr( attr, describedby )
- } else {
- el.removeAttr( attr )
- }
- }
-
-// selectors Courtesy: https://github.com/jquery/jquery-ui/blob/master/ui/core.js
- var focusable = function ( element, isTabIndexNotNaN ) {
- var map, mapName, img,
- nodeName = element.nodeName.toLowerCase();
- if ( "area" === nodeName ) {
- map = element.parentNode;
- mapName = map.name;
- if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
- return false;
- }
- img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
- return !!img && visible( img );
- }
- return ( /input|select|textarea|button|object/.test( nodeName ) ?
- !element.disabled :
- "a" === nodeName ?
- element.href || isTabIndexNotNaN :isTabIndexNotNaN) && visible( element ); // the element and all of its ancestors must be visible
- }
- var visible = function ( element ) {
- return $.expr.filters.visible( element ) &&
- !$( element ).parents().addBack().filter(function() {
- return $.css( this, "visibility" ) === "hidden";
- }).length;
- }
-
- $.extend( $.expr[ ":" ], {
- data: $.expr.createPseudo ?
- $.expr.createPseudo(function( dataName ) {
- return function( elem ) {
- return !!$.data( elem, dataName );
- };
- }) :
- // support: jQuery <1.8
- function( elem, i, match ) {
- return !!$.data( elem, match[ 3 ] );
- },
-
- focusable: function( element ) {
- return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
- },
-
- tabbable: function( element ) {
- var tabIndex = $.attr( element, "tabindex" ),
- isTabIndexNaN = isNaN( tabIndex );
- return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
- }
- });
-
- // Modal Extension
- // ===============================
-
- $('.modal-dialog').attr( {'role' : 'document'})
- var modalhide = $.fn.modal.Constructor.prototype.hide
- $.fn.modal.Constructor.prototype.hide = function(){
- modalhide.apply(this, arguments)
- $(document).off('keydown.bs.modal')
- }
-
- var modalfocus = $.fn.modal.Constructor.prototype.enforceFocus
- $.fn.modal.Constructor.prototype.enforceFocus = function(){
- var focEls = this.$element.find(":tabbable")
- , lastEl = focEls[focEls.length-1]
- $(document).on('keydown.bs.modal', $.proxy(function (ev) {
- if(!this.$element.has(ev.target).length && ev.shiftKey && ev.keyCode === 9) {
- lastEl.focus()
- ev.preventDefault();
- }
- }, this))
-
- modalfocus.apply(this, arguments)
- }
-
- // DROPDOWN Extension
- // ===============================
-
- var toggle = '[data-toggle=dropdown]'
- , $par
- , firstItem
- , focusDelay = 200
- , menus = $(toggle).parent().find('ul').attr('role','menu')
- , lis = menus.find('li').attr('role','presentation')
-
- lis.find('a').attr({'role':'menuitem', 'tabIndex':'-1'})
- $(toggle).attr({ 'aria-haspopup':'true', 'aria-expanded': 'false'})
-
- $(toggle).parent().on('shown.bs.dropdown',function(e){
- $par = $(this)
- var $toggle = $par.find(toggle)
- $toggle.attr('aria-expanded','true')
- $toggle.on('keydown.bs.dropdown', $.proxy(function (ev) {
- setTimeout(function(){
- firstItem = $('.dropdown-menu [role=menuitem]:visible', $par)[0]
- try{ firstItem.focus()} catch(ex) {}
- }, focusDelay)
- }, this))
-
- })
-
- $(toggle).parent().on('hidden.bs.dropdown',function(e){
- $par = $(this)
- var $toggle = $par.find(toggle)
- $toggle.attr('aria-expanded','false')
- })
-
- $(document)
- .on('focusout.dropdown.data-api', '.dropdown-menu', function(e){
- var $this = $(this)
- , that = this
- setTimeout(function() {
- if(!$.contains(that, document.activeElement)){
- $this.parent().removeClass('open')
- $this.parent().find('[data-toggle=dropdown]').attr('aria-expanded','false')
- }
- }, 150)
- })
- .on('keydown.bs.dropdown.data-api', toggle + ', [role=menu]' , $.fn.dropdown.Constructor.prototype.keydown)
-
- // Collapse Extension
- // ===============================
-
- var $colltabs = $('[data-toggle="collapse"]')
- $colltabs.each(function( index ) {
- var colltab = $(this)
- , collpanel = (colltab.attr('data-target')) ? $(colltab.attr('data-target')) : $(colltab.attr('href'))
- , parent = colltab.attr('data-parent')
- , collparent = parent && $(parent)
- , collid = colltab.attr('id') || uniqueId('ui-collapse')
-
- colltab.attr('id', collid)
-
- if(collparent){
- colltab.attr({ 'role':'tab', 'aria-selected':'false', 'aria-expanded':'false' })
- $(collparent).find('div:not(.collapse,.panel-body), h4').attr('role','presentation')
- collparent.attr({ 'role' : 'tablist', 'aria-multiselectable' : 'true' })
-
- if(collpanel.hasClass('in')){
- colltab.attr({ 'aria-controls': collpanel.attr('id'), 'aria-selected':'true', 'aria-expanded':'true', 'tabindex':'0' })
- collpanel.attr({ 'role':'tabpanel', 'tabindex':'0', 'aria-labelledby':collid, 'aria-hidden':'false' })
- }else{
- colltab.attr({'aria-controls' : collpanel.attr('id'), 'tabindex':'-1' })
- collpanel.attr({ 'role':'tabpanel', 'tabindex':'-1', 'aria-labelledby':collid, 'aria-hidden':'true' })
- }
- }
- })
-
- var collToggle = $.fn.collapse.Constructor.prototype.toggle
- $.fn.collapse.Constructor.prototype.toggle = function(){
- var prevTab = this.$parent && this.$parent.find('[aria-expanded="true"]') , href
-
- if(prevTab){
- var prevPanel = prevTab.attr('data-target') || (href = prevTab.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')
- , $prevPanel = $(prevPanel)
- , $curPanel = this.$element
- , par = this.$parent
- , curTab
-
- if (this.$parent) curTab = this.$parent.find('[data-toggle=collapse][href="#' + this.$element.attr('id') + '"]')
-
- collToggle.apply(this, arguments)
-
- if ($.support.transition) {
- this.$element.one($.support.transition.end, function(){
-
- prevTab.attr({ 'aria-selected':'false','aria-expanded':'false', 'tabIndex':'-1' })
- $prevPanel.attr({ 'aria-hidden' : 'true','tabIndex' : '-1'})
-
- curTab.attr({ 'aria-selected':'true','aria-expanded':'true', 'tabIndex':'0' })
-
- if($curPanel.hasClass('in')){
- $curPanel.attr({ 'aria-hidden' : 'false','tabIndex' : '0' })
- }else{
- curTab.attr({ 'aria-selected':'false','aria-expanded':'false'})
- $curPanel.attr({ 'aria-hidden' : 'true','tabIndex' : '-1' })
- }
- })
- }
- }else{
- collToggle.apply(this, arguments)
- }
- }
-
- $.fn.collapse.Constructor.prototype.keydown = function (e) {
- var $this = $(this)
- , $items
- , $tablist = $this.closest('div[role=tablist] ')
- , index
- , k = e.which || e.keyCode
-
- $this = $(this)
- if (!/(32|37|38|39|40)/.test(k)) return
- if(k==32) $this.click()
-
- $items = $tablist.find('[role=tab]')
- index = $items.index($items.filter(':focus'))
-
- if (k == 38 || k == 37) index-- // up & left
- if (k == 39 || k == 40) index++ // down & right
- if(index < 0) index = $items.length -1
- if(index == $items.length) index = 0
-
- $items.eq(index).focus()
-
- e.preventDefault()
- e.stopPropagation()
-
- }
-
- $(document).on('keydown.collapse.data-api','[data-toggle="collapse"]' , $.fn.collapse.Constructor.prototype.keydown)
-
-// Carousel Extension
- // ===============================
-
- $('.carousel').each(function (index) {
-
- // This function positions a highlight box around the tabs in the tablist to use in focus styling
-
- function setTablistHighlightBox() {
-
- var $tab
- , offset
- , height
- , width
- , highlightBox = {}
-
- highlightBox.top = 0
- highlightBox.left = 32000
- highlightBox.height = 0
- highlightBox.width = 0
-
- for (var i = 0; i < $tabs.length; i++) {
- $tab = $tabs[i]
- offset = $($tab).offset()
- height = $($tab).height()
- width = $($tab).width()
-
-// console.log(" Top: " + offset.top + " Left: " + offset.left + " Height: " + height + " Width: " + width)
-
- if (highlightBox.top < offset.top) {
- highlightBox.top = Math.round(offset.top)
- }
-
- if (highlightBox.height < height) {
- highlightBox.height = Math.round(height)
- }
-
- if (highlightBox.left > offset.left) {
- highlightBox.left = Math.round(offset.left)
- }
-
- var w = (offset.left - highlightBox.left) + Math.round(width)
-
- if (highlightBox.width < w) {
- highlightBox.width = w
- }
-
- } // end for
-
-// console.log("[HIGHLIGHT] Top: " + highlightBox.top + " Left: " + highlightBox.left + " Height: " + highlightBox.height + " Width: " + highlightBox.width)
-
- $tablistHighlight.style.top = (highlightBox.top - 2) + 'px'
- $tablistHighlight.style.left = (highlightBox.left - 2) + 'px'
- $tablistHighlight.style.height = (highlightBox.height + 7) + 'px'
- $tablistHighlight.style.width = (highlightBox.width + 8) + 'px'
-
- } // end function
-
- var $this = $(this)
- , $prev = $this.find('[data-slide="prev"]')
- , $next = $this.find('[data-slide="next"]')
- , $tablist = $this.find('.carousel-indicators')
- , $tabs = $this.find('.carousel-indicators li')
- , $tabpanels = $this.find('.item')
- , $tabpanel
- , $tablistHighlight
- , $pauseCarousel
- , $complementaryLandmark
- , $tab
- , $is_paused = false
- , offset
- , height
- , width
- , i
- , id_title = 'id_title'
- , id_desc = 'id_desc'
-
-
- $tablist.attr('role', 'tablist')
-
- $tabs.focus(function() {
- $this.carousel('pause')
- $is_paused = true
- $pauseCarousel.innerHTML = "Play Carousel"
- $(this).parent().addClass('active');
-// $(this).addClass('focus')
- setTablistHighlightBox()
- $($tablistHighlight).addClass('focus')
- $(this).parents('.carousel').addClass('contrast')
- })
-
- $tabs.blur(function(event) {
- $(this).parent().removeClass('active');
-// $(this).removeClass('focus')
- $($tablistHighlight).removeClass('focus')
- $(this).parents('.carousel').removeClass('contrast')
- })
-
-
- for (i = 0; i < $tabpanels.length; i++) {
- $tabpanel = $tabpanels[i]
- $tabpanel.setAttribute('role', 'tabpanel')
- $tabpanel.setAttribute('id', 'tabpanel-' + index + '-' + i)
- $tabpanel.setAttribute('aria-labelledby', 'tab-' + index + '-' + i)
- }
-
- if (typeof $this.attr('role') !== 'string') {
- $this.attr('role', 'complementary');
- $this.attr('aria-labelledby', id_title);
- $this.attr('aria-describedby', id_desc);
- $this.prepend('
A carousel is a rotating set of images, rotation stops on keyboard focus on carousel tab controls or hovering the mouse pointer over images. Use the tabs or the previous and next buttons to change the displayed slide.
')
- $this.prepend('
Carousel content with ' + $tabpanels.length + ' slides.
')
- }
-
-
- for (i = 0; i < $tabs.length; i++) {
- $tab = $tabs[i]
-
- $tab.setAttribute('role', 'tab')
- $tab.setAttribute('id', 'tab-' + index + '-' + i)
- $tab.setAttribute('aria-controls', 'tabpanel-' + index + '-' + i)
-
- var tpId = '#tabpanel-' + index + '-' + i
- var caption = $this.find(tpId).find('h1').text()
-
- if ((typeof caption !== 'string') || (caption.length === 0)) caption = $this.find(tpId).text()
- if ((typeof caption !== 'string') || (caption.length === 0)) caption = $this.find(tpId).find('h3').text()
- if ((typeof caption !== 'string') || (caption.length === 0)) caption = $this.find(tpId).find('h4').text()
- if ((typeof caption !== 'string') || (caption.length === 0)) caption = $this.find(tpId).find('h5').text()
- if ((typeof caption !== 'string') || (caption.length === 0)) caption = $this.find(tpId).find('h6').text()
- if ((typeof caption !== 'string') || (caption.length === 0)) caption = "no title";
-
-// console.log("CAPTION: " + caption )
-
- var tabName = document.createElement('span')
- tabName.setAttribute('class', 'sr-only')
- tabName.innerHTML='Slide ' + (i+1)
- if (caption) tabName.innerHTML += ": " + caption
- $tab.appendChild(tabName)
-
- }
-
- // create div for focus styling of tablist
- $tablistHighlight = document.createElement('div')
- $tablistHighlight.className = 'carousel-tablist-highlight'
- document.body.appendChild($tablistHighlight)
-
- // create button for screen reader users to stop rotation of carousel
-
- // create button for screen reader users to pause carousel for virtual mode review
- $complementaryLandmark = document.createElement('aside')
- $complementaryLandmark.setAttribute('aria-label', 'carousel pause/play control')
- $(document.body).prepend($complementaryLandmark)
-
- $pauseCarousel = document.createElement('button')
- $pauseCarousel.className = "carousel-pause-button"
- $pauseCarousel.innerHTML = "Pause Carousel"
- $pauseCarousel.setAttribute('title', "Pause/Play carousel button can be used by screen reader users to stop carousel animations")
- $($complementaryLandmark).append($pauseCarousel)
-
- $($pauseCarousel).click(function() {
- if ($is_paused) {
- $pauseCarousel.innerHTML = "Pause Carousel"
- $this.carousel('cycle')
- $is_paused = false
- }
- else {
- $pauseCarousel.innerHTML = "Play Carousel"
- $this.carousel('pause')
- $is_paused = true
- }
- })
- $($pauseCarousel).focus(function() {
- $(this).addClass('focus')
- })
-
- $($pauseCarousel).blur(function() {
- $(this).removeClass('focus')
- })
-
- setTablistHighlightBox()
-
- $( window ).resize(function() {
- setTablistHighlightBox()
- })
-
- // Add space bar behavior to prev and next buttons for SR compatibility
- $prev.attr('aria-label', 'Previous Slide')
- $prev.keydown(function(e) {
- var k = e.which || e.keyCode
- if (/(13|32)/.test(k)) {
- e.preventDefault()
- e.stopPropagation()
- $prev.trigger('click');
- }
- });
-
- $prev.focus(function() {
- $(this).parents('.carousel').addClass('contrast')
- })
-
- $prev.blur(function() {
- $(this).parents('.carousel').removeClass('contrast')
- })
-
- $next.attr('aria-label', 'Next Slide')
- $next.keydown(function(e) {
- var k = e.which || e.keyCode
- if (/(13|32)/.test(k)) {
- e.preventDefault()
- e.stopPropagation()
- $next.trigger('click');
- }
- });
-
- $next.focus(function() {
- $(this).parents('.carousel').addClass('contrast')
- })
-
- $next.blur(function() {
- $(this).parents('.carousel').removeClass('contrast')
- })
-
- $('.carousel-inner a').focus(function() {
- $(this).parents('.carousel').addClass('contrast')
- })
-
- $('.carousel-inner a').blur(function() {
- $(this).parents('.carousel').removeClass('contrast')
- })
-
- $tabs.each(function () {
- var item = $(this)
- if(item.hasClass('active')) {
- item.attr({ 'aria-selected': 'true', 'tabindex' : '0' })
- }else{
- item.attr({ 'aria-selected': 'false', 'tabindex' : '-1' })
- }
- })
- })
-
- var slideCarousel = $.fn.carousel.Constructor.prototype.slide
- $.fn.carousel.Constructor.prototype.slide = function (type, next) {
- var $element = this.$element
- , $active = $element.find('[role=tabpanel].active')
- , $next = next || $active[type]()
- , $tab
- , $tab_count = $element.find('[role=tabpanel]').size()
- , $prev_side = $element.find('[data-slide="prev"]')
- , $next_side = $element.find('[data-slide="next"]')
- , $index = 0
- , $prev_index = $tab_count -1
- , $next_index = 1
- , $id
-
- if ($next && $next.attr('id')) {
- $id = $next.attr('id')
- $index = $id.lastIndexOf("-")
- if ($index >= 0) $index = parseInt($id.substring($index+1), 10)
-
- $prev_index = $index - 1
- if ($prev_index < 1) $prev_index = $tab_count - 1
-
- $next_index = $index + 1
- if ($next_index >= $tab_count) $next_index = 0
- }
-
- $prev_side.attr('aria-label', 'Show slide ' + ($prev_index+1) + ' of ' + $tab_count)
- $next_side.attr('aria-label', 'Show slide ' + ($next_index+1) + ' of ' + $tab_count)
-
-
- slideCarousel.apply(this, arguments)
-
- $active
- .one('bsTransitionEnd', function () {
- var $tab
-
- $tab = $element.find('li[aria-controls="' + $active.attr('id') + '"]')
- if ($tab) $tab.attr({'aria-selected':false, 'tabIndex': '-1'})
-
- $tab = $element.find('li[aria-controls="' + $next.attr('id') + '"]')
- if ($tab) $tab.attr({'aria-selected': true, 'tabIndex': '0'})
-
- })
- }
-
- var $this;
- $.fn.carousel.Constructor.prototype.keydown = function (e) {
-
- $this = $this || $(this)
- if(this instanceof Node) $this = $(this)
-
- function selectTab(index) {
- if (index >= $tabs.length) return
- if (index < 0) return
-
- $carousel.carousel(index)
- setTimeout(function () {
- $tabs[index].focus()
- // $this.prev().focus()
- }, 150)
- }
-
- var $carousel = $(e.target).closest('.carousel')
- , $tabs = $carousel.find('[role=tab]')
- , k = e.which || e.keyCode
- , index
-
- if (!/(37|38|39|40)/.test(k)) return
-
- index = $tabs.index($tabs.filter('.active'))
- if (k == 37 || k == 38) { // Up
- index--
- selectTab(index);
- }
-
- if (k == 39 || k == 40) { // Down
- index++
- selectTab(index);
- }
-
- e.preventDefault()
- e.stopPropagation()
- }
- $(document).on('keydown.carousel.data-api', 'li[role=tab]', $.fn.carousel.Constructor.prototype.keydown)
-
-
-})(jQuery);
\ No newline at end of file
diff --git a/app/assets/javascripts/commonwealth-vlr-engine.js b/app/assets/javascripts/commonwealth-vlr-engine.js
index 51772801..7bcfc6fa 100644
--- a/app/assets/javascripts/commonwealth-vlr-engine.js
+++ b/app/assets/javascripts/commonwealth-vlr-engine.js
@@ -1,28 +1,19 @@
//
// Required by Blacklight-Maps
//= require blacklight-maps
-//= require leaflet.markercluster
+
// Required by Blacklight-Gallery
-//= require blacklight_gallery.js
+//= require blacklight_gallery
// Blacklight-centric Google Analytics event tracking
//= require blacklight_google_analytics/blacklight_google_analytics
-// disable main header dropdown menus on tablet/mobile
-//= require commonwealth-vlr-engine/disable_dropdown_nav
-
// site-wide utilities
//= require commonwealth-vlr-engine/vlr_utils
-// for IE8 responsiveness
-//= require respond/respond.min
-
-// bootstrap-accessibility-plugin
-//= require bootstrap-accessibility-plugin/bootstrap-accessibility
-
// blacklight_range_limit
//= require 'blacklight_range_limit'
-// WARNING: require tree disabled to avoid heavy JS files such as modernizr, openseadragon, etc.
+// WARNING: require tree disabled to avoid heavy JS files such as openseadragon
// from being automatically included on pages that don't need them
// WARNING: to require any further app-specific JS, you must use the 'require_directory' directive
diff --git a/app/assets/javascripts/commonwealth-vlr-engine/collection_facets.js b/app/assets/javascripts/commonwealth-vlr-engine/collection_facets.js
index 304e9cce..a1e44e2e 100644
--- a/app/assets/javascripts/commonwealth-vlr-engine/collection_facets.js
+++ b/app/assets/javascripts/commonwealth-vlr-engine/collection_facets.js
@@ -1,5 +1,4 @@
$(document).ready(function() {
- /* change the id of the series thumbnails facet so that collapse of */
- /* series sidebar facet works in tablet/phone view */
+ // needed for display/collapse of series facet
$('#series_wrapper').find('#facet-related_item_series_ssim').attr('id','facet-related_item_series_ssim_thumb-list');
});
diff --git a/app/assets/javascripts/commonwealth-vlr-engine/disable_dropdown_nav.js b/app/assets/javascripts/commonwealth-vlr-engine/disable_dropdown_nav.js
deleted file mode 100644
index b02ef2dc..00000000
--- a/app/assets/javascripts/commonwealth-vlr-engine/disable_dropdown_nav.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/* disable nav item dropdowns for navbar-collapse */
-/*
-function disable_dropdown_nav() {
- $('#header_main_nav').find('a.dropdown-toggle').addClass('disabled');
-}
-*/
-$(document).ready(function() {
- /*
- var nav_collapse_link = $('#nav_collapse_button');
-
- nav_collapse_link.click( function () {
- disable_dropdown_nav();
- });
- */
- // for iPad
- $('#nav_collapse_button').on("click touchstart", function () {
- //disable_dropdown_nav();
- $('#header_main_nav').find('a.dropdown-toggle').addClass('disabled');
- });
-
-});
\ No newline at end of file
diff --git a/app/assets/javascripts/commonwealth-vlr-engine/download_utils.js b/app/assets/javascripts/commonwealth-vlr-engine/download_utils.js
index 4c5ea44f..655b6416 100644
--- a/app/assets/javascripts/commonwealth-vlr-engine/download_utils.js
+++ b/app/assets/javascripts/commonwealth-vlr-engine/download_utils.js
@@ -1,4 +1,16 @@
-/* close the modal when the download button is clicked */
+/* close the modal when the download button is clicked; track events */
$('.trigger_download').on('click', function () {
- $('#ajax-modal').modal('hide');
+ // need this here, adding data-dismiss='modal' to link doesn't work
+ $('#blacklight-modal').modal('hide');
+
+ try{
+ var category = 'downloads#show';
+ var action = 'trigger_download';
+ var label = $(this).attr('class').split(' ').pop();
+ var pid = $(this).attr('href').split('/').pop().match(/^[a-z-:0-9]*/);
+ BlacklightGoogleAnalytics.track_event(category, action, label);
+ BlacklightGoogleAnalytics.track_event('downloads#items', pid, label);
+ } catch(err) {
+ BlacklightGoogleAnalytics.console_log_error(err, [category, action, label]);
+ }
});
diff --git a/app/assets/javascripts/commonwealth-vlr-engine/feedback_alerts.js.erb b/app/assets/javascripts/commonwealth-vlr-engine/feedback_alerts.js.erb
index 9289aca7..76d1c2be 100644
--- a/app/assets/javascripts/commonwealth-vlr-engine/feedback_alerts.js.erb
+++ b/app/assets/javascripts/commonwealth-vlr-engine/feedback_alerts.js.erb
@@ -9,9 +9,9 @@ $(document).ready (function () {
for (var i = 0; i < topic_options_keys.length; i++) {
if (selected_option == topic_options[topic_options_keys[i]].option) {
if (topic_options[topic_options_keys[i]].help_text != '') {
- help_text_div.html(topic_options[topic_options_keys[i]].help_text).toggleClass("hidden", false);
+ help_text_div.html(topic_options[topic_options_keys[i]].help_text).css("display", "block");
} else {
- help_text_div.toggleClass("hidden", true)
+ help_text_div.css("display", "none")
}
}
}
diff --git a/app/assets/javascripts/commonwealth-vlr-engine/folder_tools.js b/app/assets/javascripts/commonwealth-vlr-engine/folder_tools.js
deleted file mode 100644
index f49c4ae5..00000000
--- a/app/assets/javascripts/commonwealth-vlr-engine/folder_tools.js
+++ /dev/null
@@ -1,26 +0,0 @@
-// item actions for folders and bookmarks
-
-$(document).ready ( function () {
- // remove duplicate buttons from form
- $('#cite_btn,#email_btn').remove();
- // add click event for any checkbox in doc list
- $(':checkbox[name="selected[]"]').click( function () {
- addCheckedToURL();
- });
-
- // select/unselect all
- $('#selectAllItems').click( function () {
- $(':checkbox[name="selected[]"]').prop('checked', this.checked);
- addCheckedToURL();
- });
-});
-
-
-// when any checkbox is selected, append the ids of all checked items to url
-function addCheckedToURL () {
- var checkboxValues = $('[name="selected[]"]:checked').serialize();
- checkboxValues = checkboxValues.replace(/selected/g,"id");
- $('#citeLink,#emailLink,#copyLink').attr('href', function(index,previousValue) {
- return previousValue.replace(/\?.*/,"?" + checkboxValues);
- });
-}
\ No newline at end of file
diff --git a/app/assets/javascripts/commonwealth-vlr-engine/home_search_autofocus.js b/app/assets/javascripts/commonwealth-vlr-engine/home_search_autofocus.js
deleted file mode 100644
index 1f629169..00000000
--- a/app/assets/javascripts/commonwealth-vlr-engine/home_search_autofocus.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/* we add autofocus attribute to search form input here
- otherwise twitter-typeahead-rails causes issues
- where keyboard doesn't come up on mobile devices */
-$(document).ready(function() {
- $('#hero_search_form').find('#q').attr('autofocus','autofocus');
-});
\ No newline at end of file
diff --git a/app/assets/javascripts/commonwealth-vlr-engine/multi_img_viewer.js.erb b/app/assets/javascripts/commonwealth-vlr-engine/multi_img_viewer.js.erb
index cf330cef..47ba183a 100644
--- a/app/assets/javascripts/commonwealth-vlr-engine/multi_img_viewer.js.erb
+++ b/app/assets/javascripts/commonwealth-vlr-engine/multi_img_viewer.js.erb
@@ -10,7 +10,7 @@ var scrollTarget = scrollingContainer.scrollTop();
/* show loading gif while waiting for selected image to load */
$('#multi_img_show_container').on("click", "a.prev_next", function () {
// display the loading icon
- $('#img_show_canvas').html('<%= image_tag('commonwealth-vlr-engine/loading.gif',:id => 'loading', :alt => 'Loading...') %>');
+ $('#img_show_canvas').html('<%= image_tag('commonwealth-vlr-engine/loading.gif', id: 'loading', alt: 'Loading...') %>');
// scroll the thumbnail
var selected_img = scrollingContainer.find("[data-viewer='" + $(this).data('viewer') + "']");
var position = selected_img.position().top;
diff --git a/app/assets/javascripts/commonwealth-vlr-engine/ocr_search_utils.js.erb b/app/assets/javascripts/commonwealth-vlr-engine/ocr_search_utils.js.erb
index 7f11d9ec..ec7cb53c 100644
--- a/app/assets/javascripts/commonwealth-vlr-engine/ocr_search_utils.js.erb
+++ b/app/assets/javascripts/commonwealth-vlr-engine/ocr_search_utils.js.erb
@@ -1,12 +1,13 @@
-/* various utilities for ocr search results display in Bootstrap modal and WDL-Viewer contexts */
+/* various utilities for ocr search results display in Bootstrap modal */
-var top_pagination_selector = '#ocr_search_details .page_links a';
-var bottom_pagination_selector = '#ocr_pagination #pagination_links a';
+var top_pagination_selector = '#ocr_search_details .page-links a';
+var bottom_pagination_selector = '#ocr_pagination a';
var relevancy_link_selector = '#sort-dropdown a';
-var page_rel_selectors = top_pagination_selector + ", " + bottom_pagination_selector + ", " + relevancy_link_selector;
+var suggest_link_selector = '#ocr_search_suggest a';
+var page_rel_selectors = top_pagination_selector + ", " + bottom_pagination_selector + ", " + relevancy_link_selector + ", " + suggest_link_selector;
/* pagination links should preserve the modal rather than reloading the page */
-$(page_rel_selectors).on("click", Blacklight.ajaxModal.modalAjaxLinkClick);
+$(page_rel_selectors).on("click", Blacklight.modal.modalAjaxLinkClick);
/* show loading status for results, next page, etc. */
$(page_rel_selectors).on("click", function() {
@@ -16,22 +17,6 @@ $('.ocr-search-form').submit(function() {
addModalTransition();
});
-/* if the window is displayed in the WDL-Viewer context, page links should trigger page changes via JS */
-if ($("body.wdl-viewer").length) {
- $(".book_page_link").on("click", function () {
- $('#ajax-modal').modal('hide');
- $viewer.trigger("goto-page-search",
- [1, this.href.match(/\d+$/), this.href.match(/ocr_q=[\S]+\#/)[0].replace('ocr_q=','').slice(0, -1)]);
- return false;
- });
-}
-
-/* so search queries entered by user don't accidentally trigger WDL-Viewer keyboard-based controls */
-$('#ocr_q').on('keydown', function (e) {
- // Avoid keys bubbling up to our top-level input handler:
- e.stopPropagation();
-});
-
/* toggle the ocr snippets collapse link text */
$('.ocr_snippets_expand').on('click', function() {
toggleText($(this),
@@ -39,7 +24,15 @@ $('.ocr_snippets_expand').on('click', function() {
'<%= I18n.t('blacklight.ocr.search.results.snippets.less') %>');
});
+$('a').click(function () {
+ BlacklightGoogleAnalytics.track_link_clicks(this, 'ocr_search#index');
+});
+
+$("form").submit(function() {
+ BlacklightGoogleAnalytics.track_form_submit(this, 'ocr_search#index');
+});
+
// add the .modal-transition class
function addModalTransition () {
$('#modal-transition').toggle();
-}
\ No newline at end of file
+}
diff --git a/app/assets/javascripts/commonwealth-vlr-engine/vlr_utils.js b/app/assets/javascripts/commonwealth-vlr-engine/vlr_utils.js
index 918683ec..f67f9b87 100644
--- a/app/assets/javascripts/commonwealth-vlr-engine/vlr_utils.js
+++ b/app/assets/javascripts/commonwealth-vlr-engine/vlr_utils.js
@@ -6,4 +6,3 @@ function toggleText (e, text1, text2) {
return text === text1 ? text2 : text1;
})
}
-
diff --git a/app/assets/javascripts/commonwealth-vlr-engine/volumes_list.js b/app/assets/javascripts/commonwealth-vlr-engine/volumes_list.js
deleted file mode 100644
index 27ba0415..00000000
--- a/app/assets/javascripts/commonwealth-vlr-engine/volumes_list.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/* prevent the Bootstrap-collapse-triggering volume title links from going to the link target */
-/* this allows links to still be clickable for users w/o JS */
-$('#volumes_wrapper').find('a.volume_title').on("click", function (e) {
- e.preventDefault();
-});
\ No newline at end of file
diff --git a/app/assets/javascripts/respond/respond.min.js b/app/assets/javascripts/respond/respond.min.js
deleted file mode 100644
index e8d6207f..00000000
--- a/app/assets/javascripts/respond/respond.min.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/*! Respond.js v1.4.2: min/max-width media query polyfill
- * Copyright 2014 Scott Jehl
- * Licensed under MIT
- * http://j.mp/respondjs */
-
-!function(a){"use strict";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){v(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))},g=function(a){return a.replace(c.regex.minmaxwh,"").match(c.regex.other)};if(c.ajax=f,c.queue=d,c.unsupportedmq=g,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,comments:/\/\*[^*]*\*+([^/][^*]*\*+)*\//gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,maxw:/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,minmaxwh:/\(\s*m(in|ax)\-(height|width)\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/gi,other:/\([^\)]*\)/g},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var h,i,j,k=a.document,l=k.documentElement,m=[],n=[],o=[],p={},q=30,r=k.getElementsByTagName("head")[0]||l,s=k.getElementsByTagName("base")[0],t=r.getElementsByTagName("link"),u=function(){var a,b=k.createElement("div"),c=k.body,d=l.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=k.createElement("body"),c.style.background="none"),l.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&l.insertBefore(c,l.firstChild),a=b.offsetWidth,f?l.removeChild(c):c.removeChild(b),l.style.fontSize=d,e&&(c.style.fontSize=e),a=j=parseFloat(a)},v=function(b){var c="clientWidth",d=l[c],e="CSS1Compat"===k.compatMode&&d||k.body[c]||d,f={},g=t[t.length-1],p=(new Date).getTime();if(b&&h&&q>p-h)return a.clearTimeout(i),i=a.setTimeout(v,q),void 0;h=p;for(var s in m)if(m.hasOwnProperty(s)){var w=m[s],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?j||u():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?j||u():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(n[w.rules]))}for(var C in o)o.hasOwnProperty(C)&&o[C]&&o[C].parentNode===r&&r.removeChild(o[C]);o.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=k.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,r.insertBefore(E,g.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(k.createTextNode(F)),o.push(E)}},w=function(a,b,d){var e=a.replace(c.regex.comments,"").replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var h=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},i=!f&&d;b.length&&(b+="/"),i&&(f=1);for(var j=0;f>j;j++){var k,l,o,p;i?(k=d,n.push(h(a))):(k=e[j].match(c.regex.findStyles)&&RegExp.$1,n.push(RegExp.$2&&h(RegExp.$2))),o=k.split(","),p=o.length;for(var q=0;p>q;q++)l=o[q],g(l)||m.push({media:l.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:n.length-1,hasquery:l.indexOf("(")>-1,minw:l.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:l.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}v()},x=function(){if(d.length){var b=d.shift();f(b.href,function(c){w(c,b.href,b.media),p[b.href]=!0,a.setTimeout(function(){x()},0)})}},y=function(){for(var b=0;b/gim,'').replace(/\bfunction\b/g,'function-') , ');'].join(''));
- return f();
- }
- } catch (e) { }
-
- return {"err":"Could not parse the JSON object"};
- };
-
- var affectJSON = function(json) {
- if(typeof json !== "object") {
- return;
- }
- for(var key in json) {
- value = json[key];
- switch(key.toLowerCase()) {
- case "mousewheelenabled":
- mouseWheelEnabled = !!value;
- break;
- case "fullaria":
- fullARIA = !!value;
- break;
- case "describedby":
- describedBy = String(value);
- break;
- case "norangebar":
- noRangeBar = !!value;
- break;
- case "html5animation":
- html5Animation = String(value).search(/^(jump|tween|timed)$/i) != -1 ? String(value).toLowerCase() : "jump";
- break;
- case "varsetrules":
- if("onfocus" in value) {
- varSetRules.onfocus = !!value.onfocus;
- }
- if("onvalue" in value) {
- varSetRules.onvalue = !!value.onvalue;
- }
- break;
- }
- }
- };
- var addEvent = function(obj, type, fn) {
- if(obj.addEventListener) {
- obj.addEventListener(type, fn, true);
- } else if(obj.attachEvent) {
- obj.attachEvent("on"+type, fn);
- }
- };
- var removeEvent = function(obj, type, fn) {
- try {
- if(obj.removeEventListener) {
- obj.removeEventListener(type, fn, true);
- } else if(obj.detachEvent) {
- obj.detachEvent("on"+type, fn);
- }
- } catch(err) {}
- };
- var stopEvent = function(e) {
- e = e || window.event;
- if(e.stopPropagation) {
- e.stopPropagation();
- e.preventDefault();
- }
-
- /*@cc_on@*/
- /*@if(@_win32)
- e.cancelBubble = true;
- e.returnValue = false;
- /*@end@*/
-
- return false;
- };
- var preventDefault = function(e) {
- e = e || window.event;
- if(e.preventDefault) {
- e.preventDefault();
- return;
- }
- e.returnValue = false;
- };
- // Add/Remove classname utility functions
- var addClass = function(e,c) {
- if(new RegExp("(^|\\s)" + c + "(\\s|$)").test(e.className)) {
- return;
- }
- e.className += ( e.className ? " " : "" ) + c;
- };
- var removeClass = function(e,c) {
- e.className = !c ? "" : e.className.replace(new RegExp("(^|\\s)" + c + "(\\s|$)"), " ").replace(/^\s\s*/, '').replace(/\s\s*$/, '');
- };
- // Returns an Object of key value pairs indicating which sliders have values
- // that have been "set" by the user. Normally used within form validation code
- var getValueSet = function() {
- var obj = {};
- for(var id in sliders) {
- obj[id] = sliders[id].getValueSet();
- }
- return obj;
- };
- // Sets the valueSet variable for a specific slider
- var setValueSet = function(sliderId, tf) {
- sliders[sliderId].setValueSet(!!tf);
- };
- // Does the slider exist in memory
- var sliderExists = function(slider) {
- return !!(slider in sliders && sliders.hasOwnProperty(slider));
- };
- // Javascript instantiation of a slider (input type="text|range" or select list)
- var createSlider = function(options) {
- if(!options || !options.inp || !options.inp.tagName || options.inp.tagName.search(/^input|select/i) == -1) { return false; }
-
- options.html5Shim = false;
-
- if(options.inp.tagName.toLowerCase() == "select") {
- if(options.inp.options.length < 2) {
- return false;
- }
- options.min = 0;
- options.max = options.inp.options.length - 1;
- options.step = 1;
- options.precision = 0;
- options.scale = false;
- options.forceValue = true;
- } else {
- if(String(options.inp.type).search(/^(text|range)$/i) == -1) {
- return false;
- }
- options.min = options.min && String(options.min).search(fpRegExp) != -1 ? +options.min : 0;
- options.max = options.max && String(options.max).search(fpRegExp) != -1 ? +options.max : 100;
- options.step = options.step && String(options.step).search(stepRegExp) != -1 ? options.step : 1;
- options.precision = options.precision && String(options.precision).search(/^[0-9]+$/) != -1 ? options.precision : (String(options.step).search(/\.([0-9]+)$/) != -1 ? String(options.step).match(/\.([0-9]+)$/)[1].length : 0);
- options.scale = options.scale || false;
- options.forceValue = ("forceValue" in options) ? !!options.forceValue : false;
- options.userSnap = ("userSnap" in options) ? !!options.userSnap : false;
- }
- options.ariaFormat = ("ariaFormat" in options) && typeof options.ariaFormat == "function" ? options.ariaFormat : false;
- options.maxStep = options.maxStep && String(options.maxStep).search(stepRegExp) != -1 ? +options.maxStep : +options.step * 2;
- options.classNames = options.classNames || "";
- options.callbacks = options.callbacks || false;
-
- destroySingleSlider(options.inp.id);
- sliders[options.inp.id] = new fdRange(options);
- return true;
- };
- var getAttribute = function(elem, att) {
- return elem.getAttribute(att) || "";
- };
- // HTML5 input type="range" shim - called onload or onDomReady
- var init = function() {
- var inputs = document.getElementsByTagName("input"),
- options;
-
- for(var i = 0, inp; inp = inputs[i]; i++) {
-
- if(inp.tagName.toLowerCase() == "input" &&
- inp.getAttribute("type").toLowerCase() == "range" &&
- (getAttribute(inp, "min") && getAttribute(inp, "min").search(fpRegExp) != -1 ||
- getAttribute(inp, "max") && getAttribute(inp, "max").search(fpRegExp) != -1 ||
- getAttribute(inp, "step") && getAttribute(inp, "step").search(/^(any|([0-9]+(\.[0-9]+){0,1}))$/i) != -1
- )) {
-
- // Skip elements that have already been created are are resident in the DOM
- if(inp.id && document.getElementById("fd-slider-"+inp.id)) {
- continue;
- // Destroy elements that have already been created but not resident in the DOM
- } else if(inp.id && !document.getElementById("fd-slider-"+inp.id)) {
- destroySingleSlider(inp.id);
- }
-
- // Create an id for the form element if necessary
- if(!inp.id) {
- inp.id = "fd-slider-form-elem-" + uniqueid++;
- }
-
- // Basic option Object
- options = {
- inp: inp,
- callbacks: [],
- animation: html5Animation,
- vertical: getAttribute(inp, "data-fd-slider-vertical") ? true : (inp.offsetHeight > inp.offsetWidth),
- classNames: getAttribute(inp, "data-fd-slider-vertical"),
- html5Shim: true
- };
-
- if(options.vertical && !getAttribute(inp, "data-fd-slider-vertical")) {
- options.inpHeight = inp.offsetHeight;
- }
-
- options.min = getAttribute(inp, "min") || 0;
- options.max = getAttribute(inp, "max") || 100;
- options.step = getAttribute(inp, "step").search(/^any$/i) != -1 ? options.max - options.min : getAttribute(inp, "step").search(stepRegExp) != -1 ? inp.getAttribute("step") : 1;
- options.precision = String(options.step).search(/\.([0-9]+)$/) != -1 ? String(options.step).match(/\.([0-9]+)$/)[1].length : 0;
- options.maxStep = options.step * 2;
-
- destroySingleSlider(options.inp.id);
- sliders[options.inp.id] = new fdRange(options);
- }
- }
-
- return true;
- };
- var destroySingleSlider = function(id) {
- if(id in sliders && sliders.hasOwnProperty(id)) {
- sliders[id].destroy();
- delete sliders[id];
- return true;
- }
- return false;
- };
- var destroyAllsliders = function(e) {
- for(var slider in sliders) {
- if(sliders.hasOwnProperty(slider)) {
- sliders[slider].destroy();
- }
- }
- sliders = [];
- };
- var unload = function(e) {
- destroyAllsliders();
- sliders = null;
- };
- var resize = function(e) {
- for(var slider in sliders) {
- if(sliders.hasOwnProperty(slider)) {
- sliders[slider].onResize();
- }
- }
- };
- var onDomReady = function() {
- removeOnLoadEvent();
- init();
- };
- var removeOnLoadEvent = function() {
- removeEvent(window, "load", init);
- };
- function fdRange(options) {
- var inp = options.inp,
- disabled = false,
- tagName = inp.tagName.toLowerCase(),
- min = +options.min,
- max = +options.max,
- rMin = +options.min,
- rMax = +options.max,
- range = Math.abs(max - min),
- step = tagName == "select" ? 1 : +options.step,
- maxStep = options.maxStep ? +options.maxStep : step * 2,
- precision = options.precision || 0,
- steps = Math.ceil(range / step),
- scale = options.scale || false,
- hideInput = !!options.hideInput,
- animation = options.animation || "",
- vertical = !!options.vertical,
- callbacks = options.callbacks || {},
- classNames = options.classNames || "",
- html5Shim = !!options.html5Shim,
- defaultVal = max < min ? min : min + ((max - min) / 2),
- resetDef = tagName == "select" ? inp.selectedIndex : inp.defaultValue || defaultVal,
- forceValue = html5Shim || !!options.forceValue,
- inpHeight = html5Shim && vertical && ("inpHeight" in options) ? options.inpHeight : false,
- ariaFormat = !html5Shim && options.ariaFormat ? options.ariaFormat : false,
- userSnap = !html5Shim && !(tagName == "select") && ("userSnap" in options) ? !!options.userSnap : false,
- userInput = false,
- timer = null,
- kbEnabled = true,
- initialVal = tagName == "select" ? inp.selectedIndex : inp.value,
- sliderH = 0,
- sliderW = 0,
- tweenX = 0,
- tweenB = 0,
- tweenC = 0,
- tweenD = 0,
- frame = 0,
- x = 0,
- y = 0,
- rMaxPx = 0,
- rMinPx = 0,
- handlePos = 0,
- destPos = 0,
- mousePos = 0,
- stepPx = 0,
- userSet = false,
- touchEvents = false,
- outerWrapper,
- innerWrapper,
- ieBlur,
- handle,
- rangeBar,
- bar;
-
- // For the reset event to work we have to set a defaultValue
- if(tagName == "input" && forceValue && !inp.defaultValue) {
- inp.defaultValue = getWorkingValueFromInput();
- }
-
- // Make sure we have a negative step if the max < min
- if(max < min) {
- step = -Math.abs(step);
- maxStep = -Math.abs(maxStep);
- }
-
- // Add the 100% scale mark if needs be. This is hacky.
- if(scale) {
- scale[100] = max;
- }
-
- // Set the "userSet" variable programmatically for this slider
- function valueSet(tf) {
- tf = !!tf;
- if(tf != userSet) {
- userSet = tf;
- valueToPixels(getWorkingValueFromInput());
- }
- }
-
- function disableSlider(noCallback) {
- if(disabled && !noCallback) {
- return;
- }
-
- try {
- setTabIndex(handle, -1);
- removeEvent(handle, "focus", onFocus);
- removeEvent(handle, "blur", onBlur);
-
- if(!isOpera) {
- removeEvent(handle, "keydown", onKeyDown);
- removeEvent(handle, "keypress", onKeyPress);
- } else {
- removeEvent(handle, "keypress", onKeyDown);
- }
-
- removeEvent(outerWrapper, "mouseover", onMouseOver);
- removeEvent(outerWrapper, "mouseout", onMouseOut);
- removeEvent(outerWrapper, "mousedown", onMouseDown);
- removeEvent(outerWrapper, "touchstart", onMouseDown);
-
- if(mouseWheelEnabled) {
- if (window.addEventListener && !window.devicePixelRatio) window.removeEventListener('DOMMouseScroll', trackMouseWheel, false);
- else {
- removeEvent(document, "mousewheel", trackMouseWheel);
- removeEvent(window, "mousewheel", trackMouseWheel);
- }
- }
- } catch(err) {}
-
- removeClass(innerWrapper, "fd-slider-focused");
- removeClass(innerWrapper, "fd-slider-active");
-
- addClass(innerWrapper, "fd-slider-disabled");
- outerWrapper.setAttribute("aria-disabled", true);
- inp.disabled = disabled = true;
- clearTimeout(timer);
-
- if(!noCallback) {
- callback("disable");
- }
- }
-
- function enableSlider(noCallback) {
- if(!disabled && !noCallback) {
- return;
- }
-
- setTabIndex(handle, 0);
- addEvent(handle, "focus", onFocus);
- addEvent(handle, "blur", onBlur);
-
- if(!isOpera) {
- addEvent(handle, "keydown", onKeyDown);
- addEvent(handle, "keypress", onKeyPress);
- } else {
- addEvent(handle, "keypress", onKeyDown);
- }
-
- addEvent(outerWrapper, "touchstart", onMouseDown);
- addEvent(outerWrapper, "mousedown", onMouseDown);
- addEvent(outerWrapper, "mouseover", onMouseOver);
- addEvent(outerWrapper, "mouseout", onMouseOut);
-
- removeClass(innerWrapper, "fd-slider-disabled");
- outerWrapper.setAttribute("aria-disabled", false);
- inp.disabled = disabled = touchEvents = false;
-
- if(!noCallback) {
- callback("enable");
- }
- }
-
- // Destroys a slider
- function destroySlider() {
- clearTimeout(timer);
- ieBlur = bar = handle = outerWrapper = innerWrapper = timer = null;
- callback("destroy");
- callbacks = null;
- }
-
- // Calculates the pixel increment etc
- function redraw() {
- locate();
- // Internet Explorer requires the try catch as hidden
- // elements throw errors
- try {
- var sW = outerWrapper.offsetWidth,
- sH = outerWrapper.offsetHeight,
- hW = handle.offsetWidth,
- hH = handle.offsetHeight,
- bH = bar.offsetHeight,
- bW = bar.offsetWidth,
- mPx = vertical ? sH - hH : sW - hW;
-
- stepPx = mPx / steps;
- rMinPx = Math.max(scale ? percentToPixels(valueToPercent(rMin)) : Math.abs((rMin - min) / step) * stepPx, 0);
- rMaxPx = Math.min(scale ? percentToPixels(valueToPercent(rMax)) : Math.abs((rMax - min) / step) * stepPx, Math.floor(vertical ? sH - hH : sW - hW));
-
- sliderW = sW;
- sliderH = sH;
-
- valueToPixels(forceValue ? getWorkingValueFromInput() : (tagName == "select" ? inp.selectedIndex : parseFloat(inp.value)), false);
-
- } catch(err) {}
- callback("redraw");
- }
-
- // Calls a callback function
- function callback(type) {
- if(!html5Shim) {
- if(callbacks.hasOwnProperty(type)) {
- var cbObj = {"userSet":userSet, "disabled":disabled, "elem":inp, "value":tagName == "select" ? inp.options[inp.selectedIndex].value : inp.value};
-
- // Call all functions in sequence
- for(var i = 0, func; func = callbacks[type][i]; i++) {
- func.call(inp, cbObj);
- }
- }
- } else if(type.match(/^(blur|focus|change)$/i)) {
- var e;
- if(typeof(document.createEvent) != 'undefined') {
- e = document.createEvent('HTMLEvents');
- e.initEvent(type, true, true);
- inp.dispatchEvent(e);
- } else if(typeof(document.createEventObject) != 'undefined') {
- try {
- e = document.createEventObject();
- inp.fireEvent('on' + type.toLowerCase(), e);
- } catch(err){ }
- }
- }
- }
-
- // FOCUS & BLUR events
- function onFocus(e) {
- addClass(innerWrapper, 'fd-slider-focused');
-
- // Is the value said to have been set by the user onfocus
- if(varSetRules.onfocus) {
- userSet = true;
- valueToPixels(getWorkingValueFromInput());
- }
-
- // If mousewheel events required then add them
- if(mouseWheelEnabled) {
- addEvent(window, 'DOMMouseScroll', trackMouseWheel);
- addEvent(document, 'mousewheel', trackMouseWheel);
- if(!isOpera) {
- addEvent(window, 'mousewheel', trackMouseWheel);
- }
- }
-
- callback("focus");
- return true;
- }
-
- function onBlur(e) {
- removeClass(innerWrapper, 'fd-slider-focused');
-
- // Remove mousewheel events if necessary
- if(mouseWheelEnabled) {
- removeEvent(document, 'mousewheel', trackMouseWheel);
- removeEvent(window, 'DOMMouseScroll', trackMouseWheel);
- if(!isOpera) {
- removeEvent(window, 'mousewheel', trackMouseWheel);
- }
- }
-
- kbEnabled = true;
- callback("blur");
- }
-
- // MOUSEWHEEL events
- function trackMouseWheel(e) {
- if(!kbEnabled) {
- return;
- }
-
- e = e || window.event;
- var delta = 0,
- value;
-
- if (e.wheelDelta) {
- delta = e.wheelDelta/120;
- // Older versions of Opera require a small hack to inverse the delta
- if (isOpera && window.opera.version() < 9.2) {
- delta = -delta;
- }
- } else if(e.detail) {
- delta = -e.detail/3;
- }
-
- if(vertical) {
- delta = -delta;
- }
-
- if(delta) {
- value = getWorkingValueFromInput();
- value += (delta < 0) ? -step : step;
- userSet = true;
- valueToPixels(getValidValue(value));
- }
-
- preventDefault(e);
- }
-
- // KEYBOARD events
- function onKeyPress(e) {
- e = e || window.event;
- // Let all non-hijacked keyboard events pass
- if((e.keyCode >= 33 && e.keyCode <= 40) || !kbEnabled || e.keyCode == 45 || e.keyCode == 46) {
- return stopEvent(e);
- }
- return true;
- }
-
- function onKeyDown(e) {
- if(!kbEnabled) {
- return true;
- }
-
- e = e || window.event;
- var kc = e.keyCode !== null ? e.keyCode : e.charCode,
- value;
-
- if(kc < 33 || (kc > 40 && (kc != 45 && kc != 46))) {
- return true;
- }
-
- value = getWorkingValueFromInput();
-
- if( kc == 37 || kc == 40 || kc == 46 || kc == 34) {
- // left, down, ins, page down
- value -= (e.ctrlKey || kc == 34 ? +maxStep : +step);
- } else if( kc == 39 || kc == 38 || kc == 45 || kc == 33) {
- // right, up, del, page up
- value += (e.ctrlKey || kc == 33 ? +maxStep : +step);
- } else if( kc == 35 ) {
- // max
- value = rMax;
- } else if( kc == 36 ) {
- // min
- value = rMin;
- }
-
- userSet = true;
- valueToPixels(getValidValue(value));
-
- callback("update");
-
- // Opera doesn't let us cancel key events so the up/down arrows and home/end buttons will scroll the screen - which sucks
- preventDefault(e);
- }
-
- // MOUSE & TOUCH events
-
- function onMouseOver(e) {
- addClass(innerWrapper, 'fd-slider-hover');
- }
-
- function onMouseOut(e) {
- // Should really check we are not still in the slider
- removeClass(innerWrapper, 'fd-slider-hover');
- }
-
- // Mousedown on the slider
- function onMouseDown(e) {
- e = e || window.event;
-
- // Stop page scrolling
- preventDefault(e);
-
- // Grab the event target
- var targ;
- if (e.target) {
- targ = e.target;
- } else if (e.srcElement) {
- targ = e.srcElement;
- }
- if(targ && targ.nodeType == 3) {
- targ = targ.parentNode;
- }
-
- // Are we using touchEvents
- if(e.touches) {
- // Skip gestures
- if(e.targetTouches && e.targetTouches.length != 1) {
- return false;
- }
-
- e = e.touches[0];
- touchEvents = true;
- }
-
- // Stop any animation timers
- clearTimeout(timer);
- timer = null;
-
- // Not keyboard enabled
- kbEnabled = false;
-
- // User has set a value
- userSet = true;
-
- // Handle mousedown - initiate drag
- if(targ.className.search("fd-slider-handle") != -1) {
- mousePos = vertical ? e.clientY : e.clientX;
- handlePos = parseInt(vertical ? handle.offsetTop : handle.offsetLeft)||0;
-
- // Set a value on first click even if no movement
- trackMouse(e);
-
- if(!touchEvents) {
- addEvent(document, 'mousemove', trackMouse);
- addEvent(document, 'mouseup', stopDrag);
- } else {
- addEvent(document, 'touchmove', trackMouse);
- addEvent(document, 'touchend', stopDrag);
- // Remove mouseEvents to stop them firing after the touch event
- removeEvent(outerWrapper, "mousedown", onMouseDown);
- }
-
- addClass(innerWrapper, 'fd-slider-active');
- addClass(document.body, "fd-slider-drag-" + (vertical ? "vertical" : "horizontal"));
-
- callback("dragstart");
-
- // Wrapper mousedown - initiate animation to click point
- } else {
- locate();
-
- var posx = 0;
-
- if(e.pageX || e.pageY) {
- posx = vertical ? e.pageY : e.pageX;
- } else if (e.clientX || e.clientY) {
- posx = vertical ? e.clientY + document.body.scrollTop + document.documentElement.scrollTop : e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
- }
-
- posx -= vertical ? y + Math.round(handle.offsetHeight / 2) : x + Math.round(handle.offsetWidth / 2);
- posx = snapToPxValue(posx);
-
- // Tween animation to click point
- if(animation == "tween") {
- addClass(innerWrapper, 'fd-slider-active');
- tweenTo(posx);
- // Progressive increment to click point
- } else if(animation == "timed") {
- addClass(innerWrapper, 'fd-slider-active');
- addEvent(document, touchEvents ? 'touchend' : 'mouseup', onDocMouseUp);
- destPos = posx;
- onTimer();
- // Immediate jump to click point
- } else {
- pixelsToValue(posx);
- //addEvent(document, touchEvents ? 'touchend' : 'mouseup', onMouseUp);
- }
- }
-
- return false;
- }
-
- // Progressive increment to click point - clear the animation timer and remove the mouseup/touchend event
- function onDocMouseUp( e ) {
- e = e || window.event;
-
- preventDefault(e);
- removeEvent(document, touchEvents ? 'touchend' : 'mouseup', onDocMouseUp);
- removeClass(innerWrapper, "fd-slider-active");
-
- clearTimeout(timer);
- timer = null;
- kbEnabled = true;
-
- return false;
- }
-
- // Mouseup or touchend event on the document to stop drag
- function stopDrag(e) {
- e = e || window.event;
-
- preventDefault(e);
-
- if(touchEvents) {
- removeEvent(document, 'touchmove', trackMouse);
- removeEvent(document, 'touchend', stopDrag);
- } else {
- removeEvent(document, 'mousemove', trackMouse);
- removeEvent(document, 'mouseup', stopDrag);
- }
-
- kbEnabled = true;
- removeClass(document.body, "fd-slider-drag-" + (vertical ? "vertical" : "horizontal"));
- removeClass(innerWrapper, "fd-slider-active");
-
- callback("dragend");
-
- return false;
- }
-
- // Mousemove or touchmove event on the drag handle
- function trackMouse(e) {
- e = e || window.event;
-
- preventDefault(e);
-
- if(e.touches) {
- // Skip gestures
- if(e.targetTouches && e.targetTouches.length != 1) {
- return false;
- }
- e = e.touches[0];
- }
-
- pixelsToValue(snapToPxValue(handlePos + (vertical ? e.clientY - mousePos : e.clientX - mousePos)));
-
- return false;
- }
-
- // Increments the slider by "inc" steps
- function increment(inc) {
- var value = getWorkingValueFromInput();
- userSet = true;
- value += inc * step;
- valueToPixels(getValidValue(value));
- }
-
- // Attempts to locate the on-screen position of the slider
- function locate(){
- var curleft = 0,
- curtop = 0,
- obj = outerWrapper;
-
- // Try catch for IE's benefit
- try {
- do {
- curleft += obj.offsetLeft;
- curtop += obj.offsetTop;
- } while(obj = obj.offsetParent);
- } catch(err) {}
- x = curleft;
- y = curtop;
- }
-
- // Used during the progressive animation to click point
- function onTimer() {
- var xtmp = parseInt(vertical ? handle.offsetTop : handle.offsetLeft, 10);
- xtmp = Math.round((destPos < xtmp) ? Math.max(destPos, Math.floor(xtmp - stepPx)) : Math.min(destPos, Math.ceil(xtmp + stepPx)));
-
- pixelsToValue(snapToPxValue(xtmp));
- if(xtmp != destPos) {
- timer = setTimeout(onTimer, steps > 20 ? 50 : 100);
- } else {
- kbEnabled = true;
- removeClass(innerWrapper, "fd-slider-active");
- callback("finalise");
- }
- }
-
- var tween = function(){
- frame++;
- var c = tweenC,
- d = 20,
- t = frame,
- b = tweenB,
- x = Math.ceil((t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b);
-
- pixelsToValue(t == d ? tweenX : x);
-
- if(t!=d) {
- // Call the "move" callback on each animation increment
- callback("move");
- timer = setTimeout(tween, 20);
- } else {
- clearTimeout(timer);
- timer = null;
- kbEnabled = true;
-
- removeClass(innerWrapper, "fd-slider-focused");
- removeClass(innerWrapper, "fd-slider-active");
-
- // Call the "finalise" callback whenever the animation is complete
- callback("finalise");
- }
- };
-
- function tweenTo(tx){
- kbEnabled = false;
- tweenX = parseInt(tx, 10);
- tweenB = parseInt(vertical ? handle.offsetTop : handle.offsetLeft, 10);
- tweenC = tweenX - tweenB;
- tweenD = 20;
- frame = 0;
-
- if(!timer) {
- timer = setTimeout(tween, 20);
- }
- }
-
- // Returns a value within the range & sets the userSet var
- // i.e. has the user entered a valid value
- function checkValue(value) {
- if(isNaN(value) || value === "" || typeof value == "undefined") {
- userSet = false;
- return defaultVal;
- } else if(value < Math.min(rMin,rMax)) {
- userSet = false;
- return Math.min(rMin,rMax);
- } else if(value > Math.max(rMin,rMax)) {
- userSet = false;
- return Math.max(rMin,rMax);
- }
- userSet = true;
- return value;
- }
-
- // Returns a value within a range - uses the form element value as base
- function getWorkingValueFromInput() {
- return getValidValue(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex);
- }
-
- // Returns a value within the range
- function getValidValue(value) {
- return (isNaN(value) || value === "" || typeof value == "undefined") ? defaultVal : Math.min(Math.max(value, Math.min(rMin,rMax)), Math.max(rMin,rMax));
- }
-
- // Calculates value according to pixel position of slider handle
- function pixelsToValue(px) {
- var val = getValidValue(scale ? percentToValue(pixelsToPercent(px)) : vertical ? max - (Math.round(px / stepPx) * step) : min + (Math.round(px / stepPx) * step));
-
- handle.style[vertical ? "top" : "left"] = (px || 0) + "px";
- redrawRange();
- setInputValue((tagName == "select" || step == 1) ? Math.round(val) : val);
- }
-
- // Calculates pixel position according to form element value
- function valueToPixels(val, updateInputValue) {
- var clearVal = false,
- value;
-
- // Allow empty values for non-polyfill sliders
- if((typeof val === "undefined" || isNaN(val) || val === "") && tagName == "input" && !forceValue) {
- value = defaultVal;
- clearVal = true;
- userSet = false;
- } else {
- value = checkValue(val);
- }
-
- handle.style[vertical ? "top" : "left"] = (scale ? percentToPixels(valueToPercent(value)) : vertical ? Math.round(((max - value) / step) * stepPx) : Math.round(((value - min) / step) * stepPx)) + "px";
- redrawRange();
- if(typeof updateInputValue !== false) {
- setInputValue(clearVal ? "" : value);
- }
- }
-
- // Rounds a pixel value to the nearest "snap" point on the slider scale
- function snapToPxValue(px) {
- if(scale) {
- return Math.max(Math.min(rMaxPx, px), rMinPx);
- } else {
- var rem = px % stepPx;
- if(rem && rem >= (stepPx / 2)) {
- px += (stepPx - rem);
- } else {
- px -= rem;
- }
-
- if(px < Math.min(Math.abs(rMinPx), Math.abs(rMaxPx))) {
- px = Math.min(Math.abs(rMinPx), Math.abs(rMaxPx));
- } else if(px > Math.max(Math.abs(rMinPx), Math.abs(rMaxPx))) {
- px = Math.max(Math.abs(rMinPx), Math.abs(rMaxPx));
- }
-
- return Math.min(Math.max(px, 0), rMaxPx);
- }
- }
-
- // Calculates a value according to percentage of distance handle has travelled
- function percentToValue(pct) {
- var st = 0,
- fr = min,
- value;
-
- for(var s in scale) {
- if(!scale.hasOwnProperty(s)) {
- continue;
- }
-
- if(pct >= st && pct <= +s ) {
- value = fr + ((pct - st) * (+scale[s] - fr) ) / (+s - st);
- }
-
- st = +s;
- fr = +scale[s];
- }
-
- return value;
- }
-
- // Calculates the percentage handle position according to form element value
- function valueToPercent(value) {
- var st = 0,
- fr = min,
- pct = 0;
-
- for(var s in scale) {
- if(!scale.hasOwnProperty(s)) {
- continue;
- }
-
- if(value >= fr && value <= +scale[s]){
- pct = st + (value - fr) * (+s - st) / (+scale[s] - fr);
- }
-
- st = +s;
- fr = +scale[s];
- }
-
- return pct;
- }
-
- function percentToPixels(percent) {
- return ((outerWrapper[vertical ? "offsetHeight" : "offsetWidth"] - handle[vertical ? "offsetHeight" : "offsetWidth"]) / 100) * percent;
- }
-
- function pixelsToPercent(pixels) {
- return pixels / ((outerWrapper[vertical ? "offsetHeight" : "offsetWidth"] - outerWrapper[handle ? "offsetHeight" : "offsetWidth"]) / 100);
- }
-
- // Sets the form element with a valid value
- function setInputValue(val) {
- // The update callback doesn't mean the input value has changed
- callback("update");
-
- // If the user has not set this value or has entered an incorrect value then set a class
- // to enable styling of the slider
- if(!userSet) {
- addClass(innerWrapper, "fd-slider-no-value");
- } else {
- removeClass(innerWrapper, "fd-slider-no-value");
- }
-
- if(tagName == "select") {
- try {
- val = parseInt(val, 10);
- if(inp.selectedIndex === val) {
- updateAriaValues();
- return;
- }
- inp.options[val].selected = true;
- } catch (err) {}
- } else {
- if(val !== "" && !userInput) {
- val = (min + (Math.round((val - min) / step) * step)).toFixed(precision);
- }
- if(inp.value === val) {
- updateAriaValues();
- return;
- }
- inp.value = val;
- }
-
- updateAriaValues();
- callback("change");
- }
-
- function checkInputValue(value) {
- return !(isNaN(value) || value === "" || value < Math.min(rMin,rMax) || value > Math.max(rMin,rMax));
- }
-
- function setSliderRange(newMin, newMax) {
- if(rMin > rMax) {
- newMin = Math.min(min, Math.max(newMin, newMax));
- newMax = Math.max(max, Math.min(newMin, newMax));
- rMin = Math.max(newMin, newMax);
- rMax = Math.min(newMin, newMax);
- } else {
- newMin = Math.max(min, Math.min(newMin, newMax));
- newMax = Math.min(max, Math.max(newMin, newMax));
- rMin = Math.min(newMin, newMax);
- rMax = Math.max(newMin, newMax);
- }
-
- if(defaultVal < Math.min(rMin, rMax)) {
- defaultVal = Math.min(rMin, rMax);
- } else if(defaultVal > Math.max(rMin, rMax)) {
- defaultVal = Math.max(rMin, rMax);
- }
-
- handle.setAttribute("aria-valuemin", rMin);
- handle.setAttribute("aria-valuemax", rMax);
-
- checkValue(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex);
- redraw();
- }
-
- function redrawRange() {
- if(noRangeBar) {
- return;
- }
- if(vertical) {
- rangeBar.style["height"] = Math.max(1, (bar.offsetHeight - handle.offsetTop)) + "px";
- } else {
- rangeBar.style["width"] = Math.max(1, handle.offsetLeft) + "px";
- }
- }
-
- function findLabel() {
- var label = false,
- labelList = document.getElementsByTagName('label');
- // loop through label array attempting to match each 'for' attribute to the id of the current element
- for(var i = 0, lbl; lbl = labelList[i]; i++) {
- // Internet Explorer requires the htmlFor test
- if((lbl['htmlFor'] && lbl['htmlFor'] == inp.id) || (lbl.getAttribute('for') == inp.id)) {
- label = lbl;
- break;
- }
- }
-
- if(label && !label.id) {
- label.id = inp.id + "_label";
- }
-
- return label;
- }
-
- function updateAriaValues() {
- var val = tagName == "select" ? inp.options[inp.selectedIndex].value : inp.value,
- valTxt = ariaFormat ? ariaFormat(val) : tagName == "select" ? (inp.options[inp.selectedIndex].text ? inp.options[inp.selectedIndex].text : val) : val;
-
- handle.setAttribute("aria-valuenow", val);
- handle.setAttribute("aria-valuetext", valTxt);
- }
-
- function onInputChange(e) {
- userSet = true;
- userInput = userSnap;
- valueToPixels(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex);
- updateAriaValues();
- userInput = false;
- }
-
- function onInputAttributesChange(e){
- step = parseFloat(getAttribute(inp, "step"));
- min = parseFloat(getAttribute(inp, "min"));
- max = parseFloat(getAttribute(inp, "max"));
-
- rMin = parseFloat(getAttribute(inp, "min"));
- rMax = parseFloat(getAttribute(inp, "max"));
-
- range = Math.abs(max - min);
- steps = Math.ceil( range / step);
-
- redraw();
- }
-
- function onReset(e) {
- if(tagName == "input") {
- inp.value = inp.defaultValue;
- } else {
- inp.selectedIndex = resetDef;
- }
- checkValue(tagName == "select" ? inp.options[inp.selectedIndex].value : inp.value);
- redraw();
- updateAriaValues();
- }
-
- function valueSet(tf) {
- userSet = !!tf;
- }
-
- // Sets a tabindex attribute on an element, bends over for IE.
- function setTabIndex(e, i) {
- e.setAttribute(!/*@cc_on!@*/false ? "tabIndex" : "tabindex", i);
- e.tabIndex = i;
- }
-
- (function() {
- if(html5Shim || hideInput) {
- addClass(inp, "fd-form-element-hidden");
- } else {
- addEvent(inp, 'change', onInputChange);
- }
-
- addEvent(inp, "DOMAttrModified", onInputAttributesChange);
-
- // Add stepUp & stepDown methods to input element if using the html5Shim
- if(html5Shim) {
- inp.stepUp = function(n) { increment(n||1); };
- inp.stepDown = function(n) { increment(n||-1); };
- }
-
- outerWrapper = document.createElement('span');
- outerWrapper.className = "fd-slider" + (vertical ? "-vertical " : " ") + classNames;
- outerWrapper.id = "fd-slider-" + inp.id;
-
- if(vertical && inpHeight) {
- outerWrapper.style.height = inpHeight + "px";
- }
-
- innerWrapper = document.createElement('span');
- innerWrapper.className = "fd-slider-wrapper" + (!html5Shim ? " fd-slider-no-value" : "");
-
- ieBlur = document.createElement('span');
- ieBlur.className = "fd-slider-inner";
-
- bar = document.createElement('span');
- bar.className = "fd-slider-bar";
-
- if(fullARIA) {
- handle = document.createElement('span');
- } else {
- handle = document.createElement('a');
- handle.setAttribute("href", "#");
- addEvent(handle, "click", stopEvent);
- }
-
- setTabIndex(handle, 0);
-
- handle.className = "fd-slider-handle";
- handle.appendChild(document.createTextNode(String.fromCharCode(160)));
-
- innerWrapper.appendChild(ieBlur);
-
- if(!noRangeBar) {
- rangeBar = document.createElement('span');
- rangeBar.className = "fd-slider-range";
- innerWrapper.appendChild(rangeBar);
- }
-
- innerWrapper.appendChild(bar);
- innerWrapper.appendChild(handle);
- outerWrapper.appendChild(innerWrapper);
-
- inp.parentNode.insertBefore(outerWrapper, inp);
-
- if(isOpera || /*@cc_on!@*/!true) {
- handle.unselectable = "on";
- bar.unselectable = "on";
- ieBlur.unselectable = "on";
- outerWrapper.unselectable = "on";
- innerWrapper.unselectable = "on";
- if(!noRangeBar) {
- rangeBar.unselectable = "on";
- }
- }
-
- // Add ARIA accessibility info programmatically
- outerWrapper.setAttribute("role", "application");
-
- handle.setAttribute("role", "slider");
- handle.setAttribute("aria-valuemin", tagName == "select" ? inp.options[0].value : min);
- handle.setAttribute("aria-valuemax", tagName == "select" ? inp.options[inp.options.length - 1].value : max);
-
- var lbl = findLabel();
- if(lbl) {
- handle.setAttribute("aria-labelledby", lbl.id);
- handle.id = "fd-slider-handle-" + inp.id;
- /*@cc_on@*/
- /*@if(@_win32)
- lbl.setAttribute("htmlFor", handle.id);
- @else @*/
- lbl.setAttribute("for", handle.id);
- /*@end@*/
- }
-
- // Are there page instructions
- if(document.getElementById(describedBy)) {
- handle.setAttribute("aria-describedby", describedBy);
- }
-
- // Is the form element initially disabled
- if(inp.getAttribute("disabled") == true || inp.getAttribute("disabled") == "disabled") {
- disableSlider(true);
- } else {
- enableSlider(true);
- }
-
- // Does an initial form element value mean the user has set a valid value?
- // Also called onload in case browsers have automatically set the input value
- if(varSetRules.onvalue) {
- userSet = true;
- checkValue(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex);
- }
-
- // Catch form reset events
- if(inp.form) {
- addEvent(inp.form, "reset", onReset);
- }
-
- updateAriaValues();
- callback("create");
- redraw();
- })();
-
- return {
- onResize: function(e) { if(outerWrapper.offsetHeight != sliderH || outerWrapper.offsetWidth != sliderW) { redraw(); } },
- destroy: function() { destroySlider(); },
- reset: function() { valueToPixels(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); },
- stepUp: function(n) { increment(Math.abs(n)||1); },
- stepDown: function(n) { increment(-Math.abs(n)||-1); },
- increment: function(n) { increment(n); },
- disable: function() { disableSlider(); },
- enable: function() { enableSlider(); },
- setRange: function(mi, mx) { setSliderRange(mi, mx); },
- getValueSet: function() { return !!userSet; },
- setValueSet: function(tf) { valueSet(tf); },
- checkValue: function() { if(varSetRules.onvalue) { userSet = true; checkValue(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); } updateAriaValues(); redraw(); }
- };
- }
-
- addEvent(window, "load", init);
- addEvent(window, "load", function() { setTimeout(function() { var slider; for(slider in sliders) { sliders[slider].checkValue(); } }, 0); });
- addEvent(window, "resize", resize);
- addEvent(window, "unload", unload);
-
- // Have we been passed JSON within the including script tag
- (function() {
- var scriptFiles = document.getElementsByTagName('script'),
- scriptInner = String(scriptFiles[scriptFiles.length - 1].innerHTML).replace(/[\n\r\s\t]+/g, " ").replace(/^\s+/, "").replace(/\s+$/, ""),
- json = parseJSON(scriptInner);
-
- if(typeof json === "object" && !("err" in json)) {
- affectJSON(json);
- }
- })();
-
- // Add oldie class if needed for IE < 9
- /*@cc_on@*/
- /*@if (@_jscript_version < 9)
- addClass(document.documentElement, "oldie");
- /*@end@*/
-
- return {
- rescanDocument: init,
- createSlider: function(opts) { return createSlider(opts); },
- onDomReady: function() { onDomReady(); },
- destroyAll: function() { destroyAllsliders(); },
- destroySlider: function(id) { return destroySingleSlider(id); },
- redrawAll: function() { resize(); },
- addEvent: addEvent,
- removeEvent: removeEvent,
- stopEvent: stopEvent,
- increment: function(id, numSteps) { if(!sliderExists(id)) { return false; } sliders[id].increment(numSteps); },
- stepUp: function(id, n) { if(!sliderExists(id)) { return false; } sliders[id].stepUp(Math.abs(n)||1); },
- stepDown: function(id, n) { if(!sliderExists(id)) { return false; } sliders[id].stepDown(-Math.abs(n)||-1); },
- setRange: function(id, newMin, newMax) { if(!sliderExists(id)) { return false; } sliders[id].setRange(newMin, newMax); },
- updateSlider: function(id) { if(!sliderExists(id)) { return false; } sliders[id].onResize(); sliders[id].reset(); },
- disable: function(id) { if(!sliderExists(id)) { return false; } sliders[id].disable(); },
- enable: function(id) { if(!sliderExists(id)) { return false; } sliders[id].enable(); },
- getValueSet: function() { return getValueSet(); },
- setValueSet: function(a, tf) { if(!sliderExists(id)) { return false; } setValueSet(a, tf); },
- setGlobalVariables: function(json) { affectJSON(json); },
- removeOnload: function() { removeOnLoadEvent(); }
- };
-})();
diff --git a/app/assets/javascripts/wdl-viewer/jquery-deparam.js b/app/assets/javascripts/wdl-viewer/jquery-deparam.js
deleted file mode 100644
index 7984e338..00000000
--- a/app/assets/javascripts/wdl-viewer/jquery-deparam.js
+++ /dev/null
@@ -1,113 +0,0 @@
-// https://github.com/AceMetrix/jquery-deparam
-(function(deparam){
- if (typeof require === 'function' && typeof exports === 'object' && typeof module === 'object') {
- var jquery = require('jquery');
- module.exports = deparam(jquery);
- } else if (typeof define === 'function' && define.amd){
- define(['jquery'], function(jquery){
- return deparam(jquery);
- });
- } else {
- var global
- try {
- global = (false || eval)('this'); // best cross-browser way to determine global for < ES5
- } catch (e) {
- global = window; // fails only if browser (https://developer.mozilla.org/en-US/docs/Web/Security/CSP/CSP_policy_directives)
- }
- global.deparam = deparam(jQuery); // assume jQuery is in global namespace
- }
-})(function ($) {
- var deparam = function( params, coerce ) {
- var obj = {},
- coerce_types = { 'true': !0, 'false': !1, 'null': null };
-
- // Iterate over all name=value pairs.
- params.replace(/\+/g, ' ').split('&').forEach(function(v){
- var param = v.split( '=' ),
- key = decodeURIComponent( param[0] ),
- val,
- cur = obj,
- i = 0,
-
- // If key is more complex than 'foo', like 'a[]' or 'a[b][c]', split it
- // into its component parts.
- keys = key.split( '][' ),
- keys_last = keys.length - 1;
-
- // If the first keys part contains [ and the last ends with ], then []
- // are correctly balanced.
- if ( /\[/.test( keys[0] ) && /\]$/.test( keys[ keys_last ] ) ) {
- // Remove the trailing ] from the last keys part.
- keys[ keys_last ] = keys[ keys_last ].replace( /\]$/, '' );
-
- // Split first keys part into two parts on the [ and add them back onto
- // the beginning of the keys array.
- keys = keys.shift().split('[').concat( keys );
-
- keys_last = keys.length - 1;
- } else {
- // Basic 'foo' style key.
- keys_last = 0;
- }
-
- // Are we dealing with a name=value pair, or just a name?
- if ( param.length === 2 ) {
- val = decodeURIComponent( param[1] );
-
- // Coerce values.
- if ( coerce ) {
- val = val && !isNaN(val) && ((+val + '') === val) ? +val // number
- : val === 'undefined' ? undefined // undefined
- : coerce_types[val] !== undefined ? coerce_types[val] // true, false, null
- : val; // string
- }
-
- if ( keys_last ) {
- // Complex key, build deep object structure based on a few rules:
- // * The 'cur' pointer starts at the object top-level.
- // * [] = array push (n is set to array length), [n] = array if n is
- // numeric, otherwise object.
- // * If at the last keys part, set the value.
- // * For each keys part, if the current level is undefined create an
- // object or array based on the type of the next keys part.
- // * Move the 'cur' pointer to the next level.
- // * Rinse & repeat.
- for ( ; i <= keys_last; i++ ) {
- key = keys[i] === '' ? cur.length : keys[i];
- cur = cur[key] = i < keys_last
- ? cur[key] || ( keys[i+1] && isNaN( keys[i+1] ) ? {} : [] )
- : val;
- }
-
- } else {
- // Simple key, even simpler rules, since only scalars and shallow
- // arrays are allowed.
-
- if ( Object.prototype.toString.call( obj[key] ) === '[object Array]' ) {
- // val is already an array, so push on the next value.
- obj[key].push( val );
-
- } else if ( {}.hasOwnProperty.call(obj, key) ) {
- // val isn't an array, but since a second value has been specified,
- // convert val into an array.
- obj[key] = [ obj[key], val ];
-
- } else {
- // val is a scalar.
- obj[key] = val;
- }
- }
-
- } else if ( key ) {
- // No value was defined, so set something meaningful.
- obj[key] = coerce
- ? undefined
- : '';
- }
- });
-
- return obj;
- };
- $.prototype.deparam = $.deparam = deparam;
- return deparam;
-});
diff --git a/app/assets/javascripts/wdl-viewer/jquery.ba-throttle-debounce.min.js b/app/assets/javascripts/wdl-viewer/jquery.ba-throttle-debounce.min.js
deleted file mode 100644
index 07205508..00000000
--- a/app/assets/javascripts/wdl-viewer/jquery.ba-throttle-debounce.min.js
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * jQuery throttle / debounce - v1.1 - 3/7/2010
- * http://benalman.com/projects/jquery-throttle-debounce-plugin/
- *
- * Copyright (c) 2010 "Cowboy" Ben Alman
- * Dual licensed under the MIT and GPL licenses.
- * http://benalman.com/about/license/
- */
-(function(b,c){var $=b.jQuery||b.Cowboy||(b.Cowboy={}),a;$.throttle=a=function(e,f,j,i){var h,d=0;if(typeof f!=="boolean"){i=j;j=f;f=c}function g(){var o=this,m=+new Date()-d,n=arguments;function l(){d=+new Date();j.apply(o,n)}function k(){h=c}if(i&&!h){l()}h&&clearTimeout(h);if(i===c&&m>e){l()}else{if(f!==true){h=setTimeout(i?k:l,i===c?e-m:e)}}}if($.guid){g.guid=j.guid=j.guid||$.guid++}return g};$.debounce=function(d,e,f){return f===c?a(d,e,false):a(d,f,e!==false)}})(this);
\ No newline at end of file
diff --git a/app/assets/javascripts/wdl-viewer/jquery.hammer.min.js b/app/assets/javascripts/wdl-viewer/jquery.hammer.min.js
deleted file mode 100644
index 87404179..00000000
--- a/app/assets/javascripts/wdl-viewer/jquery.hammer.min.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/*! Hammer.JS - v1.0.5 - 2013-04-07
- * http://eightmedia.github.com/hammer.js
- *
- * Copyright (c) 2013 Jorik Tangelder ;
- * Licensed under the MIT license */
-
-(function(t,e){"use strict";function n(){if(!i.READY){i.event.determineEventTypes();for(var t in i.gestures)i.gestures.hasOwnProperty(t)&&i.detection.register(i.gestures[t]);i.event.onTouch(i.DOCUMENT,i.EVENT_MOVE,i.detection.detect),i.event.onTouch(i.DOCUMENT,i.EVENT_END,i.detection.detect),i.READY=!0}}var i=function(t,e){return new i.Instance(t,e||{})};i.defaults={stop_browser_behavior:{userSelect:"none",touchAction:"none",touchCallout:"none",contentZooming:"none",userDrag:"none",tapHighlightColor:"rgba(0,0,0,0)"}},i.HAS_POINTEREVENTS=navigator.pointerEnabled||navigator.msPointerEnabled,i.HAS_TOUCHEVENTS="ontouchstart"in t,i.MOBILE_REGEX=/mobile|tablet|ip(ad|hone|od)|android/i,i.NO_MOUSEEVENTS=i.HAS_TOUCHEVENTS&&navigator.userAgent.match(i.MOBILE_REGEX),i.EVENT_TYPES={},i.DIRECTION_DOWN="down",i.DIRECTION_LEFT="left",i.DIRECTION_UP="up",i.DIRECTION_RIGHT="right",i.POINTER_MOUSE="mouse",i.POINTER_TOUCH="touch",i.POINTER_PEN="pen",i.EVENT_START="start",i.EVENT_MOVE="move",i.EVENT_END="end",i.DOCUMENT=document,i.plugins={},i.READY=!1,i.Instance=function(t,e){var r=this;return n(),this.element=t,this.enabled=!0,this.options=i.utils.extend(i.utils.extend({},i.defaults),e||{}),this.options.stop_browser_behavior&&i.utils.stopDefaultBrowserBehavior(this.element,this.options.stop_browser_behavior),i.event.onTouch(t,i.EVENT_START,function(t){r.enabled&&i.detection.startDetect(r,t)}),this},i.Instance.prototype={on:function(t,e){for(var n=t.split(" "),i=0;n.length>i;i++)this.element.addEventListener(n[i],e,!1);return this},off:function(t,e){for(var n=t.split(" "),i=0;n.length>i;i++)this.element.removeEventListener(n[i],e,!1);return this},trigger:function(t,e){var n=i.DOCUMENT.createEvent("Event");n.initEvent(t,!0,!0),n.gesture=e;var r=this.element;return i.utils.hasParent(e.target,r)&&(r=e.target),r.dispatchEvent(n),this},enable:function(t){return this.enabled=t,this}};var r=null,o=!1,s=!1;i.event={bindDom:function(t,e,n){for(var i=e.split(" "),r=0;i.length>r;r++)t.addEventListener(i[r],n,!1)},onTouch:function(t,e,n){var a=this;this.bindDom(t,i.EVENT_TYPES[e],function(c){var u=c.type.toLowerCase();if(!u.match(/mouse/)||!s){(u.match(/touch/)||u.match(/pointerdown/)||u.match(/mouse/)&&1===c.which)&&(o=!0),u.match(/touch|pointer/)&&(s=!0);var h=0;o&&(i.HAS_POINTEREVENTS&&e!=i.EVENT_END?h=i.PointerEvent.updatePointer(e,c):u.match(/touch/)?h=c.touches.length:s||(h=u.match(/up/)?0:1),h>0&&e==i.EVENT_END?e=i.EVENT_MOVE:h||(e=i.EVENT_END),h||null===r?r=c:c=r,n.call(i.detection,a.collectEventData(t,e,c)),i.HAS_POINTEREVENTS&&e==i.EVENT_END&&(h=i.PointerEvent.updatePointer(e,c))),h||(r=null,o=!1,s=!1,i.PointerEvent.reset())}})},determineEventTypes:function(){var t;t=i.HAS_POINTEREVENTS?i.PointerEvent.getEvents():i.NO_MOUSEEVENTS?["touchstart","touchmove","touchend touchcancel"]:["touchstart mousedown","touchmove mousemove","touchend touchcancel mouseup"],i.EVENT_TYPES[i.EVENT_START]=t[0],i.EVENT_TYPES[i.EVENT_MOVE]=t[1],i.EVENT_TYPES[i.EVENT_END]=t[2]},getTouchList:function(t){return i.HAS_POINTEREVENTS?i.PointerEvent.getTouchList():t.touches?t.touches:[{identifier:1,pageX:t.pageX,pageY:t.pageY,target:t.target}]},collectEventData:function(t,e,n){var r=this.getTouchList(n,e),o=i.POINTER_TOUCH;return(n.type.match(/mouse/)||i.PointerEvent.matchType(i.POINTER_MOUSE,n))&&(o=i.POINTER_MOUSE),{center:i.utils.getCenter(r),timeStamp:(new Date).getTime(),target:n.target,touches:r,eventType:e,pointerType:o,srcEvent:n,preventDefault:function(){this.srcEvent.preventManipulation&&this.srcEvent.preventManipulation(),this.srcEvent.preventDefault&&this.srcEvent.preventDefault()},stopPropagation:function(){this.srcEvent.stopPropagation()},stopDetect:function(){return i.detection.stopDetect()}}}},i.PointerEvent={pointers:{},getTouchList:function(){var t=this,e=[];return Object.keys(t.pointers).sort().forEach(function(n){e.push(t.pointers[n])}),e},updatePointer:function(t,e){return t==i.EVENT_END?this.pointers={}:(e.identifier=e.pointerId,this.pointers[e.pointerId]=e),Object.keys(this.pointers).length},matchType:function(t,e){if(!e.pointerType)return!1;var n={};return n[i.POINTER_MOUSE]=e.pointerType==e.MSPOINTER_TYPE_MOUSE||e.pointerType==i.POINTER_MOUSE,n[i.POINTER_TOUCH]=e.pointerType==e.MSPOINTER_TYPE_TOUCH||e.pointerType==i.POINTER_TOUCH,n[i.POINTER_PEN]=e.pointerType==e.MSPOINTER_TYPE_PEN||e.pointerType==i.POINTER_PEN,n[t]},getEvents:function(){return["pointerdown MSPointerDown","pointermove MSPointerMove","pointerup pointercancel MSPointerUp MSPointerCancel"]},reset:function(){this.pointers={}}},i.utils={extend:function(t,n,i){for(var r in n)t[r]!==e&&i||(t[r]=n[r]);return t},hasParent:function(t,e){for(;t;){if(t==e)return!0;t=t.parentNode}return!1},getCenter:function(t){for(var e=[],n=[],i=0,r=t.length;r>i;i++)e.push(t[i].pageX),n.push(t[i].pageY);return{pageX:(Math.min.apply(Math,e)+Math.max.apply(Math,e))/2,pageY:(Math.min.apply(Math,n)+Math.max.apply(Math,n))/2}},getVelocity:function(t,e,n){return{x:Math.abs(e/t)||0,y:Math.abs(n/t)||0}},getAngle:function(t,e){var n=e.pageY-t.pageY,i=e.pageX-t.pageX;return 180*Math.atan2(n,i)/Math.PI},getDirection:function(t,e){var n=Math.abs(t.pageX-e.pageX),r=Math.abs(t.pageY-e.pageY);return n>=r?t.pageX-e.pageX>0?i.DIRECTION_LEFT:i.DIRECTION_RIGHT:t.pageY-e.pageY>0?i.DIRECTION_UP:i.DIRECTION_DOWN},getDistance:function(t,e){var n=e.pageX-t.pageX,i=e.pageY-t.pageY;return Math.sqrt(n*n+i*i)},getScale:function(t,e){return t.length>=2&&e.length>=2?this.getDistance(e[0],e[1])/this.getDistance(t[0],t[1]):1},getRotation:function(t,e){return t.length>=2&&e.length>=2?this.getAngle(e[1],e[0])-this.getAngle(t[1],t[0]):0},isVertical:function(t){return t==i.DIRECTION_UP||t==i.DIRECTION_DOWN},stopDefaultBrowserBehavior:function(t,e){var n,i=["webkit","khtml","moz","ms","o",""];if(e&&t.style){for(var r=0;i.length>r;r++)for(var o in e)e.hasOwnProperty(o)&&(n=o,i[r]&&(n=i[r]+n.substring(0,1).toUpperCase()+n.substring(1)),t.style[n]=e[o]);"none"==e.userSelect&&(t.onselectstart=function(){return!1})}}},i.detection={gestures:[],current:null,previous:null,stopped:!1,startDetect:function(t,e){this.current||(this.stopped=!1,this.current={inst:t,startEvent:i.utils.extend({},e),lastEvent:!1,name:""},this.detect(e))},detect:function(t){if(this.current&&!this.stopped){t=this.extendEventData(t);for(var e=this.current.inst.options,n=0,r=this.gestures.length;r>n;n++){var o=this.gestures[n];if(!this.stopped&&e[o.name]!==!1&&o.handler.call(o,t,this.current.inst)===!1){this.stopDetect();break}}return this.current&&(this.current.lastEvent=t),t.eventType==i.EVENT_END&&!t.touches.length-1&&this.stopDetect(),t}},stopDetect:function(){this.previous=i.utils.extend({},this.current),this.current=null,this.stopped=!0},extendEventData:function(t){var e=this.current.startEvent;if(e&&(t.touches.length!=e.touches.length||t.touches===e.touches)){e.touches=[];for(var n=0,r=t.touches.length;r>n;n++)e.touches.push(i.utils.extend({},t.touches[n]))}var o=t.timeStamp-e.timeStamp,s=t.center.pageX-e.center.pageX,a=t.center.pageY-e.center.pageY,c=i.utils.getVelocity(o,s,a);return i.utils.extend(t,{deltaTime:o,deltaX:s,deltaY:a,velocityX:c.x,velocityY:c.y,distance:i.utils.getDistance(e.center,t.center),angle:i.utils.getAngle(e.center,t.center),direction:i.utils.getDirection(e.center,t.center),scale:i.utils.getScale(e.touches,t.touches),rotation:i.utils.getRotation(e.touches,t.touches),startEvent:e}),t},register:function(t){var n=t.defaults||{};return n[t.name]===e&&(n[t.name]=!0),i.utils.extend(i.defaults,n,!0),t.index=t.index||1e3,this.gestures.push(t),this.gestures.sort(function(t,e){return t.indexe.index?1:0}),this.gestures}},i.gestures=i.gestures||{},i.gestures.Hold={name:"hold",index:10,defaults:{hold_timeout:500,hold_threshold:1},timer:null,handler:function(t,e){switch(t.eventType){case i.EVENT_START:clearTimeout(this.timer),i.detection.current.name=this.name,this.timer=setTimeout(function(){"hold"==i.detection.current.name&&e.trigger("hold",t)},e.options.hold_timeout);break;case i.EVENT_MOVE:t.distance>e.options.hold_threshold&&clearTimeout(this.timer);break;case i.EVENT_END:clearTimeout(this.timer)}}},i.gestures.Tap={name:"tap",index:100,defaults:{tap_max_touchtime:250,tap_max_distance:10,tap_always:!0,doubletap_distance:20,doubletap_interval:300},handler:function(t,e){if(t.eventType==i.EVENT_END){var n=i.detection.previous,r=!1;if(t.deltaTime>e.options.tap_max_touchtime||t.distance>e.options.tap_max_distance)return;n&&"tap"==n.name&&t.timeStamp-n.lastEvent.timeStamp0&&t.touches.length>e.options.swipe_max_touches)return;(t.velocityX>e.options.swipe_velocity||t.velocityY>e.options.swipe_velocity)&&(e.trigger(this.name,t),e.trigger(this.name+t.direction,t))}}},i.gestures.Drag={name:"drag",index:50,defaults:{drag_min_distance:10,drag_max_touches:1,drag_block_horizontal:!1,drag_block_vertical:!1,drag_lock_to_axis:!1,drag_lock_min_distance:25},triggered:!1,handler:function(t,n){if(i.detection.current.name!=this.name&&this.triggered)return n.trigger(this.name+"end",t),this.triggered=!1,e;if(!(n.options.drag_max_touches>0&&t.touches.length>n.options.drag_max_touches))switch(t.eventType){case i.EVENT_START:this.triggered=!1;break;case i.EVENT_MOVE:if(t.distancet.deltaY?i.DIRECTION_UP:i.DIRECTION_DOWN:0>t.deltaX?i.DIRECTION_LEFT:i.DIRECTION_RIGHT),this.triggered||(n.trigger(this.name+"start",t),this.triggered=!0),n.trigger(this.name,t),n.trigger(this.name+t.direction,t),(n.options.drag_block_vertical&&i.utils.isVertical(t.direction)||n.options.drag_block_horizontal&&!i.utils.isVertical(t.direction))&&t.preventDefault();break;case i.EVENT_END:this.triggered&&n.trigger(this.name+"end",t),this.triggered=!1}}},i.gestures.Transform={name:"transform",index:45,defaults:{transform_min_scale:.01,transform_min_rotation:1,transform_always_block:!1},triggered:!1,handler:function(t,n){if(i.detection.current.name!=this.name&&this.triggered)return n.trigger(this.name+"end",t),this.triggered=!1,e;if(!(2>t.touches.length))switch(n.options.transform_always_block&&t.preventDefault(),t.eventType){case i.EVENT_START:this.triggered=!1;break;case i.EVENT_MOVE:var r=Math.abs(1-t.scale),o=Math.abs(t.rotation);if(n.options.transform_min_scale>r&&n.options.transform_min_rotation>o)return;i.detection.current.name=this.name,this.triggered||(n.trigger(this.name+"start",t),this.triggered=!0),n.trigger(this.name,t),o>n.options.transform_min_rotation&&n.trigger("rotate",t),r>n.options.transform_min_scale&&(n.trigger("pinch",t),n.trigger("pinch"+(1>t.scale?"in":"out"),t));break;case i.EVENT_END:this.triggered&&n.trigger(this.name+"end",t),this.triggered=!1}}},i.gestures.Touch={name:"touch",index:-1/0,defaults:{prevent_default:!1,prevent_mouseevents:!1},handler:function(t,n){return n.options.prevent_mouseevents&&t.pointerType==i.POINTER_MOUSE?(t.stopDetect(),e):(n.options.prevent_default&&t.preventDefault(),t.eventType==i.EVENT_START&&n.trigger(this.name,t),e)}},i.gestures.Release={name:"release",index:1/0,handler:function(t,e){t.eventType==i.EVENT_END&&e.trigger(this.name,t)}},"object"==typeof module&&"object"==typeof module.exports?module.exports=i:(t.Hammer=i,"function"==typeof t.define&&t.define.amd&&t.define("hammer",[],function(){return i}))})(this),function(t,e){"use strict";t!==e&&(Hammer.event.bindDom=function(n,i,r){t(n).on(i,function(t){var n=t.originalEvent||t;n.pageX===e&&(n.pageX=t.pageX,n.pageY=t.pageY),n.target||(n.target=t.target),n.which===e&&(n.which=n.button),n.preventDefault||(n.preventDefault=t.preventDefault),n.stopPropagation||(n.stopPropagation=t.stopPropagation),r.call(this,n)})},Hammer.Instance.prototype.on=function(e,n){return t(this.element).on(e,n)},Hammer.Instance.prototype.off=function(e,n){return t(this.element).off(e,n)},Hammer.Instance.prototype.trigger=function(e,n){var i=t(this.element);return i.has(n.target).length&&(i=t(n.target)),i.trigger({type:e,gesture:n})},t.fn.hammer=function(e){return this.each(function(){var n=t(this),i=n.data("hammer");i?i&&e&&Hammer.utils.extend(i.options,e):n.data("hammer",new Hammer(this,e||{}))})})}(window.jQuery||window.Zepto);
\ No newline at end of file
diff --git a/app/assets/javascripts/wdl-viewer/modernizr-wdl.min.js b/app/assets/javascripts/wdl-viewer/modernizr-wdl.min.js
deleted file mode 100644
index 2816db1b..00000000
--- a/app/assets/javascripts/wdl-viewer/modernizr-wdl.min.js
+++ /dev/null
@@ -1,3 +0,0 @@
-/* custom Modernizr build used on WDL production */
-/* js flexbox flexboxlegacy canvas no-touch history rgba csstransforms fontface video audio localstorage fullscreen */
-window.Modernizr=function(window,document,undefined){var version="2.6.2",Modernizr={},enableClasses=true,docElement=document.documentElement,mod="modernizr",modElem=document.createElement(mod),mStyle=modElem.style,inputElem=document.createElement("input"),smile=":)",toString={}.toString,prefixes=" -webkit- -moz- -o- -ms- ".split(" "),omPrefixes="Webkit Moz O ms",cssomPrefixes=omPrefixes.split(" "),domPrefixes=omPrefixes.toLowerCase().split(" "),tests={},inputs={},attrs={},classes=[],slice=classes.slice,featureName,injectElementWithStyles=function(rule,callback,nodes,testnames){var style,ret,node,docOverflow,div=document.createElement("div"),body=document.body,fakeBody=body||document.createElement("body");if(parseInt(nodes,10)){while(nodes--){node=document.createElement("div");node.id=testnames?testnames[nodes]:mod+(nodes+1);div.appendChild(node)}}style=["",'"].join("");div.id=mod;(body?div:fakeBody).innerHTML+=style;fakeBody.appendChild(div);if(!body){fakeBody.style.background="";fakeBody.style.overflow="hidden";docOverflow=docElement.style.overflow;docElement.style.overflow="hidden";docElement.appendChild(fakeBody)}ret=callback(div,rule);if(!body){fakeBody.parentNode.removeChild(fakeBody);docElement.style.overflow=docOverflow}else{div.parentNode.removeChild(div)}return!!ret},_hasOwnProperty={}.hasOwnProperty,hasOwnProp;if(!is(_hasOwnProperty,"undefined")&&!is(_hasOwnProperty.call,"undefined")){hasOwnProp=function(object,property){return _hasOwnProperty.call(object,property)}}else{hasOwnProp=function(object,property){return property in object&&is(object.constructor.prototype[property],"undefined")}}if(!Function.prototype.bind){Function.prototype.bind=function bind(that){var target=this;if(typeof target!="function"){throw new TypeError}var args=slice.call(arguments,1),bound=function(){if(this instanceof bound){var F=function(){};F.prototype=target.prototype;var self=new F;var result=target.apply(self,args.concat(slice.call(arguments)));if(Object(result)===result){return result}return self}else{return target.apply(that,args.concat(slice.call(arguments)))}};return bound}}function setCss(str){mStyle.cssText=str}function setCssAll(str1,str2){return setCss(prefixes.join(str1+";")+(str2||""))}function is(obj,type){return typeof obj===type}function contains(str,substr){return!!~(""+str).indexOf(substr)}function testProps(props,prefixed){for(var i in props){var prop=props[i];if(!contains(prop,"-")&&mStyle[prop]!==undefined){return prefixed=="pfx"?prop:true}}return false}function testDOMProps(props,obj,elem){for(var i in props){var item=obj[props[i]];if(item!==undefined){if(elem===false)return props[i];if(is(item,"function")){return item.bind(elem||obj)}return item}}return false}function testPropsAll(prop,prefixed,elem){var ucProp=prop.charAt(0).toUpperCase()+prop.slice(1),props=(prop+" "+cssomPrefixes.join(ucProp+" ")+ucProp).split(" ");if(is(prefixed,"string")||is(prefixed,"undefined")){return testProps(props,prefixed)}else{props=(prop+" "+domPrefixes.join(ucProp+" ")+ucProp).split(" ");return testDOMProps(props,prefixed,elem)}}tests["flexbox"]=function(){return testPropsAll("flexWrap")};tests["flexboxlegacy"]=function(){return testPropsAll("boxDirection")};tests["canvas"]=function(){var elem=document.createElement("canvas");return!!(elem.getContext&&elem.getContext("2d"))};tests["touch"]=function(){var bool;if("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch){bool=true}else{injectElementWithStyles(["@media (",prefixes.join("touch-enabled),("),mod,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(node){bool=node.offsetTop===9})}return bool};tests["history"]=function(){return!!(window.history&&history.pushState)};tests["rgba"]=function(){setCss("background-color:rgba(150,255,150,.5)");return contains(mStyle.backgroundColor,"rgba")};tests["csstransforms"]=function(){return!!testPropsAll("transform")};tests["fontface"]=function(){var bool;injectElementWithStyles('@font-face {font-family:"font";src:url("https://")}',function(node,rule){var style=document.getElementById("smodernizr"),sheet=style.sheet||style.styleSheet,cssText=sheet?sheet.cssRules&&sheet.cssRules[0]?sheet.cssRules[0].cssText:sheet.cssText||"":"";bool=/src/i.test(cssText)&&cssText.indexOf(rule.split(" ")[0])===0});return bool};tests["video"]=function(){var elem=document.createElement("video"),bool=false;try{if(bool=!!elem.canPlayType){bool=new Boolean(bool);bool.ogg=elem.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,"");bool.h264=elem.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,"");bool.webm=elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}}catch(e){}return bool};tests["audio"]=function(){var elem=document.createElement("audio"),bool=false;try{if(bool=!!elem.canPlayType){bool=new Boolean(bool);bool.ogg=elem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,"");bool.mp3=elem.canPlayType("audio/mpeg;").replace(/^no$/,"");bool.wav=elem.canPlayType('audio/wav; codecs="1"').replace(/^no$/,"");bool.m4a=(elem.canPlayType("audio/x-m4a;")||elem.canPlayType("audio/aac;")).replace(/^no$/,"")}}catch(e){}return bool};tests["localstorage"]=function(){try{localStorage.setItem(mod,mod);localStorage.removeItem(mod);return true}catch(e){return false}};function webforms(){Modernizr["input"]=function(props){for(var i=0,len=props.length;i";supportsHtml5Styles="hidden"in a;supportsUnknownElements=a.childNodes.length==1||function(){document.createElement("a");var frag=document.createDocumentFragment();return typeof frag.cloneNode=="undefined"||typeof frag.createDocumentFragment=="undefined"||typeof frag.createElement=="undefined"}()}catch(e){supportsHtml5Styles=true;supportsUnknownElements=true}})();function addStyleSheet(ownerDocument,cssText){var p=ownerDocument.createElement("p"),parent=ownerDocument.getElementsByTagName("head")[0]||ownerDocument.documentElement;p.innerHTML="x";return parent.insertBefore(p.lastChild,parent.firstChild)}function getElements(){var elements=html5.elements;return typeof elements=="string"?elements.split(" "):elements}function getExpandoData(ownerDocument){var data=expandoData[ownerDocument[expando]];if(!data){data={};expanID++;ownerDocument[expando]=expanID;expandoData[expanID]=data}return data}function createElement(nodeName,ownerDocument,data){if(!ownerDocument){ownerDocument=document}if(supportsUnknownElements){return ownerDocument.createElement(nodeName)}if(!data){data=getExpandoData(ownerDocument)}var node;if(data.cache[nodeName]){node=data.cache[nodeName].cloneNode()}else if(saveClones.test(nodeName)){node=(data.cache[nodeName]=data.createElem(nodeName)).cloneNode()}else{node=data.createElem(nodeName)}return node.canHaveChildren&&!reSkip.test(nodeName)?data.frag.appendChild(node):node}function createDocumentFragment(ownerDocument,data){if(!ownerDocument){ownerDocument=document}if(supportsUnknownElements){return ownerDocument.createDocumentFragment()}data=data||getExpandoData(ownerDocument);var clone=data.frag.cloneNode(),i=0,elems=getElements(),l=elems.length;for(;i= 500 || "timeout" == t) && this.tries++ <= this.retryLimit && jQuery.ajax(this)
- }, jQuery.ajax(e)
-}, WDL.Search = (function () {
- 'use strict';
-
- function matchesTerm(haystack, needle) {
- var key = haystack.toLocaleLowerCase();
- return key.indexOf(needle.toLocaleLowerCase()) > -1;
- }
-
- function inTerms(a, b) {
- for (var i = 0; i < b.length; i++) {
- if (matchesTerm(a, b[i])) {
- return true;
- }
- }
- return false;
- }
-
- function formatPercentage(i) {
- // Take a float between 0.0 and 1.0 a string percentage suitable for CSS:
- return Math.round(100 * i).toString() + '%';
- }
-
- return {
- inTerms: inTerms,
- formatPercentage: formatPercentage
- };
-})();
\ No newline at end of file
diff --git a/app/assets/javascripts/wdl-viewer/wdl-viewer_commonwealth.js b/app/assets/javascripts/wdl-viewer/wdl-viewer_commonwealth.js
deleted file mode 100644
index 57796f63..00000000
--- a/app/assets/javascripts/wdl-viewer/wdl-viewer_commonwealth.js
+++ /dev/null
@@ -1,1147 +0,0 @@
-/*global navigator, window, document, Element, Modernizr, jQuery, Image, OpenSeadragon, WDL */
-/* this is a modified version of the wdl-viewer JS */
-/* https://github.com/LibraryOfCongress/wdl-viewer/src/js/wdl-viewer.js */
-/* Thanks to Chris Adams (https://github.com/acdha) for help with adaptation */
-/* all local changes are marked with: *** commonwealth changes *** */
-
-(function ($) {
- "use strict";
- var $window = $(window),
- placeholderImage = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
-
- var gettext = window.gettext;
- if (typeof(gettext) == "undefined") {
- // intentionally does nothing but avoids breaking if JS I18N dict fails to load
- gettext = function (i) { return i; };
- }
-
- function isFullScreen() {
- return ((document.fullScreenElement && document.fullScreenElement !== null) ||
- (!document.mozFullScreen && !document.webkitIsFullScreen));
- }
-
- function enterFullscreen() {
- var doc = document.documentElement;
- if (doc.requestFullscreen) {
- doc.requestFullscreen();
- } else if (doc.webkitRequestFullscreen) {
- doc.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
- } else if (doc.mozRequestFullScreen) {
- doc.mozRequestFullScreen();
- }
- }
-
- function leaveFullscreen() {
- if (document.exitFullscreen) {
- document.exitFullscreen();
- } else if (document.cancelFullscreen) {
- document.cancelFullscreen();
- } else if (document.mozCancelFullScreen) {
- document.mozCancelFullScreen();
- } else if (document.webkitCancelFullScreen) {
- document.webkitCancelFullScreen();
- }
- }
-
- function toggleFullscreen() {
- if (isFullScreen()) {
- enterFullscreen();
- } else {
- leaveFullscreen();
- }
- }
-
- $window.on("fullscreenchange mozfullscreenchange webkitfullscreenchange msfullscreenchange", function () {
- $window.trigger("resize");
- });
-
- // TODO: Finish refactoring this out of being a jQuery plugin
- $.fn.wdlViewer = function (config) {
- return this.each(function View(idx, elm) {
- return new ViewController(elm, config);
- });
- };
-
- function ViewController(elm, config) {
- var controller = this, // Convenience alias for event handlers…
- $viewer = $(elm),
- $header = $viewer.find("header"),
- $footer = $viewer.find("footer"),
- $help = $("#help"),
- $pages = $("#pages"),
- $grid = $('').hide().insertAfter($pages),
- $seadragon = $('').hide().insertAfter($pages),
- $groupControl = $("#group"),
- $indexControl = $("#index");
-
- // We still want to allow custom events and some jQuery convenience, so we'll expose these to views:
- this.viewer = $viewer;
- this.footer = $footer;
- this.header = $header;
-
- this.config = config;
- this.rotation = config.viewportRotation || 0;
- this.searchText = null; // *** commonwealth changes ***
-
- config.placeholderSrc = config.placeholderSrc || placeholderImage;
- // TODO: Adjust image max size based on the viewport
- config.maxPageEdge = 1024;
- config.maxThumbnailEdge = 256;
-
- // These control the state of the overall View (pagination, search, etc.) but not the individual
- // page displays:
- this.currentGroup = parseInt($groupControl.val(), 10) || 1;
- this.currentIndex = parseInt($indexControl.val(), 10) || 1;
- this.maxIndex = config.pageGroups[this.currentGroup] || 1;
-
- // Hide the group selection button if we only have one item:
- if ($groupControl.children().length < 2) {
- $groupControl.parent().hide();
- }
-
- if ($.isFunction(config.imageUrlTemplate)) {
- this.generateImageUrl = config.imageUrlTemplate;
- }
-
- if ($.isFunction(config.pageUrlTemplate)) {
- this.generatePageUrl = config.pageUrlTemplate;
- }
-
- if ($.isFunction(config.dziUrlTemplate)) {
- this.generateDziUrl = config.dziUrlTemplate;
- }
-
- /* *** commonwealth changes *** */
- if ($.isFunction(config.thumbUrlTemplate)) {
- this.generateThumbUrl = config.thumbUrlTemplate;
- }
- if ($.isFunction(config.wordCoordinatesUrlTemplate)) {
- this.generateWordCoordinatesUrl = config.wordCoordinatesUrlTemplate;
- }
-
- this.pageView = new PageView(this, $pages, config);
-
- if (config.dziUrlTemplate) {
- this.seadragonView = new SeadragonView(this, $seadragon, config);
- }
-
- this.gridView = new GridView(this, $grid, config);
- this.activeView = this.pageView;
-
- /* *** commonwealth changes *** */
- /* add classes for bootstrap and font-awesome */
- // Add toolbar features which only work with JavaScript:
- if (this.seadragonView) {
- $('')
- .attr("title","Zoom")
- .appendTo("footer .toolbar .controls")
- .on("click", $.proxy(function () {
- if ((this.activeView == this.seadragonView) || (this.activeView == this.gridView)) {
- this.openPageView();
- } else {
- this.openSeadragonView();
- }
- }, this));
- }
-
- if (Modernizr.canvas || Modernizr.csstransforms) {
- $('')
- // .text(gettext("Rotate Left"))
- .attr("title","Rotate Left")
- .appendTo("footer .toolbar .controls")
- .on("click", $.proxy(function () {
- this.rotate(true);
- }, this));
-
- $('')
- //.text(gettext("Rotate Right"))
- .attr("title","Rotate Right")
- .appendTo("footer .toolbar .controls")
- .on("click", $.proxy(function () {
- this.rotate();
- }, this));
- }
-
- $('')
- .attr("title","Page List")
- .appendTo("footer .toolbar .controls")
- .on("click", $.proxy(function () {
- if (this.activeView == this.gridView) {
- this.openPageView();
- } else {
- this.openGridView();
- }
- }, this));
-
- if ($("html").hasClass("fullscreen")) {
- $('')
- .attr("title","Full Screen")
- .appendTo("footer .toolbar .controls")
- .on("click", function () {
- toggleFullscreen();
- });
- }
-
- $('')
- .attr("title","Help")
- .appendTo("footer .toolbar .controls")
- .on("click", function () {
- $("#help").toggle();
- });
-
- /* ***commonwealth changes (search add)*** */
- if (config.fts) {
- // IE8 doesn't support some methods used in jquery-deparam
- var q = decodeURIComponent(document.location.search.split('ocr_q=')[1]); // $.deparam(document.location.search)['?ocr_q']
-
- if (q && (q != 'undefined')) {
- controller.searchText = this.setSearchText(q);
- }
-
- var $searchToggle = $('')
- .attr("href", this.setSearchToggleHref())
- .attr("title", "Search this work")
- //.data("ajax_modal", "trigger") // not working!
- .prependTo("footer .toolbar .controls");
- }
-
- $groupControl.on("change", function() {
- controller.setGroup(parseInt($groupControl.val(), 10));
- });
-
- $indexControl.on("change", function() {
- controller.setIndex(parseInt($indexControl.val(), 10));
- });
-
- $viewer.find("input.current-index").on("change", function() {
- // This is actually less painful than trying to get to work cross-browser…
- var val = parseInt(this.value, 10);
- if (val == controller.currentIndex || isNaN(val) || val < 0 || val > controller.maxIndex) {
- this.value = controller.currentIndex;
- return false;
- }
-
- controller.setIndex(val);
- });
-
- $(document).on("keydown", $.proxy(function (evt) {
- if ($help.is(':visible')) {
- $help.hide();
- return false;
- }
-
- // Allow views to override:
- if (this.activeView.onKeydown) {
- var res = this.activeView.onKeydown(evt);
- if (typeof(res) != "undefined") {
- return res;
- }
- }
-
- if (evt.metaKey || evt.altKey) {
- if (evt.which == 37 || evt.which == 39) {
- this.rotate(evt.which == 37);
- return false;
- } else {
- // Allow normal handling to avoid interfering with normal browser controls:
- return true;
- }
- }
-
- // Global state changes:
- switch (evt.which) {
- case 80: // p
- $("#toggle-grid").trigger("click");
- return false;
- case 81: // q
- $searchToggle.trigger("click");
- return false;
- case 191: // ?
- $help.show();
- return false;
- case 90: // z
- $("#toggle-seadragon").trigger("click");
- return false;
- case 70: // f
- $("#toggle-fullscreen").trigger("click");
- return false;
- case 27: // esc
- leaveFullscreen();
- return false;
- case 32: // Space bar
- if (evt.shiftKey) {
- this.goToPreviousPage();
- } else {
- this.goToNextPage();
- }
- return false;
-
- case 74: // j
- case 34: // Page Down
- this.goToNextPage();
- return false;
-
- case 75: // k
- case 33: // Page Up
- this.goToPreviousPage();
- return false;
-
- case 37: // left arrow
- this.goToPreviousPage();
- return false;
-
- case 39: // right arrow
- this.goToNextPage();
- return false;
- }
-
- // Fall through to normal browser default handling:
- return true;
- }, this));
-
- $help.on("click", function () {
- $help.hide();
- });
-
- $viewer.on("goto-next-page", $.proxy(this.goToNextPage, this));
- $viewer.on("goto-previous-page", $.proxy(this.goToPreviousPage, this));
-
- $viewer.on("goto-page", function (evt, newGroup, newIndex) {
- controller.setGroup(parseInt(newGroup, 10), parseInt(newIndex, 10));
- });
-
- /* *** commonwealth addition *** */
- $viewer.on("goto-page-search", function (evt, newGroup, newIndex, query) {
- controller.searchText = controller.setSearchText(query);
- $searchToggle.attr("href", controller.setSearchToggleHref());
- controller.setGroup(parseInt(newGroup, 10), parseInt(newIndex, 10));
- });
-
- /*
- We offer two convenience functions for event handlers which increment the current rotation as
- well as a way to set the current rotation directly:
- */
- $viewer.on("rotate-left", function () {
- controller.rotate(true);
- });
- $viewer.on("rotate-right", function () {
- controller.rotate();
- });
- $viewer.on("set-rotation", function (evt, degrees) {
- controller.setRotation(degrees);
- });
-
- $viewer.on("page-changed", $.proxy(function () {
- $groupControl.val(this.currentGroup);
- $indexControl.val(this.currentIndex);
- $viewer.find('input.current-index').attr('max', this.maxIndex).val(this.currentIndex);
- $viewer.find(".max-index").text(this.maxIndex);
- $indexControl.attr("max", this.maxIndex);
- }, this));
-
- $viewer.on("prefetch-adjacent-pages", $.proxy(function () {
- this.activeView.prefetch();
- }, this));
-
- $window.on("resize", $.proxy(function () {
- this.activeView.onResize();
- }, this));
-
- $viewer.on("open-seadragon", $.proxy(function () { this.openSeadragonView(); }, this));
-
- // For efficiency we'll expose a variable which event handlers can use to decide whether to make an
- // expensive jQuery call:
-
- var headerHidden = false;
- $viewer.on("hide-header", function () {
- if (!headerHidden) {
- headerHidden = true;
- $header.stop(true, true).slideUp();
- }
- });
- $viewer.on("show-header", function () {
- if (headerHidden) {
- headerHidden = false;
- $header.stop(true, true).slideDown();
- }
- });
-
- var footerHidden = false;
- $viewer.on("hide-footer", $.proxy(function () {
- // Don't hide the footer when the seadragon view is active as there's no way to restore it
- // without using keyboard shortcuts:
- if (!footerHidden && (this.activeView != this.seadragonView)) {
- footerHidden = true;
- $footer.stop(true, true).slideUp();
- }
- }, this));
-
- $viewer.on("show-footer", function () {
- if (footerHidden) {
- footerHidden = false;
- $footer.stop(true, true).slideDown();
- }
- });
-
- var headerHeight = $header.height();
-
- $viewer.on("mousemove", function (evt) {
- if (evt.pageY < headerHeight * 2) {
- $viewer.trigger("show-header");
- } else if (evt.pageY > headerHeight * 3) {
- $viewer.trigger("hide-header");
- }
- });
-
- $viewer.on("hide-chrome", function () {
- $viewer.trigger("hide-header");
- $viewer.trigger("hide-footer");
- });
-
- $viewer.on("show-chrome", function () {
- $viewer.trigger("show-header");
- $viewer.trigger("show-footer");
- });
-
- $viewer.on("toggle-chrome", function () {
- if (headerHidden || footerHidden) {
- $viewer.trigger("show-chrome");
- } else {
- $viewer.trigger("hide-chrome");
- }
- });
-
- $viewer.on("page-changed", function () {
- $viewer.trigger("hide-header");
- });
-
- if (config.initialView == "grid") {
- this.openGridView();
- } else if (config.initialView == "seadragon") {
- this.openSeadragonView();
- } else {
- this.openPageView();
- }
-
- this.updateViewer();
- }
-
- ViewController.prototype = {
- generatePageUrl: function (group, index) {
- // commonwealth changes (search add)
- var url = this.config.pageUrlTemplate.replace('{group}', group).replace('{index}', index);
-
- if (this.searchText) {
- return "?ocr_q=" + encodeURIComponent(this.searchText) + url
- } else {
- return url;
- }
- },
- generateWordCoordinatesUrl: function (group, index) {
- return this.config.wordCoordinatesUrlTemplate.replace('{group}', group).replace('{index}', index);
- },
- generateImageUrl: function (group, index, maxEdge) {
- return this.config.imageUrlTemplate.replace(/\{([^}]+)\}/g, function(match, name) {
- switch (name) {
- case "group":
- return group;
- case "index":
- return index;
- case "height":
- case "width":
- return maxEdge;
- }
- });
- },
- generateDziUrl: function (group, index) {
- return this.config.dziUrlTemplate.replace("{group}", group).replace("{index}", index);
- },
- setIndex: function (newIndex) {
- if (newIndex < 1) {
- newIndex = 1;
- } else if (newIndex > this.maxIndex) {
- newIndex = this.maxIndex;
- }
-
- if (newIndex == this.currentIndex) {
- return;
- }
-
- this.currentIndex = newIndex;
-
- this.updateViewer();
- },
- /* ***commonwealth changes*** */
- generateThumbUrl: function (group, index) {
- return this.config.thumbUrlTemplate.replace('{group}', group).replace('{index}', index);
- },
- setGroup: function (newGroup, newIndex) {
- if (newGroup == this.currentGroup && (!newIndex || newIndex == this.currentIndex)) {
- return;
- }
-
- this.currentGroup = newGroup;
- this.currentIndex = !!newIndex ? newIndex : 1;
- this.maxIndex = this.config.pageGroups[newGroup];
-
- this.updateViewer();
- },
- updateViewer: function () {
- // Update next / previous links:
- if (this.currentIndex < this.maxIndex) {
- $(".toolbar .page.next")
- .removeClass("disabled")
- .attr("href", this.generatePageUrl(this.currentGroup, this.currentIndex + 1));
- } else {
- $(".toolbar .page.next")
- .addClass("disabled")
- .removeAttr("href");
- }
-
- if (this.currentIndex > 1) {
- $(".toolbar .page.previous")
- .removeClass("disabled")
- .attr("href", this.generatePageUrl(this.currentGroup, this.currentIndex - 1));
- } else {
- $(".toolbar .page.previous")
- .addClass("disabled")
- .removeAttr("href");
- }
-
- this.viewer.data({group: this.currentGroup, index: this.currentIndex});
-
- window.history.replaceState(
- {
- group: this.currentGroup,
- index: this.currentIndex
- },
- "Page " + this.currentIndex,
- this.generatePageUrl(this.currentGroup, this.currentIndex)
- );
- this.activeView.update();
- this.viewer.trigger("page-changed");
- this.activeView.prefetch();
- },
- goToNextPage: function () {
- var step = this.activeView.getPageCount(),
- delta = this.maxIndex - this.currentIndex;
-
- if (delta > 0) {
- this.setIndex(this.currentIndex + step);
- } else {
- // In case chrome is hidden, display the nav so the user can see they're on the last page:
- this.viewer.trigger("show-chrome");
- }
- },
- goToPreviousPage: function () {
- var step = this.activeView.getPageCount();
-
- if (this.currentIndex > 1) {
- this.setIndex(this.currentIndex - step);
- } else {
- // In case chrome is hidden, display the nav so the user can see they're on the first page:
- this.viewer.trigger("show-chrome");
- }
- },
- openPageView: function () {
- if (this.activeView == this.pageView) {
- return;
- } else if (this.activeView) {
- this.activeView.hide();
- }
-
- this.activeView = this.pageView;
- this.pageView.show();
- this.viewer.attr("data-active-view", "page").trigger("show-footer");
- },
- openGridView: function () {
- if (this.activeView == this.gridView) {
- return;
- } else if (this.activeView) {
- this.activeView.hide();
- }
- this.activeView = this.gridView;
- this.activeView.show();
- this.viewer.attr("data-active-view", "grid"); // *** commonwealth changes *** .trigger("hide-footer")
- },
- openSeadragonView: function () {
- if (!this.seadragonView || this.activeView == this.seadragonView) {
- return;
- } else if (this.activeView) {
- this.activeView.hide();
- }
-
- this.activeView = this.seadragonView;
- this.activeView.show();
- this.viewer.attr("data-active-view", "seadragon").trigger("show-footer");
- },
- rotate: function (reverse) {
- this.setRotation(this.rotation + (reverse ? -90 : 90));
- },
- setRotation: function (degrees) {
- this.rotation = degrees;
- if (this.activeView && this.activeView.setRotation) {
- this.activeView.setRotation(this.rotation);
- }
- },
- /* *** commonwealth changes (search add) -- setSearchText preps ocr_q params for search *** */
- setSearchText: function (text) {
- return decodeURIComponent($.trim(text));
- },
- /* *** commonwealth changes (search add) -- setSearchToggleHref sets target of search control link *** */
- setSearchToggleHref: function () {
- return this.searchText ? this.config.ocrSearchPath + '?ocr_q=' + this.searchText : this.config.ocrSearchPath;
- }
- };
-
- function PageView(controller, $container, config) {
- this.controller = controller;
- this.config = config;
-
- var $pages = $("#pages"),
- $currentPage = $pages.find(".current img").first(),
- $nextPage = $(''),
- previousImages = [new Image(), new Image(), new Image()],
- nextImages = [new Image(), new Image(), new Image()];
-
- $currentPage.parent().clone().empty().removeClass("current").addClass("next")
- .appendTo($pages)
- .append($nextPage);
-
- this.hide = function () {
- $container.hide();
- };
-
- /* *** commonwealth changes *** */
- this.show = function () {
- var seadragon_toggle = $("#toggle-seadragon");
- seadragon_toggle.attr("title","Zoom");
- seadragon_toggle.find("i").attr("class", "fa fa-plus");
-
- $container.show();
- this.update();
- };
-
- this.setRotation = function (degrees) {
- // We set this explicitly here rather
- $pages.css({
- '-webkit-transform': 'rotate(' + degrees + 'deg)',
- '-ms-transform': 'rotate(' + degrees + 'deg)',
- 'transform': 'rotate(' + degrees + 'deg)'
- });
-
- this.checkViewportConstraints();
- };
-
- this.getPageCount = function () {
- return $pages.find("img:visible").length;
- };
-
- this.update = function() {
- // Cycle the sources to avoid issues with the load event not firing on cache hits:
- var newSrc = controller.generateImageUrl(controller.currentGroup, controller.currentIndex,
- config.maxPageEdge);
- if (newSrc != $currentPage.attr("src")) {
- $pages.find("img").fadeTo(200, 0.3);
- $currentPage.attr("src", newSrc);
- }
-
- /*
- We'll set our own dirty flag because we can't rely on the HTML5 img.complete property
- when an error occurs while loading an image:
-
- https://bugs.webkit.org/show_bug.cgi?id=28832
- https://bugzilla.mozilla.org/show_bug.cgi?id=513541
- */
- $nextPage.hide()
- .attr("src", this.config.placeholderSrc)
- .data("dirty", true);
-
- if ((controller.maxIndex - controller.currentIndex) > 0) {
- $nextPage.attr("src", controller.generateImageUrl(controller.currentGroup,
- controller.currentIndex + 1,
- config.maxPageEdge));
- } else {
- $nextPage.hide();
- }
-
- this.setRotation(this.controller.rotation);
- this.updateSearch();
- };
-
- this.checkViewportConstraints = function() {
- if ($nextPage.data("dirty")) {
- return;
- }
-
- var lastPage = ((this.controller.maxIndex - this.controller.currentIndex) < 1);
-
- /* ***commonwealth changes*** */
- var firstPage = (this.controller.currentIndex == 1);
-
- var overflow = false;
-
- // CSS transforms rotate display but not the DOM element's height/width:
- if (this.controller.rotation % 180 === 0) {
- overflow = ($nextPage.outerWidth() + $currentPage.outerWidth() + 20 >= $window.width());
- } else {
- overflow = ($nextPage.outerHeight() + $currentPage.outerHeight() + 20 >= $window.height());
- }
-
- /* ***commonwealth changes*** */
- /* don't show $nextPage if viewing the first page */
- /* (which is usually the jacket/cover, so this keeps gutter aligned properly) */
- if (firstPage || lastPage || overflow) {
- $nextPage.hide();
- } else {
- $nextPage.show()
- .stop(true, false)
- .fadeTo(200, 1.0);
- }
- };
-
- this.onResize = function () {
- return this.checkViewportConstraints();
- };
-
- this.prefetch = function () {
- for (var i = 0; i < 3; i++) {
- nextImages[i].src = controller.generateImageUrl(
- controller.currentGroup,
- Math.min(controller.maxIndex, controller.currentIndex + 1 + i),
- config.maxPageEdge
- );
- }
-
- for (i = 0; i < 3; i++) {
- previousImages[i].src = controller.generateImageUrl(
- controller.currentGroup,
- Math.max(1, controller.currentIndex - (1 + 1)),
- config.maxPageEdge
- );
- }
- };
-
- /* commonwealth changes (search add) */
- this.updateSearch = function () {
- if (!config.fts || !controller.searchText) { // !controller.search || !controller.search.query) {
- return;
- }
-
- $pages.find(".highlighted").remove();
-
- var terms = this.processTerms(controller.searchText); // controller.search.terms;
-
- this.applySearchHighlighting(controller.currentGroup, controller.currentIndex, terms);
- if (controller.currentIndex < controller.maxIndex) {
- this.applySearchHighlighting(controller.currentGroup, controller.currentIndex + 1, terms);
- }
- };
-
- this.applySearchHighlighting = function (group, index, terms) {
- WDL.ajaxRetry({
- url: controller.generateWordCoordinatesUrl(group, index, terms),
- success: function (data) {
- if (group != controller.currentGroup ||
- (index != controller.currentIndex && index != controller.currentIndex + 1)) {
- return;
- }
-
- var $page = index == controller.currentIndex ? $currentPage : $nextPage;
-
- var master_height = data.height,
- master_width = data.width;
-
- $.each(data.words, function (k, v) {
- if (!WDL.Search.inTerms(k, terms)) {
- return;
- }
-
- // Response format is x1, y1, x2, y2
- for (var i=0; i < v.length; i++) {
- var coords = v[i];
-
- $('
\ No newline at end of file
diff --git a/app/views/advanced/_advanced_search_facets.html.erb b/app/views/advanced/_advanced_search_facets.html.erb
index 7e4e837a..4b7f49c4 100644
--- a/app/views/advanced/_advanced_search_facets.html.erb
+++ b/app/views/advanced/_advanced_search_facets.html.erb
@@ -1,5 +1,5 @@
\ No newline at end of file
diff --git a/app/views/advanced/_advanced_search_fields.html.erb b/app/views/advanced/_advanced_search_fields.html.erb
index 02d15857..4588b539 100644
--- a/app/views/advanced/_advanced_search_fields.html.erb
+++ b/app/views/advanced/_advanced_search_fields.html.erb
@@ -1,39 +1,33 @@
-<% search_fields_for_advanced_search.take(3).each_with_index do |(key, field_def), index| %>
-
+<% search_fields_for_advanced_search.take(3).each_with_index do |(_key, _field_def), index| %>
+
-
-
<% end %>
\ No newline at end of file
diff --git a/app/views/advanced/_advanced_search_help.html.erb b/app/views/advanced/_advanced_search_help.html.erb
index 4fbab0ab..35dcb84b 100644
--- a/app/views/advanced/_advanced_search_help.html.erb
+++ b/app/views/advanced/_advanced_search_help.html.erb
@@ -1,13 +1,15 @@
-
-
Advanced Search tips:
-
-
Use quotation marks to search as a phrase.
-
Use "+" before a term to make it required.
-
Use "-" before a word or phrase to exclude it.
-
Use "OR", "AND", and "NOT" within a search field to create complex boolean logic. You can also use parentheses.
-
Truncation and wildcards are not supported (word-stemming is done automatically).
-
For an open-ended date range limit (e.g. before 1850, after 1900, etc.) leave either the 'Start' or 'End' field blank in the 'Year' section.
-
If a date range is entered in the form in the 'Year' section, undated items will not be included in the search results.
-
If no boxes are checked in the 'Format' or 'Institution' limit, all values will be included.
-
+
+
+
Advanced Search tips:
+
+
Use quotation marks to search as a phrase.
+
Use "+" before a term to make it required.
+
Use "-" before a word or phrase to exclude it.
+
Use "OR", "AND", and "NOT" within a search field to create complex boolean logic. You can also use parentheses.
+
Truncation and wildcards are not supported (word-stemming is done automatically).
+
For an open-ended date range limit (e.g. before 1850, after 1900, etc.) leave either the 'Start' or 'End' field blank in the 'Year' section.
+
If a date range is entered in the form in the 'Year' section, undated items will not be included in the search results.
+
If no boxes are checked in the 'Format' or 'Institution' limit, all values will be included.
+
+
\ No newline at end of file
diff --git a/app/views/advanced/_facet_layout.html.erb b/app/views/advanced/_facet_layout.html.erb
index 64ee9b3e..ef879210 100644
--- a/app/views/advanced/_facet_layout.html.erb
+++ b/app/views/advanced/_facet_layout.html.erb
@@ -1,9 +1,8 @@
-
- <% if folder.description %>
- <%= folder.description %>
- <% end %>
-
\ No newline at end of file
diff --git a/app/views/catalog/_add_this.html.erb b/app/views/catalog/_add_this.html.erb
index ee6d7755..ad52ca07 100644
--- a/app/views/catalog/_add_this.html.erb
+++ b/app/views/catalog/_add_this.html.erb
@@ -1,12 +1,9 @@
-
-
-
\ No newline at end of file
diff --git a/app/views/catalog/_az_links.html.erb b/app/views/catalog/_az_links.html.erb
index e9d2b545..7b011f62 100644
--- a/app/views/catalog/_az_links.html.erb
+++ b/app/views/catalog/_az_links.html.erb
@@ -1,15 +1,13 @@
-
\ No newline at end of file
diff --git a/app/views/catalog/_citation.html.erb b/app/views/catalog/_citation.html.erb
index bde62f6a..39240886 100644
--- a/app/views/catalog/_citation.html.erb
+++ b/app/views/catalog/_citation.html.erb
@@ -1,6 +1,8 @@
+<%# override so we can add save_search partial from Bpluser %>
+<% if Deprecation.silence(Blacklight::RenderConstraintsHelperBehavior) { query_has_constraints? } %>
+
+<% end %>
diff --git a/app/views/catalog/_facet_group.html.erb b/app/views/catalog/_facet_group.html.erb
new file mode 100644
index 00000000..575fa6c4
--- /dev/null
+++ b/app/views/catalog/_facet_group.html.erb
@@ -0,0 +1,27 @@
+<%# override so we can set facet heading based on controller %>
+<% # main container for facets/limits menu -%>
+<% if has_facet_values? facet_field_names(groupname), @response %>
+
+<% end %>
\ No newline at end of file
diff --git a/app/views/catalog/_facet_limit_series.html.erb b/app/views/catalog/_facet_limit_series.html.erb
index 68f49f49..5e53dd67 100644
--- a/app/views/catalog/_facet_limit_series.html.erb
+++ b/app/views/catalog/_facet_limit_series.html.erb
@@ -1,23 +1,20 @@
diff --git a/app/views/catalog/_facets.html.erb b/app/views/catalog/_facets.html.erb
deleted file mode 100644
index c6a29245..00000000
--- a/app/views/catalog/_facets.html.erb
+++ /dev/null
@@ -1,31 +0,0 @@
-<% # main container for facets/limits menu -%>
-
-<% case params[:controller] %>
-<% when 'collections' %>
- <% facet_heading = t('blacklight.collections.facets.title') %>
-<% when 'institutions' %>
- <% facet_heading = t('blacklight.institutions.facets.title') %>
-<% else %>
- <% facet_heading = t('blacklight.search.facets.title') %>
-<% end %>
-
-<% if has_facet_values? %>
-
-
-
-
-
- <%= facet_heading %>
-
-
-
-
- <%= render_facet_partials %>
-
-
-<% end %>
\ No newline at end of file
diff --git a/app/views/catalog/_facets_series.html.erb b/app/views/catalog/_facets_series.html.erb
index 4c327066..24ab9604 100644
--- a/app/views/catalog/_facets_series.html.erb
+++ b/app/views/catalog/_facets_series.html.erb
@@ -1,4 +1,4 @@
<% # container for series facet -%>
<%= t('blacklight.collections.series.title') %>
-<%= render_facet_partials(['related_item_series_ssim'],
- :partial => 'facet_limit_series') %>
\ No newline at end of file
+<%= render_facet_partials([blacklight_config.series_field], response: @response,
+ partial: 'facet_limit_series') %>
\ No newline at end of file
diff --git a/app/views/catalog/_field.json.jbuilder b/app/views/catalog/_field.json.jbuilder
new file mode 100644
index 00000000..ade28e80
--- /dev/null
+++ b/app/views/catalog/_field.json.jbuilder
@@ -0,0 +1,3 @@
+# frozen_string_literal: true
+
+json.set! field_name, field_presenter.values
diff --git a/app/views/catalog/_folder_item_control.html.erb b/app/views/catalog/_folder_item_control.html.erb
deleted file mode 100644
index 405b1fc4..00000000
--- a/app/views/catalog/_folder_item_control.html.erb
+++ /dev/null
@@ -1,65 +0,0 @@
-<% if current_or_guest_user %>
-
\ No newline at end of file
diff --git a/app/views/catalog/_index_gallery.html.erb b/app/views/catalog/_index_gallery.html.erb
deleted file mode 100644
index 7aa8aff3..00000000
--- a/app/views/catalog/_index_gallery.html.erb
+++ /dev/null
@@ -1,9 +0,0 @@
-<%# copy (with some changes to styles) of blacklight-gallery/app/views/catalog/_index_gallery %>
-
\ No newline at end of file
diff --git a/app/views/catalog/_index_header_default.html.erb b/app/views/catalog/_index_header_default.html.erb
index e499dee3..2da96c6b 100644
--- a/app/views/catalog/_index_header_default.html.erb
+++ b/app/views/catalog/_index_header_default.html.erb
@@ -1,12 +1,21 @@
<%# header bar for doc items in index view -%>
-
+<%# override so we can add folder control and custom title rendering %>
+
+ <%# main title container for doc partial view
+ How many bootstrap columns need to be reserved
+ for bookmarks control depends on size.
+ -%>
+ <% document_actions = capture do %>
+ <% # bookmark functions for items/docs -%>
+ <%# render_index_doc_actions document, wrapping_class: "index-document-functions col-sm-3 col-lg-2" %>
+ <% end %>
- <%# create checkbox for folder actions (delete, move, etc.) %>
+ <%# checkbox for folder actions (delete, move, etc.) %>
<% if controller_name == 'folders' || controller_name == 'bookmarks' %>
- <%= check_box_tag('selected[]', document[:id], false, class: 'folder_item_checkbox') %>
+ <%= check_box_tag('selected[]', document[:id], false, class: 'folder_item_checkbox') %>
<% end %>
-
\ No newline at end of file
diff --git a/app/views/catalog/_more_like_this.html.erb b/app/views/catalog/_more_like_this.html.erb
index d9e63c80..e46193ab 100644
--- a/app/views/catalog/_more_like_this.html.erb
+++ b/app/views/catalog/_more_like_this.html.erb
@@ -1,9 +1,9 @@
-
diff --git a/app/views/catalog/_opengraph.html.erb b/app/views/catalog/_opengraph.html.erb
index 71161584..818c1c7b 100644
--- a/app/views/catalog/_opengraph.html.erb
+++ b/app/views/catalog/_opengraph.html.erb
@@ -4,9 +4,9 @@
<% if document[:abstract_tsim] %>
+ length: 300,
+ separator: ' ',
+ omission: '... ') %>" />
<% end %>
<% if has_image_files?(@object_files) %>
-<% if @previous_document || @next_document || current_search_session %>
-
- <% if @previous_document || @next_document %>
-
- <%= link_to_previous_document @previous_document %> |
+<%# override so we can combine pagination and start over links %>
+<% if @search_context[:prev] || @search_context[:next] || current_search_session %>
+
+<% end %>
diff --git a/app/views/catalog/_results_pagination.html.erb b/app/views/catalog/_results_pagination.html.erb
index f47415a6..2503cd4b 100644
--- a/app/views/catalog/_results_pagination.html.erb
+++ b/app/views/catalog/_results_pagination.html.erb
@@ -1,9 +1,10 @@
+<%# override so we can set id on