diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 00000000000..f643017526f
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,12 @@
+.git/
+.github/
+build/
+.editorconfig
+.gitattributes
+.gitignore
+CHANGELOG.md
+CODE_OF_CONDUCT.md
+deploy.sh
+font-selection.json
+README.md
+Vagrantfile
\ No newline at end of file
diff --git a/.editorconfig b/.editorconfig
index b54e172c0db..1692977cec8 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,4 +1,4 @@
-# EditorConfig is awesome: http://EditorConfig.org
+# EditorConfig is awesome: https://EditorConfig.org
# Top-most EditorConfig file
root = true
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000000..3069c432317
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+source/javascripts/lib/* linguist-vendored
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
deleted file mode 100644
index c026a82da63..00000000000
--- a/.github/ISSUE_TEMPLATE.md
+++ /dev/null
@@ -1,18 +0,0 @@
- https://spectrum.chat/slate <-
-
-If you've found a bug with Slate upstream that you're still encountering even in a lightly modified Slate, you're in the right place! Please fill out the form below with the issue you're having and we'll take a look. :)
--->
-
-Operating system: ✍️ TODO
-Last upstream commit (run `git log --author="Robert Lord" | head -n 1`): ✍️ TODO
-Browser version(s): ✍️ TODO
-Ruby version (run `ruby -v`): ✍️ TODO
-
----
-
-✍️ TODO write your issue here
diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md
new file mode 100644
index 00000000000..43305a233da
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug.md
@@ -0,0 +1,22 @@
+---
+name: Report a Bug
+about: Create a report to help us improve
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Bug Description**
+A clear and concise description of what the bug is and how to reproduce it.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Browser (please complete the following information):**
+ - OS: [e.g. iOS]
+ - Browser [e.g. chrome, safari]
+ - Version [e.g. 22]
+
+**Last upstream Slate commit (run `git log --author="\(Robert Lord\)\|\(Matthew Peveler\)\|\(Mike Ralphson\)" | head -n 1`):**
+Put the commit hash here
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 00000000000..16f4beed616
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,5 @@
+blank_issues_enabled: false
+contact_links:
+ - name: Questions, Ideas, Discussions
+ url: https://github.com/slatedocs/slate/discussions
+ about: Ask and answer questions, and propose new features.
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index eebe789aa08..151e45d78cd 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,5 +1,5 @@
\ No newline at end of file
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000000..d17e8826d4f
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,9 @@
+version: 2
+updates:
+- package-ecosystem: bundler
+ directory: "/"
+ schedule:
+ interval: daily
+ open-pull-requests-limit: 10
+ target-branch: dev
+ versioning-strategy: increase-if-necessary
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 00000000000..34e1b77de6f
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,38 @@
+name: Build
+
+on:
+ push:
+ branches: [ '*' ]
+ pull_request:
+ branches: [ '*' ]
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ ruby-version: [2.6, 2.7, '3.0', 3.1, 3.2]
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: Set up Ruby
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: ${{ matrix.ruby-version }}
+
+ - uses: actions/cache@v3
+ with:
+ path: vendor/bundle
+ key: gems-${{ runner.os }}-${{ matrix.ruby-version }}-${{ hashFiles('**/Gemfile.lock') }}
+ restore-keys: |
+ gems-${{ runner.os }}-${{ matrix.ruby-version }}-
+ gems-${{ runner.os }}-
+
+ - run: bundle config set deployment 'true'
+ - name: bundle install
+ run: |
+ bundle config path vendor/bundle
+ bundle install --jobs 4 --retry 3
+
+ - run: bundle exec middleman build
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
new file mode 100644
index 00000000000..6a032b44969
--- /dev/null
+++ b/.github/workflows/deploy.yml
@@ -0,0 +1,44 @@
+name: Deploy
+
+on:
+ push:
+ branches: [ 'main' ]
+
+jobs:
+ deploy:
+ permissions:
+ contents: write
+
+ runs-on: ubuntu-latest
+ env:
+ ruby-version: 2.6
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: Set up Ruby
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: ${{ env.ruby-version }}
+
+ - uses: actions/cache@v3
+ with:
+ path: vendor/bundle
+ key: gems-${{ runner.os }}-${{ env.ruby-version }}-${{ hashFiles('**/Gemfile.lock') }}
+ restore-keys: |
+ gems-${{ runner.os }}-${{ env.ruby-version }}-
+ gems-${{ runner.os }}-
+
+ - run: bundle config set deployment 'true'
+ - name: bundle install
+ run: |
+ bundle config path vendor/bundle
+ bundle install --jobs 4 --retry 3
+
+ - run: bundle exec middleman build
+
+ - name: Deploy
+ uses: peaceiris/actions-gh-pages@v3
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_dir: ./build
+ keep_files: true
diff --git a/.github/workflows/dev_deploy.yml b/.github/workflows/dev_deploy.yml
new file mode 100644
index 00000000000..d9edd290178
--- /dev/null
+++ b/.github/workflows/dev_deploy.yml
@@ -0,0 +1,85 @@
+name: Dev Deploy
+
+on:
+ push:
+ branches: [ 'dev' ]
+
+jobs:
+ push_to_registry:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Check out the repo
+ uses: actions/checkout@v3
+
+ - name: Set up QEMU
+ uses: docker/setup-qemu-action@v1
+ with:
+ platforms: all
+
+ - name: Docker meta
+ id: meta
+ uses: docker/metadata-action@v3
+ with:
+ images: |
+ slatedocs/slate
+ tags: |
+ type=ref,event=branch
+
+ - name: Set up Docker Buildx
+ id: buildx
+ uses: docker/setup-buildx-action@v1
+
+ - name: Login to DockerHub
+ uses: docker/login-action@v1
+ with:
+ username: ${{ secrets.DOCKER_USERNAME }}
+ password: ${{ secrets.DOCKER_ACCESS_KEY }}
+
+ - name: Push to Docker Hub
+ uses: docker/build-push-action@v2
+ with:
+ builder: ${{ steps.buildx.outputs.name }}
+ context: .
+ file: ./Dockerfile
+ platforms: linux/amd64,linux/arm64,linux/ppc64le
+ push: true
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
+
+ deploy_gh:
+ permissions:
+ contents: write
+
+ runs-on: ubuntu-latest
+ env:
+ ruby-version: 2.6
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: Set up Ruby
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: ${{ env.ruby-version }}
+
+ - uses: actions/cache@v3
+ with:
+ path: vendor/bundle
+ key: gems-${{ runner.os }}-${{ env.ruby-version }}-${{ hashFiles('**/Gemfile.lock') }}
+ restore-keys: |
+ gems-${{ runner.os }}-${{ env.ruby-version }}-
+ gems-${{ runner.os }}-
+ - run: bundle config set deployment 'true'
+ - name: bundle install
+ run: |
+ bundle config path vendor/bundle
+ bundle install --jobs 4 --retry 3
+ - run: bundle exec middleman build
+
+ - name: Deploy
+ uses: peaceiris/actions-gh-pages@v3.7.0-8
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ destination_dir: dev
+ publish_dir: ./build
+ keep_files: true
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
new file mode 100644
index 00000000000..149e72011c1
--- /dev/null
+++ b/.github/workflows/publish.yml
@@ -0,0 +1,47 @@
+name: Publish Docker image
+
+on:
+ release:
+ types: [published]
+
+jobs:
+ push_to_registry:
+ name: Push Docker image to Docker Hub
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check out the repo
+ uses: actions/checkout@v3
+
+ - name: Set up QEMU
+ uses: docker/setup-qemu-action@v1
+ with:
+ platforms: all
+
+ - name: Docker meta
+ id: meta
+ uses: docker/metadata-action@v3
+ with:
+ images: slatedocs/slate
+ tags: |
+ type=ref,event=tag
+
+ - name: Set up Docker Buildx
+ id: buildx
+ uses: docker/setup-buildx-action@v1
+
+ - name: Login to DockerHub
+ uses: docker/login-action@v1
+ with:
+ username: ${{ secrets.DOCKER_USERNAME }}
+ password: ${{ secrets.DOCKER_ACCESS_KEY }}
+
+ - name: Push to Docker Hub
+ uses: docker/build-push-action@v2
+ with:
+ builder: ${{ steps.buildx.outputs.name }}
+ context: .
+ file: ./Dockerfile
+ platforms: linux/amd64,linux/arm64,linux/ppc64le
+ push: true
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
diff --git a/.gitignore b/.gitignore
index 10501583560..1d5d08dd245 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,6 @@ build/
_yardoc
doc/
.idea/
+
+# Vagrant artifacts
+ubuntu-*-console.log
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 0d6d210d94a..00000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-sudo: false
-
-language: ruby
-
-rvm:
- - 2.3.3
- - 2.4.0
-
-cache: bundler
-script: bundle exec middleman build
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 218f5caa99e..49b83dc3257 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,178 @@
# Changelog
+## Version 2.13.1
+
+*January 31, 2023*
+
+* Fix Vagrantfile gem install for ruby >= 2.6 (thanks @Cyb0rk)
+* Disable file watcher in run_build() for sake of qemu on arm64 (thanks @anapsix)
+* Expand deprecated git.io links to full url in docs (thanks @judge2020)
+* Add margin to paragraph following code-block on phones (thanks @tlhunter)
+* Bump nokogiri from 1.13.4 to 1.13.9
+* Bump rouge from 3.28.0 to 3.30.0
+* Bump redcarpet from 3.5.1 to 3.6.0
+* Bump middleman from 4.4.2 to 4.4.3
+* Bump middleman-syntax from 3.2.0 to 3.3.0
+* Bump webrick from 1.7.0 to 1.8.1
+
+## Version 2.13.0
+
+*April 22, 2022*
+
+* __Drop support for ruby 2.5__
+* Bump rouge from 3.26.1 to 3.28.0
+* Formally support ruby 3.1
+* Bump nokogiri from 1.12.5 to 1.13.4
+* Build docker images for multiple architectures (e.g. `aarch64`)
+* Remove `VOLUME` declaration from Dockerfile (thanks @aemengo)
+
+The security vulnerabilities reported against recent versions of nokogiri should not affect slate users with a regular setup.
+
+## Version 2.12.0
+
+*November 04, 2021*
+
+* Bump nokogiri from 1.12.3 to 1.12.5
+* Bump ffi from 1.15.0 to 1.15.4
+* Bump rouge from 3.26.0 to 3.26.1
+* Bump middleman from 4.4.0 to 4.4.2
+* Remove unnecessary files from docker images
+
+## Version 2.11.0
+
+*August 12, 2021*
+
+* __[Security]__ Bump addressable transitive dependency from 2.7.0 to 2.8.0
+* Support specifying custom meta tags in YAML front-matter
+* Bump nokogiri from 1.11.3 to 1.12.3 (minimum supported version is 1.11.4)
+* Bump middleman-autoprefixer from 2.10.1 to 3.0.0
+* Bump jquery from 3.5.1 to 3.6.0
+* Bump middleman from [`d180ca3`](https://github.com/middleman/middleman/commit/d180ca337202873f2601310c74ba2b6b4cf063ec) to 4.4.0
+
+## Version 2.10.0
+
+*April 13, 2021*
+
+* Add support for Ruby 3.0 (thanks @shaun-scale)
+* Add requirement for Git on installing dependencies
+* Bump nokogiri from 1.11.2 to 1.11.3
+* Bump middleman from 4.3.11 to [`d180ca3`](https://github.com/middleman/middleman/commit/d180ca337202873f2601310c74ba2b6b4cf063ec)
+
+## Version 2.9.2
+
+*March 30, 2021*
+
+* __[Security]__ Bump kramdown from 2.3.0 to 2.3.1
+* Bump nokogiri from 1.11.1 to 1.11.2
+
+## Version 2.9.1
+
+*February 27, 2021*
+
+* Fix Slate language tabs not working if localStorage is disabled
+
+## Version 2.9.0
+
+*January 19, 2021*
+
+* __Drop support for Ruby 2.3 and 2.4__
+* __[Security]__ Bump nokogiri from 1.10.10 to 1.11.1
+* __[Security]__ Bump redcarpet from 3.5.0 to 3.5.1
+* Specify slate is not supported on Ruby 3.x
+* Bump rouge from 3.24.0 to 3.26.0
+
+## Version 2.8.0
+
+*October 27, 2020*
+
+* Remove last trailing newline when using the copy code button
+* Rework docker image and make available at slatedocs/slate
+* Improve Dockerfile layout to improve caching (thanks @micvbang)
+* Bump rouge from 3.20 to 3.24
+* Bump nokogiri from 1.10.9 to 1.10.10
+* Bump middleman from 4.3.8 to 4.3.11
+* Bump lunr.js from 2.3.8 to 2.3.9
+
+## Version 2.7.1
+
+*August 13, 2020*
+
+* __[security]__ Bumped middleman from 4.3.7 to 4.3.8
+
+_Note_: Slate uses redcarpet, not kramdown, for rendering markdown to HTML, and so was unaffected by the security vulnerability in middleman.
+If you have changed slate to use kramdown, and with GFM, you may need to install the `kramdown-parser-gfm` gem.
+
+## Version 2.7.0
+
+*June 21, 2020*
+
+* __[security]__ Bumped rack in Gemfile.lock from 2.2.2 to 2.2.3
+* Bumped bundled jQuery from 3.2.1 to 3.5.1
+* Bumped bundled lunr from 0.5.7 to 2.3.8
+* Bumped imagesloaded from 3.1.8 to 4.1.4
+* Bumped rouge from 3.17.0 to 3.20.0
+* Bumped redcarpet from 3.4.0 to 3.5.0
+* Fix color of highlighted code being unreadable when printing page
+* Add clipboard icon for "Copy to Clipboard" functionality to code boxes (see note below)
+* Fix handling of ToC selectors that contain punctutation (thanks @gruis)
+* Fix language bar truncating languages that overflow screen width
+* Strip HTML tags from ToC title before displaying it in title bar in JS (backup to stripping done in Ruby code) (thanks @atic)
+
+To enable the new clipboard icon, you need to add `code_clipboard: true` to the frontmatter of source/index.html.md.
+See [this line](https://github.com/slatedocs/slate/blame/main/source/index.html.md#L19) for an example of usage.
+
+## Version 2.6.1
+
+*May 30, 2020*
+
+* __[security]__ update child dependency activesupport in Gemfile.lock to 5.4.2.3
+* Update Middleman in Gemfile.lock to 4.3.7
+* Replace Travis-CI with GitHub actions for continuous integration
+* Replace Spectrum with GitHub discussions
+
+## Version 2.6.0
+
+*May 18, 2020*
+
+__Note__: 2.5.0 was "pulled" due to a breaking bug discovered after release. It is recommended to skip it, and move straight to 2.6.0.
+
+* Fix large whitespace gap in middle column for sections with codeblocks
+* Fix highlighted code elements having a different background than rest of code block
+* Change JSON keys to have a different font color than their values
+* Disable asset hashing for woff and woff2 elements due to middleman bug breaking woff2 asset hashing in general
+* Move Dockerfile to Debian from Alpine
+* Converted repo to a [GitHub template](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-template-repository)
+* Update sassc to 2.3.0 in Gemfile.lock
+
+## Version 2.5.0
+
+*May 8, 2020*
+
+* __[security]__ update nokogiri to ~> 1.10.8
+* Update links in example docs to https://github.com/slatedocs/slate from https://github.com/lord/slate
+* Update LICENSE to include full Apache 2.0 text
+* Test slate against Ruby 2.5 and 2.6 on Travis-CI
+* Update Vagrantfile to use Ubuntu 18.04 (thanks @bradthurber)
+* Parse arguments and flags for deploy.sh on script start, instead of potentially after building source files
+* Install nodejs inside Vagrantfile (thanks @fernandoaguilar)
+* Add Dockerfile for running slate (thanks @redhatxl)
+* update middleman-syntax and rouge to ~>3.2
+* update middleman to 4.3.6
+
+## Version 2.4.0
+
+*October 19, 2019*
+
+- Move repository from lord/slate to slatedocs/slate
+- Fix documentation to point at new repo link, thanks to [Arun](https://github.com/slash-arun), [Gustavo Gawryszewski](https://github.com/gawry), and [Daniel Korbit](https://github.com/danielkorbit)
+- Update `nokogiri` to 1.10.4
+- Update `ffi` in `Gemfile.lock` to fix security warnings, thanks to [Grey Baker](https://github.com/greysteil) and [jakemack](https://github.com/jakemack)
+- Update `rack` to 2.0.7 in `Gemfile.lock` to fix security warnings, thanks to [Grey Baker](https://github.com/greysteil) and [jakemack](https://github.com/jakemack)
+- Update middleman to `4.3` and relax constraints on middleman related gems, thanks to [jakemack](https://github.com/jakemack)
+- Add sass gem, thanks to [jakemack](https://github.com/jakemack)
+- Activate `asset_cache` in middleman to improve cacheability of static files, thanks to [Sam Gilman](https://github.com/thenengah)
+- Update to using bundler 2 for `Gemfile.lock`, thanks to [jakemack](https://github.com/jakemack)
+
## Version 2.3.1
*July 5, 2018*
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000000..077ef3b18a8
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,26 @@
+FROM ruby:2.6-slim
+
+WORKDIR /srv/slate
+
+EXPOSE 4567
+
+COPY Gemfile .
+COPY Gemfile.lock .
+
+RUN apt-get update \
+ && apt-get install -y --no-install-recommends \
+ build-essential \
+ git \
+ nodejs \
+ && gem install bundler \
+ && bundle install \
+ && apt-get remove -y build-essential git \
+ && apt-get autoremove -y \
+ && rm -rf /var/lib/apt/lists/*
+
+COPY . /srv/slate
+
+RUN chmod +x /srv/slate/slate.sh
+
+ENTRYPOINT ["/srv/slate/slate.sh"]
+CMD ["build"]
diff --git a/Gemfile b/Gemfile
index 79d41fff6dd..f2e84416dd6 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,11 +1,13 @@
-ruby '>=2.3.1'
+ruby '>= 2.6'
source 'https://rubygems.org'
# Middleman
-gem 'middleman', '~>4.2.1'
-gem 'middleman-syntax', '~> 3.0.0'
-gem 'middleman-autoprefixer', '~> 2.7.0'
-gem 'middleman-sprockets', '~> 4.1.0'
-gem 'rouge', '~> 2.0.5'
-gem 'redcarpet', '~> 3.4.0'
-gem 'nokogiri', '~> 1.8.2'
+gem 'middleman', '~> 4.4'
+gem 'middleman-syntax', '~> 3.2'
+gem 'middleman-autoprefixer', '~> 3.0'
+gem 'middleman-sprockets', '~> 4.1'
+gem 'rouge', '~> 3.21'
+gem 'redcarpet', '~> 3.6.0'
+gem 'nokogiri', '~> 1.13.3'
+gem 'sass'
+gem 'webrick'
diff --git a/Gemfile.lock b/Gemfile.lock
index eebb95a9694..79bfbcbf7e4 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,61 +1,60 @@
GEM
remote: https://rubygems.org/
specs:
- activesupport (5.0.1)
+ activesupport (6.1.6.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
- i18n (~> 0.7)
- minitest (~> 5.1)
- tzinfo (~> 1.1)
- addressable (2.5.0)
- public_suffix (~> 2.0, >= 2.0.2)
- autoprefixer-rails (6.6.1)
- execjs
- backports (3.6.8)
+ i18n (>= 1.6, < 2)
+ minitest (>= 5.1)
+ tzinfo (~> 2.0)
+ zeitwerk (~> 2.3)
+ addressable (2.8.1)
+ public_suffix (>= 2.0.2, < 6.0)
+ autoprefixer-rails (10.2.5.0)
+ execjs (< 2.8.0)
+ backports (3.23.0)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.12.2)
- compass-import-once (1.0.5)
- sass (>= 3.2, < 3.5)
- concurrent-ruby (1.0.5)
- contracts (0.13.0)
- dotenv (2.2.0)
+ concurrent-ruby (1.2.0)
+ contracts (0.16.1)
+ dotenv (2.8.1)
erubis (2.7.0)
execjs (2.7.0)
- fast_blank (1.0.0)
- fastimage (2.0.1)
- addressable (~> 2)
- ffi (1.9.17)
- haml (4.0.7)
+ fast_blank (1.0.1)
+ fastimage (2.2.6)
+ ffi (1.15.5)
+ haml (5.2.2)
+ temple (>= 0.8.0)
tilt
hamster (3.0.0)
concurrent-ruby (~> 1.0)
- hashie (3.5.1)
- i18n (0.7.0)
- kramdown (1.13.2)
- listen (3.0.8)
- rb-fsevent (~> 0.9, >= 0.9.4)
- rb-inotify (~> 0.9, >= 0.9.7)
- memoist (0.15.0)
- middleman (4.2.1)
+ hashie (3.6.0)
+ i18n (1.6.0)
+ concurrent-ruby (~> 1.0)
+ kramdown (2.4.0)
+ rexml
+ listen (3.8.0)
+ rb-fsevent (~> 0.10, >= 0.10.3)
+ rb-inotify (~> 0.9, >= 0.9.10)
+ memoist (0.16.2)
+ middleman (4.4.3)
coffee-script (~> 2.2)
- compass-import-once (= 1.0.5)
- haml (>= 4.0.5)
- kramdown (~> 1.2)
- middleman-cli (= 4.2.1)
- middleman-core (= 4.2.1)
- sass (>= 3.4.0, < 4.0)
- middleman-autoprefixer (2.7.1)
- autoprefixer-rails (>= 6.5.2, < 7.0.0)
- middleman-core (>= 3.3.3)
- middleman-cli (4.2.1)
+ haml (>= 4.0.5, < 6.0)
+ kramdown (>= 2.3.0)
+ middleman-cli (= 4.4.3)
+ middleman-core (= 4.4.3)
+ middleman-autoprefixer (3.0.0)
+ autoprefixer-rails (~> 10.0)
+ middleman-core (>= 4.0.0)
+ middleman-cli (4.4.3)
thor (>= 0.17.0, < 2.0)
- middleman-core (4.2.1)
- activesupport (>= 4.2, < 5.1)
- addressable (~> 2.3)
+ middleman-core (4.4.3)
+ activesupport (>= 6.1, < 7.1)
+ addressable (~> 2.4)
backports (~> 3.6)
- bundler (~> 1.1)
- contracts (~> 0.13.0)
+ bundler (~> 2.0)
+ contracts (~> 0.13)
dotenv
erubis
execjs (~> 2.0)
@@ -63,67 +62,84 @@ GEM
fastimage (~> 2.0)
hamster (~> 3.0)
hashie (~> 3.4)
- i18n (~> 0.7.0)
- listen (~> 3.0.0)
+ i18n (~> 1.6.0)
+ listen (~> 3.0)
memoist (~> 0.14)
- padrino-helpers (~> 0.13.0)
+ padrino-helpers (~> 0.15.0)
parallel
rack (>= 1.4.5, < 3)
- sass (>= 3.4)
+ sassc (~> 2.0)
servolux
- tilt (~> 2.0)
+ tilt (~> 2.0.9)
+ toml
uglifier (~> 3.0)
- middleman-sprockets (4.1.0)
+ webrick
+ middleman-sprockets (4.1.1)
middleman-core (~> 4.0)
sprockets (>= 3.0)
- middleman-syntax (3.0.0)
+ middleman-syntax (3.3.0)
middleman-core (>= 3.2)
- rouge (~> 2.0)
- mini_portile2 (2.3.0)
- minitest (5.10.1)
- nokogiri (1.8.2)
- mini_portile2 (~> 2.3.0)
- padrino-helpers (0.13.3.3)
- i18n (~> 0.6, >= 0.6.7)
- padrino-support (= 0.13.3.3)
+ rouge (~> 3.2)
+ mini_portile2 (2.8.0)
+ minitest (5.17.0)
+ nokogiri (1.13.9)
+ mini_portile2 (~> 2.8.0)
+ racc (~> 1.4)
+ padrino-helpers (0.15.2)
+ i18n (>= 0.6.7, < 2)
+ padrino-support (= 0.15.2)
tilt (>= 1.4.1, < 3)
- padrino-support (0.13.3.3)
- activesupport (>= 3.1)
- parallel (1.10.0)
- public_suffix (2.0.5)
- rack (2.0.5)
- rb-fsevent (0.9.8)
- rb-inotify (0.9.8)
- ffi (>= 0.5.0)
- redcarpet (3.4.0)
- rouge (2.0.7)
- sass (3.4.23)
- servolux (0.12.0)
+ padrino-support (0.15.2)
+ parallel (1.22.1)
+ parslet (2.0.0)
+ public_suffix (5.0.1)
+ racc (1.6.0)
+ rack (2.2.6.2)
+ rb-fsevent (0.11.2)
+ rb-inotify (0.10.1)
+ ffi (~> 1.0)
+ redcarpet (3.6.0)
+ rexml (3.2.5)
+ rouge (3.30.0)
+ sass (3.7.4)
+ sass-listen (~> 4.0.0)
+ sass-listen (4.0.0)
+ rb-fsevent (~> 0.9, >= 0.9.4)
+ rb-inotify (~> 0.9, >= 0.9.7)
+ sassc (2.4.0)
+ ffi (~> 1.9)
+ servolux (0.13.0)
sprockets (3.7.2)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
- thor (0.19.4)
- thread_safe (0.3.5)
- tilt (2.0.6)
- tzinfo (1.2.2)
- thread_safe (~> 0.1)
- uglifier (3.0.4)
+ temple (0.10.0)
+ thor (1.2.1)
+ tilt (2.0.11)
+ toml (0.3.0)
+ parslet (>= 1.8.0, < 3.0.0)
+ tzinfo (2.0.6)
+ concurrent-ruby (~> 1.0)
+ uglifier (3.2.0)
execjs (>= 0.3.0, < 3)
+ webrick (1.8.1)
+ zeitwerk (2.6.0)
PLATFORMS
ruby
DEPENDENCIES
- middleman (~> 4.2.1)
- middleman-autoprefixer (~> 2.7.0)
- middleman-sprockets (~> 4.1.0)
- middleman-syntax (~> 3.0.0)
- nokogiri (~> 1.8.2)
- redcarpet (~> 3.4.0)
- rouge (~> 2.0.5)
+ middleman (~> 4.4)
+ middleman-autoprefixer (~> 3.0)
+ middleman-sprockets (~> 4.1)
+ middleman-syntax (~> 3.2)
+ nokogiri (~> 1.13.3)
+ redcarpet (~> 3.6.0)
+ rouge (~> 3.21)
+ sass
+ webrick
RUBY VERSION
- ruby 2.3.3p222
+ ruby 2.7.2p137
BUNDLED WITH
- 1.15.4
+ 2.2.22
diff --git a/LICENSE b/LICENSE
index 5ceddf59f68..261eeb9e9f8 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,13 +1,201 @@
-Copyright 2008-2013 Concur Technologies, Inc.
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
-Licensed under the Apache License, Version 2.0 (the "License"); you may
-not use this file except in compliance with the License. You may obtain
-a copy of the License at
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
- http://www.apache.org/licenses/LICENSE-2.0
+ 1. Definitions.
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-License for the specific language governing permissions and limitations
-under the License.
\ No newline at end of file
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/README.md b/README.md
index c9017010ae6..1560f214308 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,15 @@
-
+
-
+
+
Slate helps you create beautiful, intelligent, responsive API documentation.
-
+
-The example above was created with Slate. Check it out at lord.github.io/slate .
+The example above was created with Slate. Check it out at slatedocs.github.io/slate .
Features
------------
@@ -21,7 +22,7 @@ Features
* **Write code samples in multiple languages** — If your API has bindings in multiple programming languages, you can easily put in tabs to switch between them. In your document, you'll distinguish different languages by specifying the language name at the top of each code block, just like with GitHub Flavored Markdown.
-* **Out-of-the-box syntax highlighting** for [over 100 languages](https://github.com/jneen/rouge/wiki/List-of-supported-languages-and-lexers), no configuration required.
+* **Out-of-the-box syntax highlighting** for [over 100 languages](https://github.com/rouge-ruby/rouge/wiki/List-of-supported-languages-and-lexers), no configuration required.
* **Automatic, smoothly scrolling table of contents** on the far left of the page. As you scroll, it displays your current position in the document. It's fast, too. We're using Slate at TripIt to build documentation for our new API, where our table of contents has over 180 entries. We've made sure that the performance remains excellent, even for larger documents.
@@ -29,44 +30,18 @@ Features
* **RTL Support** Full right-to-left layout for RTL languages such as Arabic, Persian (Farsi), Hebrew etc.
-Getting started with Slate is super easy! Simply fork this repository and follow the instructions below. Or, if you'd like to check out what Slate is capable of, take a look at the [sample docs](http://lord.github.io/slate).
+Getting started with Slate is super easy! Simply press the green "use this template" button above and follow the instructions below. Or, if you'd like to check out what Slate is capable of, take a look at the [sample docs](https://slatedocs.github.io/slate/).
Getting Started with Slate
------------------------------
-### Prerequisites
+To get started with Slate, please check out the [Getting Started](https://github.com/slatedocs/slate/wiki#getting-started)
+section in our [wiki](https://github.com/slatedocs/slate/wiki).
-You're going to need:
-
- - **Linux or macOS** — Windows may work, but is unsupported.
- - **Ruby, version 2.3.1 or newer**
- - **Bundler** — If Ruby is already installed, but the `bundle` command doesn't work, just run `gem install bundler` in a terminal.
-
-### Getting Set Up
-
-1. Fork this repository on GitHub.
-2. Clone *your forked repository* (not our original one) to your hard drive with `git clone https://github.com/YOURUSERNAME/slate.git`
-3. `cd slate`
-4. Initialize and start Slate. You can either do this locally, or with Vagrant:
-
-```shell
-# either run this to run locally
-bundle install
-bundle exec middleman server
-
-# OR run this to run with vagrant
-vagrant up
-```
-
-You can now see the docs at http://localhost:4567. Whoa! That was fast!
-
-Now that Slate is all set up on your machine, you'll probably want to learn more about [editing Slate markdown](https://github.com/lord/slate/wiki/Markdown-Syntax), or [how to publish your docs](https://github.com/lord/slate/wiki/Deploying-Slate).
-
-If you'd prefer to use Docker, instructions are available [in the wiki](https://github.com/lord/slate/wiki/Docker).
-
-### Note on JavaScript Runtime
-
-For those who don't have JavaScript runtime or are experiencing JavaScript runtime issues with ExecJS, it is recommended to add the [rubyracer gem](https://github.com/cowboyd/therubyracer) to your gemfile and run `bundle` again.
+We support running Slate in three different ways:
+* [Natively](https://github.com/slatedocs/slate/wiki/Using-Slate-Natively)
+* [Using Vagrant](https://github.com/slatedocs/slate/wiki/Using-Slate-in-Vagrant)
+* [Using Docker](https://github.com/slatedocs/slate/wiki/Using-Slate-in-Docker)
Companies Using Slate
---------------------------------
@@ -76,26 +51,26 @@ Companies Using Slate
* [Best Buy](https://bestbuyapis.github.io/api-documentation/)
* [Travis-CI](https://docs.travis-ci.com/api/)
* [Greenhouse](https://developers.greenhouse.io/harvest.html)
-* [Woocommerce](http://woocommerce.github.io/woocommerce-rest-api-docs/)
+* [WooCommerce](http://woocommerce.github.io/woocommerce-rest-api-docs/)
* [Dwolla](https://docs.dwolla.com/)
* [Clearbit](https://clearbit.com/docs)
* [Coinbase](https://developers.coinbase.com/api)
* [Parrot Drones](http://developer.parrot.com/docs/bebop/)
-* [Scale](https://docs.scaleapi.com/)
+* [CoinAPI](https://docs.coinapi.io/)
-You can view more in [the list on the wiki](https://github.com/lord/slate/wiki/Slate-in-the-Wild).
+You can view more in [the list on the wiki](https://github.com/slatedocs/slate/wiki/Slate-in-the-Wild).
Questions? Need Help? Found a bug?
--------------------
-If you've got questions about setup, deploying, special feature implementation in your fork, or just want to chat with the developer, please feel free to [start a thread in our Spectrum community](https://spectrum.chat/slate)!
+If you've got questions about setup, deploying, special feature implementation in your fork, or just want to chat with the developer, please feel free to [start a thread in our Discussions tab](https://github.com/slatedocs/slate/discussions)!
-Found a bug with upstream Slate? Go ahead and [submit an issue](https://github.com/lord/slate/issues). And, of course, feel free to submit pull requests with bug fixes or changes to the `dev` branch.
+Found a bug with upstream Slate? Go ahead and [submit an issue](https://github.com/slatedocs/slate/issues). And, of course, feel free to submit pull requests with bug fixes or changes to the `dev` branch.
Contributors
--------------------
-Slate was built by [Robert Lord](https://lord.io) while interning at [TripIt](https://www.tripit.com/).
+Slate was built by [Robert Lord](https://lord.io) while at [TripIt](https://www.tripit.com/). The project is now maintained by [Matthew Peveler](https://github.com/MasterOdin) and [Mike Ralphson](https://github.com/MikeRalphson).
Thanks to the following people who have submitted major pull requests:
@@ -105,11 +80,3 @@ Thanks to the following people who have submitted major pull requests:
- [@cvkef](https://github.com/cvkef)
Also, thanks to [Sauce Labs](http://saucelabs.com) for sponsoring the development of the responsive styles.
-
-Special Thanks
---------------------
-- [Middleman](https://github.com/middleman/middleman)
-- [jquery.tocify.js](https://github.com/gfranko/jquery.tocify.js)
-- [middleman-syntax](https://github.com/middleman/middleman-syntax)
-- [middleman-gh-pages](https://github.com/edgecase/middleman-gh-pages)
-- [Font Awesome](http://fortawesome.github.io/Font-Awesome/)
diff --git a/Vagrantfile b/Vagrantfile
index 6f2444e2133..8a9981b8f77 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -1,5 +1,5 @@
Vagrant.configure(2) do |config|
- config.vm.box = "ubuntu/trusty64"
+ config.vm.box = "ubuntu/focal64"
config.vm.network :forwarded_port, guest: 4567, host: 4567
config.vm.provider "virtualbox" do |vb|
vb.memory = "2048"
@@ -8,12 +8,14 @@ Vagrant.configure(2) do |config|
config.vm.provision "bootstrap",
type: "shell",
inline: <<-SHELL
- sudo apt-add-repository ppa:brightbox/ruby-ng
+ # add nodejs v12 repository
+ curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
+
sudo apt-get update
- sudo apt-get install -yq ruby2.4 ruby2.4-dev
+ sudo apt-get install -yq ruby ruby-dev
sudo apt-get install -yq pkg-config build-essential nodejs git libxml2-dev libxslt-dev
sudo apt-get autoremove -yq
- gem2.4 install --no-ri --no-rdoc bundler
+ gem install --no-document bundler
SHELL
# add the local user git config to the vm
@@ -26,6 +28,7 @@ Vagrant.configure(2) do |config|
echo "=============================================="
echo "Installing app dependencies"
cd /vagrant
+ sudo gem install bundler -v "$(grep -A 1 "BUNDLED WITH" Gemfile.lock | tail -n 1)"
bundle config build.nokogiri --use-system-libraries
bundle install
SHELL
diff --git a/config.rb b/config.rb
index 24887979fea..6f8b677f617 100644
--- a/config.rb
+++ b/config.rb
@@ -23,6 +23,7 @@
# Activate the syntax highlighter
activate :syntax
ready do
+ require './lib/monokai_sublime_slate.rb'
require './lib/multilang.rb'
end
@@ -40,12 +41,16 @@
# Build Configuration
configure :build do
+ # We do want to hash woff and woff2 as there's a bug where woff2 will use
+ # woff asset hash which breaks things. Trying to use a combination of ignore and
+ # rewrite_ignore does not work as it conflicts weirdly with relative_assets. Disabling
+ # the .woff2 extension only does not work as .woff will still activate it so have to
+ # have both. See https://github.com/slatedocs/slate/issues/1171 for more details.
+ activate :asset_hash, :exts => app.config[:asset_extensions] - %w[.woff .woff2]
# If you're having trouble with Middleman hanging, commenting
# out the following two lines has been known to help
activate :minify_css
activate :minify_javascript
- # activate :relative_assets
- # activate :asset_hash
# activate :gzip
end
diff --git a/deploy.sh b/deploy.sh
index f122ba7ce62..9dbd7db9c72 100755
--- a/deploy.sh
+++ b/deploy.sh
@@ -36,7 +36,7 @@ parse_args() {
while : ; do
if [[ $1 = "-h" || $1 = "--help" ]]; then
echo "$help_message"
- return 0
+ exit 0
elif [[ $1 = "-v" || $1 = "--verbose" ]]; then
verbose=true
shift
@@ -49,11 +49,22 @@ parse_args() {
elif [[ $1 = "-n" || $1 = "--no-hash" ]]; then
GIT_DEPLOY_APPEND_HASH=false
shift
+ elif [[ $1 = "--source-only" ]]; then
+ source_only=true
+ shift
+ elif [[ $1 = "--push-only" ]]; then
+ push_only=true
+ shift
else
break
fi
done
+ if [ ${source_only} ] && [ ${push_only} ]; then
+ >&2 echo "You can only specify one of --source-only or --push-only"
+ exit 1
+ fi
+
# Set internal option vars from the environment and arg flags. All internal
# vars should be declared here, with sane defaults if applicable.
@@ -73,8 +84,6 @@ parse_args() {
}
main() {
- parse_args "$@"
-
enable_expanded_output
if ! git diff --exit-code --quiet --cached; then
@@ -145,7 +154,7 @@ incremental_deploy() {
0) echo No changes to files in $deploy_directory. Skipping commit.;;
1) commit+push;;
*)
- echo git diff exited with code $diff. Aborting. Staying on branch $deploy_branch so you can debug. To switch back to master, use: git symbolic-ref HEAD refs/heads/master && git reset --mixed >&2
+ echo git diff exited with code $diff. Aborting. Staying on branch $deploy_branch so you can debug. To switch back to main, use: git symbolic-ref HEAD refs/heads/main && git reset --mixed >&2
return $diff
;;
esac
@@ -205,9 +214,11 @@ sanitize() {
"$@" 2> >(filter 1>&2) | filter
}
-if [[ $1 = --source-only ]]; then
+parse_args "$@"
+
+if [[ ${source_only} ]]; then
run_build
-elif [[ $1 = --push-only ]]; then
+elif [[ ${push_only} ]]; then
main "$@"
else
run_build
diff --git a/lib/monokai_sublime_slate.rb b/lib/monokai_sublime_slate.rb
new file mode 100644
index 00000000000..cd2de33172d
--- /dev/null
+++ b/lib/monokai_sublime_slate.rb
@@ -0,0 +1,95 @@
+# -*- coding: utf-8 -*- #
+# frozen_string_literal: true
+
+# this is based on https://github.com/rouge-ruby/rouge/blob/master/lib/rouge/themes/monokai_sublime.rb
+# but without the added background, and changed styling for JSON keys to be soft_yellow instead of white
+
+module Rouge
+ module Themes
+ class MonokaiSublimeSlate < CSSTheme
+ name 'monokai.sublime.slate'
+
+ palette :black => '#000000'
+ palette :bright_green => '#a6e22e'
+ palette :bright_pink => '#f92672'
+ palette :carmine => '#960050'
+ palette :dark => '#49483e'
+ palette :dark_grey => '#888888'
+ palette :dark_red => '#aa0000'
+ palette :dimgrey => '#75715e'
+ palette :emperor => '#555555'
+ palette :grey => '#999999'
+ palette :light_grey => '#aaaaaa'
+ palette :light_violet => '#ae81ff'
+ palette :soft_cyan => '#66d9ef'
+ palette :soft_yellow => '#e6db74'
+ palette :very_dark => '#1e0010'
+ palette :whitish => '#f8f8f2'
+ palette :orange => '#f6aa11'
+ palette :white => '#ffffff'
+
+ style Generic::Heading, :fg => :grey
+ style Literal::String::Regex, :fg => :orange
+ style Generic::Output, :fg => :dark_grey
+ style Generic::Prompt, :fg => :emperor
+ style Generic::Strong, :bold => false
+ style Generic::Subheading, :fg => :light_grey
+ style Name::Builtin, :fg => :orange
+ style Comment::Multiline,
+ Comment::Preproc,
+ Comment::Single,
+ Comment::Special,
+ Comment, :fg => :dimgrey
+ style Error,
+ Generic::Error,
+ Generic::Traceback, :fg => :carmine
+ style Generic::Deleted,
+ Generic::Inserted,
+ Generic::Emph, :fg => :dark
+ style Keyword::Constant,
+ Keyword::Declaration,
+ Keyword::Reserved,
+ Name::Constant,
+ Keyword::Type, :fg => :soft_cyan
+ style Literal::Number::Float,
+ Literal::Number::Hex,
+ Literal::Number::Integer::Long,
+ Literal::Number::Integer,
+ Literal::Number::Oct,
+ Literal::Number,
+ Literal::String::Char,
+ Literal::String::Escape,
+ Literal::String::Symbol, :fg => :light_violet
+ style Literal::String::Doc,
+ Literal::String::Double,
+ Literal::String::Backtick,
+ Literal::String::Heredoc,
+ Literal::String::Interpol,
+ Literal::String::Other,
+ Literal::String::Single,
+ Literal::String, :fg => :soft_yellow
+ style Name::Attribute,
+ Name::Class,
+ Name::Decorator,
+ Name::Exception,
+ Name::Function, :fg => :bright_green
+ style Name::Variable::Class,
+ Name::Namespace,
+ Name::Entity,
+ Name::Builtin::Pseudo,
+ Name::Variable::Global,
+ Name::Variable::Instance,
+ Name::Variable,
+ Text::Whitespace,
+ Text,
+ Name, :fg => :white
+ style Name::Label, :fg => :bright_pink
+ style Operator::Word,
+ Name::Tag,
+ Keyword,
+ Keyword::Namespace,
+ Keyword::Pseudo,
+ Operator, :fg => :bright_pink
+ end
+ end
+ end
diff --git a/slate.sh b/slate.sh
new file mode 100755
index 00000000000..d6f1bd9d5f1
--- /dev/null
+++ b/slate.sh
@@ -0,0 +1,248 @@
+#!/usr/bin/env bash
+set -o errexit #abort if any command fails
+
+me=$(basename "$0")
+
+help_message="\
+Usage: $me [] []
+Run commands related to the slate process.
+
+Commands:
+
+ serve Run the middleman server process, useful for
+ development.
+ build Run the build process.
+ deploy Will build and deploy files to branch. Use
+ --no-build to only deploy.
+
+Global Options:
+
+ -h, --help Show this help information.
+ -v, --verbose Increase verbosity. Useful for debugging.
+
+Deploy options:
+ -e, --allow-empty Allow deployment of an empty directory.
+ -m, --message MESSAGE Specify the message used when committing on the
+ deploy branch.
+ -n, --no-hash Don't append the source commit's hash to the deploy
+ commit's message.
+ --no-build Do not build the source files.
+"
+
+
+run_serve() {
+ exec bundle exec middleman serve --watcher-force-polling
+}
+
+run_build() {
+ bundle exec middleman build --clean --watcher-disable
+}
+
+parse_args() {
+ # Set args from a local environment file.
+ if [ -e ".env" ]; then
+ source .env
+ fi
+
+ command=
+
+ # Parse arg flags
+ # If something is exposed as an environment variable, set/overwrite it
+ # here. Otherwise, set/overwrite the internal variable instead.
+ while : ; do
+ if [[ $1 = "-h" || $1 = "--help" ]]; then
+ echo "$help_message"
+ exit 0
+ elif [[ $1 = "-v" || $1 = "--verbose" ]]; then
+ verbose=true
+ shift
+ elif [[ $1 = "-e" || $1 = "--allow-empty" ]]; then
+ allow_empty=true
+ shift
+ elif [[ ( $1 = "-m" || $1 = "--message" ) && -n $2 ]]; then
+ commit_message=$2
+ shift 2
+ elif [[ $1 = "-n" || $1 = "--no-hash" ]]; then
+ GIT_DEPLOY_APPEND_HASH=false
+ shift
+ elif [[ $1 = "--no-build" ]]; then
+ no_build=true
+ shift
+ elif [[ $1 = "serve" || $1 = "build" || $1 = "deploy" ]]; then
+ if [ ! -z "${command}" ]; then
+ >&2 echo "You can only specify one command."
+ exit 1
+ fi
+ command=$1
+ shift
+ elif [ -z $1 ]; then
+ break
+ fi
+ done
+
+ if [ -z "${command}" ]; then
+ >&2 echo "Command not specified."
+ exit 1
+ fi
+
+ # Set internal option vars from the environment and arg flags. All internal
+ # vars should be declared here, with sane defaults if applicable.
+
+ # Source directory & target branch.
+ deploy_directory=build
+ deploy_branch=gh-pages
+
+ #if no user identity is already set in the current git environment, use this:
+ default_username=${GIT_DEPLOY_USERNAME:-deploy.sh}
+ default_email=${GIT_DEPLOY_EMAIL:-}
+
+ #repository to deploy to. must be readable and writable.
+ repo=origin
+
+ #append commit hash to the end of message by default
+ append_hash=${GIT_DEPLOY_APPEND_HASH:-true}
+}
+
+main() {
+ enable_expanded_output
+
+ if ! git diff --exit-code --quiet --cached; then
+ echo Aborting due to uncommitted changes in the index >&2
+ return 1
+ fi
+
+ commit_title=`git log -n 1 --format="%s" HEAD`
+ commit_hash=` git log -n 1 --format="%H" HEAD`
+
+ #default commit message uses last title if a custom one is not supplied
+ if [[ -z $commit_message ]]; then
+ commit_message="publish: $commit_title"
+ fi
+
+ #append hash to commit message unless no hash flag was found
+ if [ $append_hash = true ]; then
+ commit_message="$commit_message"$'\n\n'"generated from commit $commit_hash"
+ fi
+
+ previous_branch=`git rev-parse --abbrev-ref HEAD`
+
+ if [ ! -d "$deploy_directory" ]; then
+ echo "Deploy directory '$deploy_directory' does not exist. Aborting." >&2
+ return 1
+ fi
+
+ # must use short form of flag in ls for compatibility with macOS and BSD
+ if [[ -z `ls -A "$deploy_directory" 2> /dev/null` && -z $allow_empty ]]; then
+ echo "Deploy directory '$deploy_directory' is empty. Aborting. If you're sure you want to deploy an empty tree, use the --allow-empty / -e flag." >&2
+ return 1
+ fi
+
+ if git ls-remote --exit-code $repo "refs/heads/$deploy_branch" ; then
+ # deploy_branch exists in $repo; make sure we have the latest version
+
+ disable_expanded_output
+ git fetch --force $repo $deploy_branch:$deploy_branch
+ enable_expanded_output
+ fi
+
+ # check if deploy_branch exists locally
+ if git show-ref --verify --quiet "refs/heads/$deploy_branch"
+ then incremental_deploy
+ else initial_deploy
+ fi
+
+ restore_head
+}
+
+initial_deploy() {
+ git --work-tree "$deploy_directory" checkout --orphan $deploy_branch
+ git --work-tree "$deploy_directory" add --all
+ commit+push
+}
+
+incremental_deploy() {
+ #make deploy_branch the current branch
+ git symbolic-ref HEAD refs/heads/$deploy_branch
+ #put the previously committed contents of deploy_branch into the index
+ git --work-tree "$deploy_directory" reset --mixed --quiet
+ git --work-tree "$deploy_directory" add --all
+
+ set +o errexit
+ diff=$(git --work-tree "$deploy_directory" diff --exit-code --quiet HEAD --)$?
+ set -o errexit
+ case $diff in
+ 0) echo No changes to files in $deploy_directory. Skipping commit.;;
+ 1) commit+push;;
+ *)
+ echo git diff exited with code $diff. Aborting. Staying on branch $deploy_branch so you can debug. To switch back to main, use: git symbolic-ref HEAD refs/heads/main && git reset --mixed >&2
+ return $diff
+ ;;
+ esac
+}
+
+commit+push() {
+ set_user_id
+ git --work-tree "$deploy_directory" commit -m "$commit_message"
+
+ disable_expanded_output
+ #--quiet is important here to avoid outputting the repo URL, which may contain a secret token
+ git push --quiet $repo $deploy_branch
+ enable_expanded_output
+}
+
+#echo expanded commands as they are executed (for debugging)
+enable_expanded_output() {
+ if [ $verbose ]; then
+ set -o xtrace
+ set +o verbose
+ fi
+}
+
+#this is used to avoid outputting the repo URL, which may contain a secret token
+disable_expanded_output() {
+ if [ $verbose ]; then
+ set +o xtrace
+ set -o verbose
+ fi
+}
+
+set_user_id() {
+ if [[ -z `git config user.name` ]]; then
+ git config user.name "$default_username"
+ fi
+ if [[ -z `git config user.email` ]]; then
+ git config user.email "$default_email"
+ fi
+}
+
+restore_head() {
+ if [[ $previous_branch = "HEAD" ]]; then
+ #we weren't on any branch before, so just set HEAD back to the commit it was on
+ git update-ref --no-deref HEAD $commit_hash $deploy_branch
+ else
+ git symbolic-ref HEAD refs/heads/$previous_branch
+ fi
+
+ git reset --mixed
+}
+
+filter() {
+ sed -e "s|$repo|\$repo|g"
+}
+
+sanitize() {
+ "$@" 2> >(filter 1>&2) | filter
+}
+
+parse_args "$@"
+
+if [ "${command}" = "serve" ]; then
+ run_serve
+elif [[ "${command}" = "build" ]]; then
+ run_build
+elif [[ ${command} = "deploy" ]]; then
+ if [[ ${no_build} != true ]]; then
+ run_build
+ fi
+ main "$@"
+fi
diff --git a/source/index.html.md b/source/index.html.md
index e101e66ef94..71997cf6555 100644
--- a/source/index.html.md
+++ b/source/index.html.md
@@ -1,7 +1,7 @@
---
title: API Reference
-language_tabs: # must be one of https://git.io/vQNgJ
+language_tabs: # must be one of https://github.com/rouge-ruby/rouge/wiki/List-of-supported-languages-and-lexers
- shell
- ruby
- python
@@ -9,12 +9,18 @@ language_tabs: # must be one of https://git.io/vQNgJ
toc_footers:
- Sign Up for a Developer Key
- - Documentation Powered by Slate
+ - Documentation Powered by Slate
includes:
- errors
search: true
+
+code_clipboard: true
+
+meta:
+ - name: description
+ content: Documentation for the Kittn API
---
# Introduction
@@ -23,7 +29,7 @@ Welcome to the Kittn API! You can use our API to access Kittn API endpoints, whi
We have language bindings in Shell, Ruby, Python, and JavaScript! You can view code examples in the dark area to the right, and you can switch the programming language of the examples with the tabs in the top right.
-This example API documentation page was created with [Slate](https://github.com/lord/slate). Feel free to edit it and use it as a base for your own API's documentation.
+This example API documentation page was created with [Slate](https://github.com/slatedocs/slate). Feel free to edit it and use it as a base for your own API's documentation.
# Authentication
@@ -43,7 +49,7 @@ api = kittn.authorize('meowmeowmeow')
```shell
# With shell, you can just pass the correct header with each request
-curl "api_endpoint_here"
+curl "api_endpoint_here" \
-H "Authorization: meowmeowmeow"
```
@@ -84,7 +90,7 @@ api.kittens.get()
```
```shell
-curl "http://example.com/api/kittens"
+curl "http://example.com/api/kittens" \
-H "Authorization: meowmeowmeow"
```
@@ -150,7 +156,7 @@ api.kittens.get(2)
```
```shell
-curl "http://example.com/api/kittens/2"
+curl "http://example.com/api/kittens/2" \
-H "Authorization: meowmeowmeow"
```
@@ -204,8 +210,8 @@ api.kittens.delete(2)
```
```shell
-curl "http://example.com/api/kittens/2"
- -X DELETE
+curl "http://example.com/api/kittens/2" \
+ -X DELETE \
-H "Authorization: meowmeowmeow"
```
diff --git a/source/javascripts/all_nosearch.js b/source/javascripts/all_nosearch.js
index b18c1d833d4..026e5a20039 100644
--- a/source/javascripts/all_nosearch.js
+++ b/source/javascripts/all_nosearch.js
@@ -1,7 +1,13 @@
//= require ./lib/_energize
+//= require ./app/_copy
//= require ./app/_toc
//= require ./app/_lang
+function adjustLanguageSelectorWidth() {
+ const elem = $('.dark-box > .lang-selector');
+ elem.width(elem.parent().width());
+}
+
$(function() {
loadToc($('#toc'), '.toc-link', '.toc-list-h2', 10);
setupLanguages($('body').data('languages'));
@@ -9,6 +15,11 @@ $(function() {
window.recacheHeights();
window.refreshToc();
});
+
+ $(window).resize(function() {
+ adjustLanguageSelectorWidth();
+ });
+ adjustLanguageSelectorWidth();
});
window.onpopstate = function() {
diff --git a/source/javascripts/app/_copy.js b/source/javascripts/app/_copy.js
new file mode 100644
index 00000000000..4dfbbb6c06d
--- /dev/null
+++ b/source/javascripts/app/_copy.js
@@ -0,0 +1,15 @@
+function copyToClipboard(container) {
+ const el = document.createElement('textarea');
+ el.value = container.textContent.replace(/\n$/, '');
+ document.body.appendChild(el);
+ el.select();
+ document.execCommand('copy');
+ document.body.removeChild(el);
+}
+
+function setupCodeCopy() {
+ $('pre.highlight').prepend('');
+ $('.copy-clipboard').on('click', function() {
+ copyToClipboard(this.parentNode.children[1]);
+ });
+}
diff --git a/source/javascripts/app/_lang.js b/source/javascripts/app/_lang.js
index 0fbaaef7046..c1bd6b2a9b0 100644
--- a/source/javascripts/app/_lang.js
+++ b/source/javascripts/app/_lang.js
@@ -129,20 +129,27 @@ under the License.
history.pushState({}, '', '?' + generateNewQueryString(language) + '#' + hash);
// save language as next default
- localStorage.setItem("language", language);
+ if (localStorage) {
+ localStorage.setItem("language", language);
+ }
}
function setupLanguages(l) {
- var defaultLanguage = localStorage.getItem("language");
+ var defaultLanguage = null;
+ if (localStorage) {
+ defaultLanguage = localStorage.getItem("language");
+ }
languages = l;
var presetLanguage = getLanguageFromQueryString();
- if (presetLanguage) {
+ if (presetLanguage && languages.includes(presetLanguage)) {
// the language is in the URL, so use that language!
activateLanguage(presetLanguage);
- localStorage.setItem("language", presetLanguage);
+ if (localStorage) {
+ localStorage.setItem("language", presetLanguage);
+ }
} else if ((defaultLanguage !== null) && (jQuery.inArray(defaultLanguage, languages) != -1)) {
// the language was the last selected one saved in localstorage, so use that language!
activateLanguage(defaultLanguage);
diff --git a/source/javascripts/app/_search.js b/source/javascripts/app/_search.js
index 9ff4233c18a..0b0ccd97fdd 100644
--- a/source/javascripts/app/_search.js
+++ b/source/javascripts/app/_search.js
@@ -8,32 +8,36 @@
var highlightOpts = { element: 'span', className: 'search-highlight' };
var searchDelay = 0;
var timeoutHandle = 0;
-
- var index = new lunr.Index();
-
- index.ref('id');
- index.field('title', { boost: 10 });
- index.field('body');
- index.pipeline.add(lunr.trimmer, lunr.stopWordFilter);
-
- $(populate);
- $(bind);
+ var index;
function populate() {
- $('h1, h2').each(function() {
- var title = $(this);
- var body = title.nextUntil('h1, h2');
- index.add({
- id: title.prop('id'),
- title: title.text(),
- body: body.text()
+ index = lunr(function(){
+
+ this.ref('id');
+ this.field('title', { boost: 10 });
+ this.field('body');
+ this.pipeline.add(lunr.trimmer, lunr.stopWordFilter);
+ var lunrConfig = this;
+
+ $('h1, h2').each(function() {
+ var title = $(this);
+ var body = title.nextUntil('h1, h2');
+ lunrConfig.add({
+ id: title.prop('id'),
+ title: title.text(),
+ body: body.text()
+ });
});
- });
+ });
determineSearchDelay();
}
+
+ $(populate);
+ $(bind);
+
function determineSearchDelay() {
- if(index.tokenStore.length>5000) {
+ if (index.tokenSet.toArray().length>5000) {
searchDelay = 300;
}
}
@@ -51,7 +55,7 @@
}();
wait(function(){
search(e);
- }, searchDelay );
+ }, searchDelay);
});
}
diff --git a/source/javascripts/app/_toc.js b/source/javascripts/app/_toc.js
index eb20fef93f2..f70bdc0ff44 100644
--- a/source/javascripts/app/_toc.js
+++ b/source/javascripts/app/_toc.js
@@ -38,7 +38,7 @@
$toc.find(tocLinkSelector).each(function() {
var targetId = $(this).attr('href');
if (targetId[0] === "#") {
- headerHeights[targetId] = $(targetId).offset().top;
+ headerHeights[targetId] = $("#" + $.escapeSelector(targetId.substring(1))).offset().top;
}
});
};
@@ -80,9 +80,9 @@
if (window.history.replaceState) {
window.history.replaceState(null, "", best);
}
- var thisTitle = $best.data("title")
+ var thisTitle = $best.data("title");
if (thisTitle !== undefined && thisTitle.length > 0) {
- document.title = thisTitle + " – " + originalTitle;
+ document.title = thisTitle.replace(htmlPattern, "") + " – " + originalTitle;
} else {
document.title = originalTitle;
}
diff --git a/source/javascripts/lib/_imagesloaded.min.js b/source/javascripts/lib/_imagesloaded.min.js
index d66f658937d..e443a77d627 100644
--- a/source/javascripts/lib/_imagesloaded.min.js
+++ b/source/javascripts/lib/_imagesloaded.min.js
@@ -1,7 +1,7 @@
/*!
- * imagesLoaded PACKAGED v3.1.8
+ * imagesLoaded PACKAGED v4.1.4
* JavaScript is all like "You images are done yet or what?"
* MIT License
*/
-(function(){function e(){}function t(e,t){for(var n=e.length;n--;)if(e[n].listener===t)return n;return-1}function n(e){return function(){return this[e].apply(this,arguments)}}var i=e.prototype,r=this,o=r.EventEmitter;i.getListeners=function(e){var t,n,i=this._getEvents();if("object"==typeof e){t={};for(n in i)i.hasOwnProperty(n)&&e.test(n)&&(t[n]=i[n])}else t=i[e]||(i[e]=[]);return t},i.flattenListeners=function(e){var t,n=[];for(t=0;e.length>t;t+=1)n.push(e[t].listener);return n},i.getListenersAsObject=function(e){var t,n=this.getListeners(e);return n instanceof Array&&(t={},t[e]=n),t||n},i.addListener=function(e,n){var i,r=this.getListenersAsObject(e),o="object"==typeof n;for(i in r)r.hasOwnProperty(i)&&-1===t(r[i],n)&&r[i].push(o?n:{listener:n,once:!1});return this},i.on=n("addListener"),i.addOnceListener=function(e,t){return this.addListener(e,{listener:t,once:!0})},i.once=n("addOnceListener"),i.defineEvent=function(e){return this.getListeners(e),this},i.defineEvents=function(e){for(var t=0;e.length>t;t+=1)this.defineEvent(e[t]);return this},i.removeListener=function(e,n){var i,r,o=this.getListenersAsObject(e);for(r in o)o.hasOwnProperty(r)&&(i=t(o[r],n),-1!==i&&o[r].splice(i,1));return this},i.off=n("removeListener"),i.addListeners=function(e,t){return this.manipulateListeners(!1,e,t)},i.removeListeners=function(e,t){return this.manipulateListeners(!0,e,t)},i.manipulateListeners=function(e,t,n){var i,r,o=e?this.removeListener:this.addListener,s=e?this.removeListeners:this.addListeners;if("object"!=typeof t||t instanceof RegExp)for(i=n.length;i--;)o.call(this,t,n[i]);else for(i in t)t.hasOwnProperty(i)&&(r=t[i])&&("function"==typeof r?o.call(this,i,r):s.call(this,i,r));return this},i.removeEvent=function(e){var t,n=typeof e,i=this._getEvents();if("string"===n)delete i[e];else if("object"===n)for(t in i)i.hasOwnProperty(t)&&e.test(t)&&delete i[t];else delete this._events;return this},i.removeAllListeners=n("removeEvent"),i.emitEvent=function(e,t){var n,i,r,o,s=this.getListenersAsObject(e);for(r in s)if(s.hasOwnProperty(r))for(i=s[r].length;i--;)n=s[r][i],n.once===!0&&this.removeListener(e,n.listener),o=n.listener.apply(this,t||[]),o===this._getOnceReturnValue()&&this.removeListener(e,n.listener);return this},i.trigger=n("emitEvent"),i.emit=function(e){var t=Array.prototype.slice.call(arguments,1);return this.emitEvent(e,t)},i.setOnceReturnValue=function(e){return this._onceReturnValue=e,this},i._getOnceReturnValue=function(){return this.hasOwnProperty("_onceReturnValue")?this._onceReturnValue:!0},i._getEvents=function(){return this._events||(this._events={})},e.noConflict=function(){return r.EventEmitter=o,e},"function"==typeof define&&define.amd?define("eventEmitter/EventEmitter",[],function(){return e}):"object"==typeof module&&module.exports?module.exports=e:this.EventEmitter=e}).call(this),function(e){function t(t){var n=e.event;return n.target=n.target||n.srcElement||t,n}var n=document.documentElement,i=function(){};n.addEventListener?i=function(e,t,n){e.addEventListener(t,n,!1)}:n.attachEvent&&(i=function(e,n,i){e[n+i]=i.handleEvent?function(){var n=t(e);i.handleEvent.call(i,n)}:function(){var n=t(e);i.call(e,n)},e.attachEvent("on"+n,e[n+i])});var r=function(){};n.removeEventListener?r=function(e,t,n){e.removeEventListener(t,n,!1)}:n.detachEvent&&(r=function(e,t,n){e.detachEvent("on"+t,e[t+n]);try{delete e[t+n]}catch(i){e[t+n]=void 0}});var o={bind:i,unbind:r};"function"==typeof define&&define.amd?define("eventie/eventie",o):e.eventie=o}(this),function(e,t){"function"==typeof define&&define.amd?define(["eventEmitter/EventEmitter","eventie/eventie"],function(n,i){return t(e,n,i)}):"object"==typeof exports?module.exports=t(e,require("wolfy87-eventemitter"),require("eventie")):e.imagesLoaded=t(e,e.EventEmitter,e.eventie)}(window,function(e,t,n){function i(e,t){for(var n in t)e[n]=t[n];return e}function r(e){return"[object Array]"===d.call(e)}function o(e){var t=[];if(r(e))t=e;else if("number"==typeof e.length)for(var n=0,i=e.length;i>n;n++)t.push(e[n]);else t.push(e);return t}function s(e,t,n){if(!(this instanceof s))return new s(e,t);"string"==typeof e&&(e=document.querySelectorAll(e)),this.elements=o(e),this.options=i({},this.options),"function"==typeof t?n=t:i(this.options,t),n&&this.on("always",n),this.getImages(),a&&(this.jqDeferred=new a.Deferred);var r=this;setTimeout(function(){r.check()})}function f(e){this.img=e}function c(e){this.src=e,v[e]=this}var a=e.jQuery,u=e.console,h=u!==void 0,d=Object.prototype.toString;s.prototype=new t,s.prototype.options={},s.prototype.getImages=function(){this.images=[];for(var e=0,t=this.elements.length;t>e;e++){var n=this.elements[e];"IMG"===n.nodeName&&this.addImage(n);var i=n.nodeType;if(i&&(1===i||9===i||11===i))for(var r=n.querySelectorAll("img"),o=0,s=r.length;s>o;o++){var f=r[o];this.addImage(f)}}},s.prototype.addImage=function(e){var t=new f(e);this.images.push(t)},s.prototype.check=function(){function e(e,r){return t.options.debug&&h&&u.log("confirm",e,r),t.progress(e),n++,n===i&&t.complete(),!0}var t=this,n=0,i=this.images.length;if(this.hasAnyBroken=!1,!i)return this.complete(),void 0;for(var r=0;i>r;r++){var o=this.images[r];o.on("confirm",e),o.check()}},s.prototype.progress=function(e){this.hasAnyBroken=this.hasAnyBroken||!e.isLoaded;var t=this;setTimeout(function(){t.emit("progress",t,e),t.jqDeferred&&t.jqDeferred.notify&&t.jqDeferred.notify(t,e)})},s.prototype.complete=function(){var e=this.hasAnyBroken?"fail":"done";this.isComplete=!0;var t=this;setTimeout(function(){if(t.emit(e,t),t.emit("always",t),t.jqDeferred){var n=t.hasAnyBroken?"reject":"resolve";t.jqDeferred[n](t)}})},a&&(a.fn.imagesLoaded=function(e,t){var n=new s(this,e,t);return n.jqDeferred.promise(a(this))}),f.prototype=new t,f.prototype.check=function(){var e=v[this.img.src]||new c(this.img.src);if(e.isConfirmed)return this.confirm(e.isLoaded,"cached was confirmed"),void 0;if(this.img.complete&&void 0!==this.img.naturalWidth)return this.confirm(0!==this.img.naturalWidth,"naturalWidth"),void 0;var t=this;e.on("confirm",function(e,n){return t.confirm(e.isLoaded,n),!0}),e.check()},f.prototype.confirm=function(e,t){this.isLoaded=e,this.emit("confirm",this,t)};var v={};return c.prototype=new t,c.prototype.check=function(){if(!this.isChecked){var e=new Image;n.bind(e,"load",this),n.bind(e,"error",this),e.src=this.src,this.isChecked=!0}},c.prototype.handleEvent=function(e){var t="on"+e.type;this[t]&&this[t](e)},c.prototype.onload=function(e){this.confirm(!0,"onload"),this.unbindProxyEvents(e)},c.prototype.onerror=function(e){this.confirm(!1,"onerror"),this.unbindProxyEvents(e)},c.prototype.confirm=function(e,t){this.isConfirmed=!0,this.isLoaded=e,this.emit("confirm",this,t)},c.prototype.unbindProxyEvents=function(e){n.unbind(e.target,"load",this),n.unbind(e.target,"error",this)},s});
\ No newline at end of file
+!function(e,t){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",t):"object"==typeof module&&module.exports?module.exports=t():e.EvEmitter=t()}("undefined"!=typeof window?window:this,function(){function e(){}var t=e.prototype;return t.on=function(e,t){if(e&&t){var i=this._events=this._events||{},n=i[e]=i[e]||[];return n.indexOf(t)==-1&&n.push(t),this}},t.once=function(e,t){if(e&&t){this.on(e,t);var i=this._onceEvents=this._onceEvents||{},n=i[e]=i[e]||{};return n[t]=!0,this}},t.off=function(e,t){var i=this._events&&this._events[e];if(i&&i.length){var n=i.indexOf(t);return n!=-1&&i.splice(n,1),this}},t.emitEvent=function(e,t){var i=this._events&&this._events[e];if(i&&i.length){i=i.slice(0),t=t||[];for(var n=this._onceEvents&&this._onceEvents[e],o=0;o elements
+ // (i.e., `typeof document.createElement( "object" ) === "function"`).
+ // We don't want to classify *any* DOM node as a function.
+ // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5
+ // Plus for old WebKit, typeof returns "function" for HTML collections
+ // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756)
+ return typeof obj === "function" && typeof obj.nodeType !== "number" &&
+ typeof obj.item !== "function";
+ };
+
+
+var isWindow = function isWindow( obj ) {
+ return obj != null && obj === obj.window;
+ };
+
+
+var document = window.document;
+
+
+ var preservedScriptAttributes = {
+ type: true,
+ src: true,
+ nonce: true,
+ noModule: true
+ };
- function DOMEval( code, doc ) {
+ function DOMEval( code, node, doc ) {
doc = doc || document;
- var script = doc.createElement( "script" );
+ var i, val,
+ script = doc.createElement( "script" );
script.text = code;
+ if ( node ) {
+ for ( i in preservedScriptAttributes ) {
+
+ // Support: Firefox 64+, Edge 18+
+ // Some browsers don't support the "nonce" property on scripts.
+ // On the other hand, just using `getAttribute` is not enough as
+ // the `nonce` attribute is reset to an empty string whenever it
+ // becomes browsing-context connected.
+ // See https://github.com/whatwg/html/issues/2369
+ // See https://html.spec.whatwg.org/#nonce-attributes
+ // The `node.getAttribute` check was added for the sake of
+ // `jQuery.globalEval` so that it can fake a nonce-containing node
+ // via an object.
+ val = node[ i ] || node.getAttribute && node.getAttribute( i );
+ if ( val ) {
+ script.setAttribute( i, val );
+ }
+ }
+ }
doc.head.appendChild( script ).parentNode.removeChild( script );
}
+
+
+function toType( obj ) {
+ if ( obj == null ) {
+ return obj + "";
+ }
+
+ // Support: Android <=2.3 only (functionish RegExp)
+ return typeof obj === "object" || typeof obj === "function" ?
+ class2type[ toString.call( obj ) ] || "object" :
+ typeof obj;
+}
/* global Symbol */
// Defining this global in .eslintrc.json would create a danger of using the global
// unguarded in another place, it seems safer to define global only for this module
@@ -88,7 +151,7 @@ var support = {};
var
- version = "3.2.1",
+ version = "3.6.0",
// Define a local copy of jQuery
jQuery = function( selector, context ) {
@@ -96,19 +159,6 @@ var
// The jQuery object is actually just the init constructor 'enhanced'
// Need init if jQuery is called (just allow error to be thrown if not included)
return new jQuery.fn.init( selector, context );
- },
-
- // Support: Android <=4.0 only
- // Make sure we trim BOM and NBSP
- rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
-
- // Matches dashed string for camelizing
- rmsPrefix = /^-ms-/,
- rdashAlpha = /-([a-z])/g,
-
- // Used by jQuery.camelCase as callback to replace()
- fcamelCase = function( all, letter ) {
- return letter.toUpperCase();
};
jQuery.fn = jQuery.prototype = {
@@ -175,6 +225,18 @@ jQuery.fn = jQuery.prototype = {
return this.eq( -1 );
},
+ even: function() {
+ return this.pushStack( jQuery.grep( this, function( _elem, i ) {
+ return ( i + 1 ) % 2;
+ } ) );
+ },
+
+ odd: function() {
+ return this.pushStack( jQuery.grep( this, function( _elem, i ) {
+ return i % 2;
+ } ) );
+ },
+
eq: function( i ) {
var len = this.length,
j = +i + ( i < 0 ? len : 0 );
@@ -209,7 +271,7 @@ jQuery.extend = jQuery.fn.extend = function() {
}
// Handle case when target is a string or something (possible in deep copy)
- if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
+ if ( typeof target !== "object" && !isFunction( target ) ) {
target = {};
}
@@ -226,25 +288,28 @@ jQuery.extend = jQuery.fn.extend = function() {
// Extend the base object
for ( name in options ) {
- src = target[ name ];
copy = options[ name ];
+ // Prevent Object.prototype pollution
// Prevent never-ending loop
- if ( target === copy ) {
+ if ( name === "__proto__" || target === copy ) {
continue;
}
// Recurse if we're merging plain objects or arrays
if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
( copyIsArray = Array.isArray( copy ) ) ) ) {
+ src = target[ name ];
- if ( copyIsArray ) {
- copyIsArray = false;
- clone = src && Array.isArray( src ) ? src : [];
-
+ // Ensure proper type for the source value
+ if ( copyIsArray && !Array.isArray( src ) ) {
+ clone = [];
+ } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {
+ clone = {};
} else {
- clone = src && jQuery.isPlainObject( src ) ? src : {};
+ clone = src;
}
+ copyIsArray = false;
// Never move original objects, clone them
target[ name ] = jQuery.extend( deep, clone, copy );
@@ -275,28 +340,6 @@ jQuery.extend( {
noop: function() {},
- isFunction: function( obj ) {
- return jQuery.type( obj ) === "function";
- },
-
- isWindow: function( obj ) {
- return obj != null && obj === obj.window;
- },
-
- isNumeric: function( obj ) {
-
- // As of jQuery 3.0, isNumeric is limited to
- // strings and numbers (primitives or objects)
- // that can be coerced to finite numbers (gh-2662)
- var type = jQuery.type( obj );
- return ( type === "number" || type === "string" ) &&
-
- // parseFloat NaNs numeric-cast false positives ("")
- // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
- // subtraction forces infinities to NaN
- !isNaN( obj - parseFloat( obj ) );
- },
-
isPlainObject: function( obj ) {
var proto, Ctor;
@@ -319,9 +362,6 @@ jQuery.extend( {
},
isEmptyObject: function( obj ) {
-
- /* eslint-disable no-unused-vars */
- // See https://github.com/eslint/eslint/issues/6125
var name;
for ( name in obj ) {
@@ -330,27 +370,10 @@ jQuery.extend( {
return true;
},
- type: function( obj ) {
- if ( obj == null ) {
- return obj + "";
- }
-
- // Support: Android <=2.3 only (functionish RegExp)
- return typeof obj === "object" || typeof obj === "function" ?
- class2type[ toString.call( obj ) ] || "object" :
- typeof obj;
- },
-
- // Evaluates a script in a global context
- globalEval: function( code ) {
- DOMEval( code );
- },
-
- // Convert dashed to camelCase; used by the css and data modules
- // Support: IE <=9 - 11, Edge 12 - 13
- // Microsoft forgot to hump their vendor prefix (#9572)
- camelCase: function( string ) {
- return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+ // Evaluates a script in a provided context; falls back to the global one
+ // if not specified.
+ globalEval: function( code, options, doc ) {
+ DOMEval( code, { nonce: options && options.nonce }, doc );
},
each: function( obj, callback ) {
@@ -374,13 +397,6 @@ jQuery.extend( {
return obj;
},
- // Support: Android <=4.0 only
- trim: function( text ) {
- return text == null ?
- "" :
- ( text + "" ).replace( rtrim, "" );
- },
-
// results is for internal usage only
makeArray: function( arr, results ) {
var ret = results || [];
@@ -389,7 +405,7 @@ jQuery.extend( {
if ( isArrayLike( Object( arr ) ) ) {
jQuery.merge( ret,
typeof arr === "string" ?
- [ arr ] : arr
+ [ arr ] : arr
);
} else {
push.call( ret, arr );
@@ -467,43 +483,12 @@ jQuery.extend( {
}
// Flatten any nested arrays
- return concat.apply( [], ret );
+ return flat( ret );
},
// A global GUID counter for objects
guid: 1,
- // Bind a function to a context, optionally partially applying any
- // arguments.
- proxy: function( fn, context ) {
- var tmp, args, proxy;
-
- if ( typeof context === "string" ) {
- tmp = fn[ context ];
- context = fn;
- fn = tmp;
- }
-
- // Quick check to determine if target is callable, in the spec
- // this throws a TypeError, but we will just return undefined.
- if ( !jQuery.isFunction( fn ) ) {
- return undefined;
- }
-
- // Simulated bind
- args = slice.call( arguments, 2 );
- proxy = function() {
- return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
- };
-
- // Set the guid of unique handler to the same of original handler, so it can be removed
- proxy.guid = fn.guid = fn.guid || jQuery.guid++;
-
- return proxy;
- },
-
- now: Date.now,
-
// jQuery.support is not used in Core but other projects attach their
// properties to it so it needs to exist.
support: support
@@ -515,9 +500,9 @@ if ( typeof Symbol === "function" ) {
// Populate the class2type map
jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
-function( i, name ) {
- class2type[ "[object " + name + "]" ] = name.toLowerCase();
-} );
+ function( _i, name ) {
+ class2type[ "[object " + name + "]" ] = name.toLowerCase();
+ } );
function isArrayLike( obj ) {
@@ -526,9 +511,9 @@ function isArrayLike( obj ) {
// hasOwn isn't used here due to false negatives
// regarding Nodelist length in IE
var length = !!obj && "length" in obj && obj.length,
- type = jQuery.type( obj );
+ type = toType( obj );
- if ( type === "function" || jQuery.isWindow( obj ) ) {
+ if ( isFunction( obj ) || isWindow( obj ) ) {
return false;
}
@@ -537,17 +522,16 @@ function isArrayLike( obj ) {
}
var Sizzle =
/*!
- * Sizzle CSS Selector Engine v2.3.3
+ * Sizzle CSS Selector Engine v2.3.6
* https://sizzlejs.com/
*
- * Copyright jQuery Foundation and other contributors
+ * Copyright JS Foundation and other contributors
* Released under the MIT license
- * http://jquery.org/license
+ * https://js.foundation/
*
- * Date: 2016-08-08
+ * Date: 2021-02-16
*/
-(function( window ) {
-
+( function( window ) {
var i,
support,
Expr,
@@ -578,6 +562,7 @@ var i,
classCache = createCache(),
tokenCache = createCache(),
compilerCache = createCache(),
+ nonnativeSelectorCache = createCache(),
sortOrder = function( a, b ) {
if ( a === b ) {
hasDuplicate = true;
@@ -586,61 +571,71 @@ var i,
},
// Instance methods
- hasOwn = ({}).hasOwnProperty,
+ hasOwn = ( {} ).hasOwnProperty,
arr = [],
pop = arr.pop,
- push_native = arr.push,
+ pushNative = arr.push,
push = arr.push,
slice = arr.slice,
+
// Use a stripped-down indexOf as it's faster than native
// https://jsperf.com/thor-indexof-vs-for/5
indexOf = function( list, elem ) {
var i = 0,
len = list.length;
for ( ; i < len; i++ ) {
- if ( list[i] === elem ) {
+ if ( list[ i ] === elem ) {
return i;
}
}
return -1;
},
- booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
+ booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" +
+ "ismap|loop|multiple|open|readonly|required|scoped",
// Regular expressions
// http://www.w3.org/TR/css3-selectors/#whitespace
whitespace = "[\\x20\\t\\r\\n\\f]",
- // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
- identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
+ // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
+ identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace +
+ "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",
// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
+
// Operator (capture 2)
"*([*^$|!~]?=)" + whitespace +
- // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
- "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
- "*\\]",
+
+ // "Attribute values must be CSS identifiers [capture 5]
+ // or strings [capture 3 or capture 4]"
+ "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" +
+ whitespace + "*\\]",
pseudos = ":(" + identifier + ")(?:\\((" +
+
// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
// 1. quoted (capture 3; capture 4 or capture 5)
"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
+
// 2. simple (capture 6)
"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
+
// 3. anything else (capture 2)
".*" +
")\\)|)",
// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
rwhitespace = new RegExp( whitespace + "+", "g" ),
- rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
+ rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" +
+ whitespace + "+$", "g" ),
rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
- rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
-
- rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
+ rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace +
+ "*" ),
+ rdescend = new RegExp( whitespace + "|>" ),
rpseudo = new RegExp( pseudos ),
ridentifier = new RegExp( "^" + identifier + "$" ),
@@ -651,16 +646,19 @@ var i,
"TAG": new RegExp( "^(" + identifier + "|[*])" ),
"ATTR": new RegExp( "^" + attributes ),
"PSEUDO": new RegExp( "^" + pseudos ),
- "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
- "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
- "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+ "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" +
+ whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" +
+ whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
+
// For use in libraries implementing .is()
// We use this for POS matching in `select`
- "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
- whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
+ "needsContext": new RegExp( "^" + whitespace +
+ "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
+ "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
},
+ rhtml = /HTML$/i,
rinputs = /^(?:input|select|textarea|button)$/i,
rheader = /^h\d$/i,
@@ -673,18 +671,21 @@ var i,
// CSS escapes
// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
- runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
- funescape = function( _, escaped, escapedWhitespace ) {
- var high = "0x" + escaped - 0x10000;
- // NaN means non-codepoint
- // Support: Firefox<24
- // Workaround erroneous numeric interpretation of +"0x"
- return high !== high || escapedWhitespace ?
- escaped :
+ runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ),
+ funescape = function( escape, nonHex ) {
+ var high = "0x" + escape.slice( 1 ) - 0x10000;
+
+ return nonHex ?
+
+ // Strip the backslash prefix from a non-hex escape sequence
+ nonHex :
+
+ // Replace a hexadecimal escape sequence with the encoded Unicode code point
+ // Support: IE <=11+
+ // For values outside the Basic Multilingual Plane (BMP), manually construct a
+ // surrogate pair
high < 0 ?
- // BMP codepoint
String.fromCharCode( high + 0x10000 ) :
- // Supplemental Plane codepoint (surrogate pair)
String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
},
@@ -700,7 +701,8 @@ var i,
}
// Control characters and (dependent upon position) numbers get escaped as code points
- return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
+ return ch.slice( 0, -1 ) + "\\" +
+ ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
}
// Other potentially-special ASCII characters get backslash-escaped
@@ -715,9 +717,9 @@ var i,
setDocument();
},
- disabledAncestor = addCombinator(
+ inDisabledFieldset = addCombinator(
function( elem ) {
- return elem.disabled === true && ("form" in elem || "label" in elem);
+ return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset";
},
{ dir: "parentNode", next: "legend" }
);
@@ -725,18 +727,20 @@ var i,
// Optimize for push.apply( _, NodeList )
try {
push.apply(
- (arr = slice.call( preferredDoc.childNodes )),
+ ( arr = slice.call( preferredDoc.childNodes ) ),
preferredDoc.childNodes
);
+
// Support: Android<4.0
// Detect silently failing push.apply
+ // eslint-disable-next-line no-unused-expressions
arr[ preferredDoc.childNodes.length ].nodeType;
} catch ( e ) {
push = { apply: arr.length ?
// Leverage slice if possible
function( target, els ) {
- push_native.apply( target, slice.call(els) );
+ pushNative.apply( target, slice.call( els ) );
} :
// Support: IE<9
@@ -744,8 +748,9 @@ try {
function( target, els ) {
var j = target.length,
i = 0;
+
// Can't trust NodeList.length
- while ( (target[j++] = els[i++]) ) {}
+ while ( ( target[ j++ ] = els[ i++ ] ) ) {}
target.length = j - 1;
}
};
@@ -769,24 +774,21 @@ function Sizzle( selector, context, results, seed ) {
// Try to shortcut find operations (as opposed to filters) in HTML documents
if ( !seed ) {
-
- if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
- setDocument( context );
- }
+ setDocument( context );
context = context || document;
if ( documentIsHTML ) {
// If the selector is sufficiently simple, try using a "get*By*" DOM method
// (excepting DocumentFragment context, where the methods don't exist)
- if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
+ if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {
// ID selector
- if ( (m = match[1]) ) {
+ if ( ( m = match[ 1 ] ) ) {
// Document context
if ( nodeType === 9 ) {
- if ( (elem = context.getElementById( m )) ) {
+ if ( ( elem = context.getElementById( m ) ) ) {
// Support: IE, Opera, Webkit
// TODO: identify versions
@@ -805,7 +807,7 @@ function Sizzle( selector, context, results, seed ) {
// Support: IE, Opera, Webkit
// TODO: identify versions
// getElementById can match elements by name instead of ID
- if ( newContext && (elem = newContext.getElementById( m )) &&
+ if ( newContext && ( elem = newContext.getElementById( m ) ) &&
contains( context, elem ) &&
elem.id === m ) {
@@ -815,12 +817,12 @@ function Sizzle( selector, context, results, seed ) {
}
// Type selector
- } else if ( match[2] ) {
+ } else if ( match[ 2 ] ) {
push.apply( results, context.getElementsByTagName( selector ) );
return results;
// Class selector
- } else if ( (m = match[3]) && support.getElementsByClassName &&
+ } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName &&
context.getElementsByClassName ) {
push.apply( results, context.getElementsByClassName( m ) );
@@ -830,50 +832,62 @@ function Sizzle( selector, context, results, seed ) {
// Take advantage of querySelectorAll
if ( support.qsa &&
- !compilerCache[ selector + " " ] &&
- (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
-
- if ( nodeType !== 1 ) {
- newContext = context;
- newSelector = selector;
+ !nonnativeSelectorCache[ selector + " " ] &&
+ ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) &&
- // qSA looks outside Element context, which is not what we want
- // Thanks to Andrew Dupont for this workaround technique
- // Support: IE <=8
+ // Support: IE 8 only
// Exclude object elements
- } else if ( context.nodeName.toLowerCase() !== "object" ) {
+ ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) {
- // Capture the context ID, setting it first if necessary
- if ( (nid = context.getAttribute( "id" )) ) {
- nid = nid.replace( rcssescape, fcssescape );
- } else {
- context.setAttribute( "id", (nid = expando) );
+ newSelector = selector;
+ newContext = context;
+
+ // qSA considers elements outside a scoping root when evaluating child or
+ // descendant combinators, which is not what we want.
+ // In such cases, we work around the behavior by prefixing every selector in the
+ // list with an ID selector referencing the scope context.
+ // The technique has to be used as well when a leading combinator is used
+ // as such selectors are not recognized by querySelectorAll.
+ // Thanks to Andrew Dupont for this technique.
+ if ( nodeType === 1 &&
+ ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) {
+
+ // Expand context for sibling selectors
+ newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
+ context;
+
+ // We can use :scope instead of the ID hack if the browser
+ // supports it & if we're not changing the context.
+ if ( newContext !== context || !support.scope ) {
+
+ // Capture the context ID, setting it first if necessary
+ if ( ( nid = context.getAttribute( "id" ) ) ) {
+ nid = nid.replace( rcssescape, fcssescape );
+ } else {
+ context.setAttribute( "id", ( nid = expando ) );
+ }
}
// Prefix every selector in the list
groups = tokenize( selector );
i = groups.length;
while ( i-- ) {
- groups[i] = "#" + nid + " " + toSelector( groups[i] );
+ groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " +
+ toSelector( groups[ i ] );
}
newSelector = groups.join( "," );
-
- // Expand context for sibling selectors
- newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
- context;
}
- if ( newSelector ) {
- try {
- push.apply( results,
- newContext.querySelectorAll( newSelector )
- );
- return results;
- } catch ( qsaError ) {
- } finally {
- if ( nid === expando ) {
- context.removeAttribute( "id" );
- }
+ try {
+ push.apply( results,
+ newContext.querySelectorAll( newSelector )
+ );
+ return results;
+ } catch ( qsaError ) {
+ nonnativeSelectorCache( selector, true );
+ } finally {
+ if ( nid === expando ) {
+ context.removeAttribute( "id" );
}
}
}
@@ -894,12 +908,14 @@ function createCache() {
var keys = [];
function cache( key, value ) {
+
// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
if ( keys.push( key + " " ) > Expr.cacheLength ) {
+
// Only keep the most recent entries
delete cache[ keys.shift() ];
}
- return (cache[ key + " " ] = value);
+ return ( cache[ key + " " ] = value );
}
return cache;
}
@@ -918,17 +934,19 @@ function markFunction( fn ) {
* @param {Function} fn Passed the created element and returns a boolean result
*/
function assert( fn ) {
- var el = document.createElement("fieldset");
+ var el = document.createElement( "fieldset" );
try {
return !!fn( el );
- } catch (e) {
+ } catch ( e ) {
return false;
} finally {
+
// Remove from its parent by default
if ( el.parentNode ) {
el.parentNode.removeChild( el );
}
+
// release memory in IE
el = null;
}
@@ -940,11 +958,11 @@ function assert( fn ) {
* @param {Function} handler The method that will be applied
*/
function addHandle( attrs, handler ) {
- var arr = attrs.split("|"),
+ var arr = attrs.split( "|" ),
i = arr.length;
while ( i-- ) {
- Expr.attrHandle[ arr[i] ] = handler;
+ Expr.attrHandle[ arr[ i ] ] = handler;
}
}
@@ -966,7 +984,7 @@ function siblingCheck( a, b ) {
// Check if b follows a
if ( cur ) {
- while ( (cur = cur.nextSibling) ) {
+ while ( ( cur = cur.nextSibling ) ) {
if ( cur === b ) {
return -1;
}
@@ -994,7 +1012,7 @@ function createInputPseudo( type ) {
function createButtonPseudo( type ) {
return function( elem ) {
var name = elem.nodeName.toLowerCase();
- return (name === "input" || name === "button") && elem.type === type;
+ return ( name === "input" || name === "button" ) && elem.type === type;
};
}
@@ -1037,7 +1055,7 @@ function createDisabledPseudo( disabled ) {
// Where there is no isDisabled, check manually
/* jshint -W018 */
elem.isDisabled !== !disabled &&
- disabledAncestor( elem ) === disabled;
+ inDisabledFieldset( elem ) === disabled;
}
return elem.disabled === disabled;
@@ -1059,21 +1077,21 @@ function createDisabledPseudo( disabled ) {
* @param {Function} fn
*/
function createPositionalPseudo( fn ) {
- return markFunction(function( argument ) {
+ return markFunction( function( argument ) {
argument = +argument;
- return markFunction(function( seed, matches ) {
+ return markFunction( function( seed, matches ) {
var j,
matchIndexes = fn( [], seed.length, argument ),
i = matchIndexes.length;
// Match elements found at the specified indexes
while ( i-- ) {
- if ( seed[ (j = matchIndexes[i]) ] ) {
- seed[j] = !(matches[j] = seed[j]);
+ if ( seed[ ( j = matchIndexes[ i ] ) ] ) {
+ seed[ j ] = !( matches[ j ] = seed[ j ] );
}
}
- });
- });
+ } );
+ } );
}
/**
@@ -1094,10 +1112,13 @@ support = Sizzle.support = {};
* @returns {Boolean} True iff elem is a non-HTML XML node
*/
isXML = Sizzle.isXML = function( elem ) {
- // documentElement is verified for cases where it doesn't yet exist
- // (such as loading iframes in IE - #4833)
- var documentElement = elem && (elem.ownerDocument || elem).documentElement;
- return documentElement ? documentElement.nodeName !== "HTML" : false;
+ var namespace = elem && elem.namespaceURI,
+ docElem = elem && ( elem.ownerDocument || elem ).documentElement;
+
+ // Support: IE <=8
+ // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes
+ // https://bugs.jquery.com/ticket/4833
+ return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" );
};
/**
@@ -1110,7 +1131,11 @@ setDocument = Sizzle.setDocument = function( node ) {
doc = node ? node.ownerDocument || node : preferredDoc;
// Return early if doc is invalid or already selected
- if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {
return document;
}
@@ -1119,10 +1144,14 @@ setDocument = Sizzle.setDocument = function( node ) {
docElem = document.documentElement;
documentIsHTML = !isXML( document );
- // Support: IE 9-11, Edge
+ // Support: IE 9 - 11+, Edge 12 - 18+
// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
- if ( preferredDoc !== document &&
- (subWindow = document.defaultView) && subWindow.top !== subWindow ) {
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if ( preferredDoc != document &&
+ ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {
// Support: IE 11, Edge
if ( subWindow.addEventListener ) {
@@ -1134,25 +1163,36 @@ setDocument = Sizzle.setDocument = function( node ) {
}
}
+ // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only,
+ // Safari 4 - 5 only, Opera <=11.6 - 12.x only
+ // IE/Edge & older browsers don't support the :scope pseudo-class.
+ // Support: Safari 6.0 only
+ // Safari 6.0 supports :scope but it's an alias of :root there.
+ support.scope = assert( function( el ) {
+ docElem.appendChild( el ).appendChild( document.createElement( "div" ) );
+ return typeof el.querySelectorAll !== "undefined" &&
+ !el.querySelectorAll( ":scope fieldset div" ).length;
+ } );
+
/* Attributes
---------------------------------------------------------------------- */
// Support: IE<8
// Verify that getAttribute really returns attributes and not properties
// (excepting IE8 booleans)
- support.attributes = assert(function( el ) {
+ support.attributes = assert( function( el ) {
el.className = "i";
- return !el.getAttribute("className");
- });
+ return !el.getAttribute( "className" );
+ } );
/* getElement(s)By*
---------------------------------------------------------------------- */
// Check if getElementsByTagName("*") returns only elements
- support.getElementsByTagName = assert(function( el ) {
- el.appendChild( document.createComment("") );
- return !el.getElementsByTagName("*").length;
- });
+ support.getElementsByTagName = assert( function( el ) {
+ el.appendChild( document.createComment( "" ) );
+ return !el.getElementsByTagName( "*" ).length;
+ } );
// Support: IE<9
support.getElementsByClassName = rnative.test( document.getElementsByClassName );
@@ -1161,38 +1201,38 @@ setDocument = Sizzle.setDocument = function( node ) {
// Check if getElementById returns elements by name
// The broken getElementById methods don't pick up programmatically-set names,
// so use a roundabout getElementsByName test
- support.getById = assert(function( el ) {
+ support.getById = assert( function( el ) {
docElem.appendChild( el ).id = expando;
return !document.getElementsByName || !document.getElementsByName( expando ).length;
- });
+ } );
// ID filter and find
if ( support.getById ) {
- Expr.filter["ID"] = function( id ) {
+ Expr.filter[ "ID" ] = function( id ) {
var attrId = id.replace( runescape, funescape );
return function( elem ) {
- return elem.getAttribute("id") === attrId;
+ return elem.getAttribute( "id" ) === attrId;
};
};
- Expr.find["ID"] = function( id, context ) {
+ Expr.find[ "ID" ] = function( id, context ) {
if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
var elem = context.getElementById( id );
return elem ? [ elem ] : [];
}
};
} else {
- Expr.filter["ID"] = function( id ) {
+ Expr.filter[ "ID" ] = function( id ) {
var attrId = id.replace( runescape, funescape );
return function( elem ) {
var node = typeof elem.getAttributeNode !== "undefined" &&
- elem.getAttributeNode("id");
+ elem.getAttributeNode( "id" );
return node && node.value === attrId;
};
};
// Support: IE 6 - 7 only
// getElementById is not reliable as a find shortcut
- Expr.find["ID"] = function( id, context ) {
+ Expr.find[ "ID" ] = function( id, context ) {
if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
var node, i, elems,
elem = context.getElementById( id );
@@ -1200,7 +1240,7 @@ setDocument = Sizzle.setDocument = function( node ) {
if ( elem ) {
// Verify the id attribute
- node = elem.getAttributeNode("id");
+ node = elem.getAttributeNode( "id" );
if ( node && node.value === id ) {
return [ elem ];
}
@@ -1208,8 +1248,8 @@ setDocument = Sizzle.setDocument = function( node ) {
// Fall back on getElementsByName
elems = context.getElementsByName( id );
i = 0;
- while ( (elem = elems[i++]) ) {
- node = elem.getAttributeNode("id");
+ while ( ( elem = elems[ i++ ] ) ) {
+ node = elem.getAttributeNode( "id" );
if ( node && node.value === id ) {
return [ elem ];
}
@@ -1222,7 +1262,7 @@ setDocument = Sizzle.setDocument = function( node ) {
}
// Tag
- Expr.find["TAG"] = support.getElementsByTagName ?
+ Expr.find[ "TAG" ] = support.getElementsByTagName ?
function( tag, context ) {
if ( typeof context.getElementsByTagName !== "undefined" ) {
return context.getElementsByTagName( tag );
@@ -1237,12 +1277,13 @@ setDocument = Sizzle.setDocument = function( node ) {
var elem,
tmp = [],
i = 0,
+
// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
results = context.getElementsByTagName( tag );
// Filter out possible comments
if ( tag === "*" ) {
- while ( (elem = results[i++]) ) {
+ while ( ( elem = results[ i++ ] ) ) {
if ( elem.nodeType === 1 ) {
tmp.push( elem );
}
@@ -1254,7 +1295,7 @@ setDocument = Sizzle.setDocument = function( node ) {
};
// Class
- Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
+ Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) {
if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
return context.getElementsByClassName( className );
}
@@ -1275,10 +1316,14 @@ setDocument = Sizzle.setDocument = function( node ) {
// See https://bugs.jquery.com/ticket/13378
rbuggyQSA = [];
- if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
+ if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) {
+
// Build QSA regex
// Regex strategy adopted from Diego Perini
- assert(function( el ) {
+ assert( function( el ) {
+
+ var input;
+
// Select is set to empty string on purpose
// This is to test IE's treatment of not explicitly
// setting a boolean content attribute,
@@ -1292,78 +1337,98 @@ setDocument = Sizzle.setDocument = function( node ) {
// Nothing should be selected when empty strings follow ^= or $= or *=
// The test attribute must be unknown in Opera but "safe" for WinRT
// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
- if ( el.querySelectorAll("[msallowcapture^='']").length ) {
+ if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) {
rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
}
// Support: IE8
// Boolean attributes and "value" are not treated correctly
- if ( !el.querySelectorAll("[selected]").length ) {
+ if ( !el.querySelectorAll( "[selected]" ).length ) {
rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
}
// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
- rbuggyQSA.push("~=");
+ rbuggyQSA.push( "~=" );
+ }
+
+ // Support: IE 11+, Edge 15 - 18+
+ // IE 11/Edge don't find elements on a `[name='']` query in some cases.
+ // Adding a temporary attribute to the document before the selection works
+ // around the issue.
+ // Interestingly, IE 10 & older don't seem to have the issue.
+ input = document.createElement( "input" );
+ input.setAttribute( "name", "" );
+ el.appendChild( input );
+ if ( !el.querySelectorAll( "[name='']" ).length ) {
+ rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" +
+ whitespace + "*(?:''|\"\")" );
}
// Webkit/Opera - :checked should return selected option elements
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
// IE8 throws error here and will not see later tests
- if ( !el.querySelectorAll(":checked").length ) {
- rbuggyQSA.push(":checked");
+ if ( !el.querySelectorAll( ":checked" ).length ) {
+ rbuggyQSA.push( ":checked" );
}
// Support: Safari 8+, iOS 8+
// https://bugs.webkit.org/show_bug.cgi?id=136851
// In-page `selector#id sibling-combinator selector` fails
if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
- rbuggyQSA.push(".#.+[+~]");
+ rbuggyQSA.push( ".#.+[+~]" );
}
- });
- assert(function( el ) {
+ // Support: Firefox <=3.6 - 5 only
+ // Old Firefox doesn't throw on a badly-escaped identifier.
+ el.querySelectorAll( "\\\f" );
+ rbuggyQSA.push( "[\\r\\n\\f]" );
+ } );
+
+ assert( function( el ) {
el.innerHTML = " " +
" ";
// Support: Windows 8 Native Apps
// The type and name attributes are restricted during .innerHTML assignment
- var input = document.createElement("input");
+ var input = document.createElement( "input" );
input.setAttribute( "type", "hidden" );
el.appendChild( input ).setAttribute( "name", "D" );
// Support: IE8
// Enforce case-sensitivity of name attribute
- if ( el.querySelectorAll("[name=d]").length ) {
+ if ( el.querySelectorAll( "[name=d]" ).length ) {
rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
}
// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
// IE8 throws error here and will not see later tests
- if ( el.querySelectorAll(":enabled").length !== 2 ) {
+ if ( el.querySelectorAll( ":enabled" ).length !== 2 ) {
rbuggyQSA.push( ":enabled", ":disabled" );
}
// Support: IE9-11+
// IE's :disabled selector does not pick up the children of disabled fieldsets
docElem.appendChild( el ).disabled = true;
- if ( el.querySelectorAll(":disabled").length !== 2 ) {
+ if ( el.querySelectorAll( ":disabled" ).length !== 2 ) {
rbuggyQSA.push( ":enabled", ":disabled" );
}
+ // Support: Opera 10 - 11 only
// Opera 10-11 does not throw on post-comma invalid pseudos
- el.querySelectorAll("*,:x");
- rbuggyQSA.push(",.*:");
- });
+ el.querySelectorAll( "*,:x" );
+ rbuggyQSA.push( ",.*:" );
+ } );
}
- if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
+ if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches ||
docElem.webkitMatchesSelector ||
docElem.mozMatchesSelector ||
docElem.oMatchesSelector ||
- docElem.msMatchesSelector) )) ) {
+ docElem.msMatchesSelector ) ) ) ) {
+
+ assert( function( el ) {
- assert(function( el ) {
// Check to see if it's possible to do matchesSelector
// on a disconnected node (IE 9)
support.disconnectedMatch = matches.call( el, "*" );
@@ -1372,11 +1437,11 @@ setDocument = Sizzle.setDocument = function( node ) {
// Gecko does not error, returns false instead
matches.call( el, "[s!='']:x" );
rbuggyMatches.push( "!=", pseudos );
- });
+ } );
}
- rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
- rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
+ rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) );
+ rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) );
/* Contains
---------------------------------------------------------------------- */
@@ -1393,11 +1458,11 @@ setDocument = Sizzle.setDocument = function( node ) {
adown.contains ?
adown.contains( bup ) :
a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
- ));
+ ) );
} :
function( a, b ) {
if ( b ) {
- while ( (b = b.parentNode) ) {
+ while ( ( b = b.parentNode ) ) {
if ( b === a ) {
return true;
}
@@ -1426,7 +1491,11 @@ setDocument = Sizzle.setDocument = function( node ) {
}
// Calculate position if both inputs belong to the same document
- compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?
a.compareDocumentPosition( b ) :
// Otherwise we know they are disconnected
@@ -1434,13 +1503,24 @@ setDocument = Sizzle.setDocument = function( node ) {
// Disconnected nodes
if ( compare & 1 ||
- (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
+ ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {
// Choose the first element that is related to our preferred document
- if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if ( a == document || a.ownerDocument == preferredDoc &&
+ contains( preferredDoc, a ) ) {
return -1;
}
- if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
+
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if ( b == document || b.ownerDocument == preferredDoc &&
+ contains( preferredDoc, b ) ) {
return 1;
}
@@ -1453,6 +1533,7 @@ setDocument = Sizzle.setDocument = function( node ) {
return compare & 4 ? -1 : 1;
} :
function( a, b ) {
+
// Exit early if the nodes are identical
if ( a === b ) {
hasDuplicate = true;
@@ -1468,8 +1549,14 @@ setDocument = Sizzle.setDocument = function( node ) {
// Parentless nodes are either documents or disconnected
if ( !aup || !bup ) {
- return a === document ? -1 :
- b === document ? 1 :
+
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ /* eslint-disable eqeqeq */
+ return a == document ? -1 :
+ b == document ? 1 :
+ /* eslint-enable eqeqeq */
aup ? -1 :
bup ? 1 :
sortInput ?
@@ -1483,26 +1570,32 @@ setDocument = Sizzle.setDocument = function( node ) {
// Otherwise we need full lists of their ancestors for comparison
cur = a;
- while ( (cur = cur.parentNode) ) {
+ while ( ( cur = cur.parentNode ) ) {
ap.unshift( cur );
}
cur = b;
- while ( (cur = cur.parentNode) ) {
+ while ( ( cur = cur.parentNode ) ) {
bp.unshift( cur );
}
// Walk down the tree looking for a discrepancy
- while ( ap[i] === bp[i] ) {
+ while ( ap[ i ] === bp[ i ] ) {
i++;
}
return i ?
+
// Do a sibling check if the nodes have a common ancestor
- siblingCheck( ap[i], bp[i] ) :
+ siblingCheck( ap[ i ], bp[ i ] ) :
// Otherwise nodes in our document sort first
- ap[i] === preferredDoc ? -1 :
- bp[i] === preferredDoc ? 1 :
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ /* eslint-disable eqeqeq */
+ ap[ i ] == preferredDoc ? -1 :
+ bp[ i ] == preferredDoc ? 1 :
+ /* eslint-enable eqeqeq */
0;
};
@@ -1514,16 +1607,10 @@ Sizzle.matches = function( expr, elements ) {
};
Sizzle.matchesSelector = function( elem, expr ) {
- // Set document vars if needed
- if ( ( elem.ownerDocument || elem ) !== document ) {
- setDocument( elem );
- }
-
- // Make sure that attribute selectors are quoted
- expr = expr.replace( rattributeQuotes, "='$1']" );
+ setDocument( elem );
if ( support.matchesSelector && documentIsHTML &&
- !compilerCache[ expr + " " ] &&
+ !nonnativeSelectorCache[ expr + " " ] &&
( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
@@ -1532,32 +1619,46 @@ Sizzle.matchesSelector = function( elem, expr ) {
// IE 9's matchesSelector returns false on disconnected nodes
if ( ret || support.disconnectedMatch ||
- // As well, disconnected nodes are said to be in a document
- // fragment in IE 9
- elem.document && elem.document.nodeType !== 11 ) {
+
+ // As well, disconnected nodes are said to be in a document
+ // fragment in IE 9
+ elem.document && elem.document.nodeType !== 11 ) {
return ret;
}
- } catch (e) {}
+ } catch ( e ) {
+ nonnativeSelectorCache( expr, true );
+ }
}
return Sizzle( expr, document, null, [ elem ] ).length > 0;
};
Sizzle.contains = function( context, elem ) {
+
// Set document vars if needed
- if ( ( context.ownerDocument || context ) !== document ) {
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if ( ( context.ownerDocument || context ) != document ) {
setDocument( context );
}
return contains( context, elem );
};
Sizzle.attr = function( elem, name ) {
+
// Set document vars if needed
- if ( ( elem.ownerDocument || elem ) !== document ) {
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if ( ( elem.ownerDocument || elem ) != document ) {
setDocument( elem );
}
var fn = Expr.attrHandle[ name.toLowerCase() ],
+
// Don't get fooled by Object.prototype properties (jQuery #13807)
val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
fn( elem, name, !documentIsHTML ) :
@@ -1567,13 +1668,13 @@ Sizzle.attr = function( elem, name ) {
val :
support.attributes || !documentIsHTML ?
elem.getAttribute( name ) :
- (val = elem.getAttributeNode(name)) && val.specified ?
+ ( val = elem.getAttributeNode( name ) ) && val.specified ?
val.value :
null;
};
Sizzle.escape = function( sel ) {
- return (sel + "").replace( rcssescape, fcssescape );
+ return ( sel + "" ).replace( rcssescape, fcssescape );
};
Sizzle.error = function( msg ) {
@@ -1596,7 +1697,7 @@ Sizzle.uniqueSort = function( results ) {
results.sort( sortOrder );
if ( hasDuplicate ) {
- while ( (elem = results[i++]) ) {
+ while ( ( elem = results[ i++ ] ) ) {
if ( elem === results[ i ] ) {
j = duplicates.push( i );
}
@@ -1624,17 +1725,21 @@ getText = Sizzle.getText = function( elem ) {
nodeType = elem.nodeType;
if ( !nodeType ) {
+
// If no nodeType, this is expected to be an array
- while ( (node = elem[i++]) ) {
+ while ( ( node = elem[ i++ ] ) ) {
+
// Do not traverse comment nodes
ret += getText( node );
}
} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+
// Use textContent for elements
// innerText usage removed for consistency of new lines (jQuery #11153)
if ( typeof elem.textContent === "string" ) {
return elem.textContent;
} else {
+
// Traverse its children
for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
ret += getText( elem );
@@ -1643,6 +1748,7 @@ getText = Sizzle.getText = function( elem ) {
} else if ( nodeType === 3 || nodeType === 4 ) {
return elem.nodeValue;
}
+
// Do not include comment or processing instruction nodes
return ret;
@@ -1670,19 +1776,21 @@ Expr = Sizzle.selectors = {
preFilter: {
"ATTR": function( match ) {
- match[1] = match[1].replace( runescape, funescape );
+ match[ 1 ] = match[ 1 ].replace( runescape, funescape );
// Move the given value to match[3] whether quoted or unquoted
- match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
+ match[ 3 ] = ( match[ 3 ] || match[ 4 ] ||
+ match[ 5 ] || "" ).replace( runescape, funescape );
- if ( match[2] === "~=" ) {
- match[3] = " " + match[3] + " ";
+ if ( match[ 2 ] === "~=" ) {
+ match[ 3 ] = " " + match[ 3 ] + " ";
}
return match.slice( 0, 4 );
},
"CHILD": function( match ) {
+
/* matches from matchExpr["CHILD"]
1 type (only|nth|...)
2 what (child|of-type)
@@ -1693,22 +1801,25 @@ Expr = Sizzle.selectors = {
7 sign of y-component
8 y of y-component
*/
- match[1] = match[1].toLowerCase();
+ match[ 1 ] = match[ 1 ].toLowerCase();
+
+ if ( match[ 1 ].slice( 0, 3 ) === "nth" ) {
- if ( match[1].slice( 0, 3 ) === "nth" ) {
// nth-* requires argument
- if ( !match[3] ) {
- Sizzle.error( match[0] );
+ if ( !match[ 3 ] ) {
+ Sizzle.error( match[ 0 ] );
}
// numeric x and y parameters for Expr.filter.CHILD
// remember that false/true cast respectively to 0/1
- match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
- match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
+ match[ 4 ] = +( match[ 4 ] ?
+ match[ 5 ] + ( match[ 6 ] || 1 ) :
+ 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) );
+ match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" );
- // other types prohibit arguments
- } else if ( match[3] ) {
- Sizzle.error( match[0] );
+ // other types prohibit arguments
+ } else if ( match[ 3 ] ) {
+ Sizzle.error( match[ 0 ] );
}
return match;
@@ -1716,26 +1827,28 @@ Expr = Sizzle.selectors = {
"PSEUDO": function( match ) {
var excess,
- unquoted = !match[6] && match[2];
+ unquoted = !match[ 6 ] && match[ 2 ];
- if ( matchExpr["CHILD"].test( match[0] ) ) {
+ if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) {
return null;
}
// Accept quoted arguments as-is
- if ( match[3] ) {
- match[2] = match[4] || match[5] || "";
+ if ( match[ 3 ] ) {
+ match[ 2 ] = match[ 4 ] || match[ 5 ] || "";
// Strip excess characters from unquoted arguments
} else if ( unquoted && rpseudo.test( unquoted ) &&
+
// Get excess from tokenize (recursively)
- (excess = tokenize( unquoted, true )) &&
+ ( excess = tokenize( unquoted, true ) ) &&
+
// advance to the next closing parenthesis
- (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
+ ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) {
// excess is a negative index
- match[0] = match[0].slice( 0, excess );
- match[2] = unquoted.slice( 0, excess );
+ match[ 0 ] = match[ 0 ].slice( 0, excess );
+ match[ 2 ] = unquoted.slice( 0, excess );
}
// Return only captures needed by the pseudo filter method (type and argument)
@@ -1748,7 +1861,9 @@ Expr = Sizzle.selectors = {
"TAG": function( nodeNameSelector ) {
var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
return nodeNameSelector === "*" ?
- function() { return true; } :
+ function() {
+ return true;
+ } :
function( elem ) {
return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
};
@@ -1758,10 +1873,16 @@ Expr = Sizzle.selectors = {
var pattern = classCache[ className + " " ];
return pattern ||
- (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
- classCache( className, function( elem ) {
- return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
- });
+ ( pattern = new RegExp( "(^|" + whitespace +
+ ")" + className + "(" + whitespace + "|$)" ) ) && classCache(
+ className, function( elem ) {
+ return pattern.test(
+ typeof elem.className === "string" && elem.className ||
+ typeof elem.getAttribute !== "undefined" &&
+ elem.getAttribute( "class" ) ||
+ ""
+ );
+ } );
},
"ATTR": function( name, operator, check ) {
@@ -1777,6 +1898,8 @@ Expr = Sizzle.selectors = {
result += "";
+ /* eslint-disable max-len */
+
return operator === "=" ? result === check :
operator === "!=" ? result !== check :
operator === "^=" ? check && result.indexOf( check ) === 0 :
@@ -1785,10 +1908,12 @@ Expr = Sizzle.selectors = {
operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
false;
+ /* eslint-enable max-len */
+
};
},
- "CHILD": function( type, what, argument, first, last ) {
+ "CHILD": function( type, what, _argument, first, last ) {
var simple = type.slice( 0, 3 ) !== "nth",
forward = type.slice( -4 ) !== "last",
ofType = what === "of-type";
@@ -1800,7 +1925,7 @@ Expr = Sizzle.selectors = {
return !!elem.parentNode;
} :
- function( elem, context, xml ) {
+ function( elem, _context, xml ) {
var cache, uniqueCache, outerCache, node, nodeIndex, start,
dir = simple !== forward ? "nextSibling" : "previousSibling",
parent = elem.parentNode,
@@ -1814,7 +1939,7 @@ Expr = Sizzle.selectors = {
if ( simple ) {
while ( dir ) {
node = elem;
- while ( (node = node[ dir ]) ) {
+ while ( ( node = node[ dir ] ) ) {
if ( ofType ?
node.nodeName.toLowerCase() === name :
node.nodeType === 1 ) {
@@ -1822,6 +1947,7 @@ Expr = Sizzle.selectors = {
return false;
}
}
+
// Reverse direction for :only-* (if we haven't yet done so)
start = dir = type === "only" && !start && "nextSibling";
}
@@ -1837,22 +1963,22 @@ Expr = Sizzle.selectors = {
// ...in a gzip-friendly way
node = parent;
- outerCache = node[ expando ] || (node[ expando ] = {});
+ outerCache = node[ expando ] || ( node[ expando ] = {} );
// Support: IE <9 only
// Defend against cloned attroperties (jQuery gh-1709)
uniqueCache = outerCache[ node.uniqueID ] ||
- (outerCache[ node.uniqueID ] = {});
+ ( outerCache[ node.uniqueID ] = {} );
cache = uniqueCache[ type ] || [];
nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
diff = nodeIndex && cache[ 2 ];
node = nodeIndex && parent.childNodes[ nodeIndex ];
- while ( (node = ++nodeIndex && node && node[ dir ] ||
+ while ( ( node = ++nodeIndex && node && node[ dir ] ||
// Fallback to seeking `elem` from the start
- (diff = nodeIndex = 0) || start.pop()) ) {
+ ( diff = nodeIndex = 0 ) || start.pop() ) ) {
// When found, cache indexes on `parent` and break
if ( node.nodeType === 1 && ++diff && node === elem ) {
@@ -1862,16 +1988,18 @@ Expr = Sizzle.selectors = {
}
} else {
+
// Use previously-cached element index if available
if ( useCache ) {
+
// ...in a gzip-friendly way
node = elem;
- outerCache = node[ expando ] || (node[ expando ] = {});
+ outerCache = node[ expando ] || ( node[ expando ] = {} );
// Support: IE <9 only
// Defend against cloned attroperties (jQuery gh-1709)
uniqueCache = outerCache[ node.uniqueID ] ||
- (outerCache[ node.uniqueID ] = {});
+ ( outerCache[ node.uniqueID ] = {} );
cache = uniqueCache[ type ] || [];
nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
@@ -1881,9 +2009,10 @@ Expr = Sizzle.selectors = {
// xml :nth-child(...)
// or :nth-last-child(...) or :nth(-last)?-of-type(...)
if ( diff === false ) {
+
// Use the same loop as above to seek `elem` from the start
- while ( (node = ++nodeIndex && node && node[ dir ] ||
- (diff = nodeIndex = 0) || start.pop()) ) {
+ while ( ( node = ++nodeIndex && node && node[ dir ] ||
+ ( diff = nodeIndex = 0 ) || start.pop() ) ) {
if ( ( ofType ?
node.nodeName.toLowerCase() === name :
@@ -1892,12 +2021,13 @@ Expr = Sizzle.selectors = {
// Cache the index of each encountered element
if ( useCache ) {
- outerCache = node[ expando ] || (node[ expando ] = {});
+ outerCache = node[ expando ] ||
+ ( node[ expando ] = {} );
// Support: IE <9 only
// Defend against cloned attroperties (jQuery gh-1709)
uniqueCache = outerCache[ node.uniqueID ] ||
- (outerCache[ node.uniqueID ] = {});
+ ( outerCache[ node.uniqueID ] = {} );
uniqueCache[ type ] = [ dirruns, diff ];
}
@@ -1918,6 +2048,7 @@ Expr = Sizzle.selectors = {
},
"PSEUDO": function( pseudo, argument ) {
+
// pseudo-class names are case-insensitive
// http://www.w3.org/TR/selectors/#pseudo-classes
// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
@@ -1937,15 +2068,15 @@ Expr = Sizzle.selectors = {
if ( fn.length > 1 ) {
args = [ pseudo, pseudo, "", argument ];
return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
- markFunction(function( seed, matches ) {
+ markFunction( function( seed, matches ) {
var idx,
matched = fn( seed, argument ),
i = matched.length;
while ( i-- ) {
- idx = indexOf( seed, matched[i] );
- seed[ idx ] = !( matches[ idx ] = matched[i] );
+ idx = indexOf( seed, matched[ i ] );
+ seed[ idx ] = !( matches[ idx ] = matched[ i ] );
}
- }) :
+ } ) :
function( elem ) {
return fn( elem, 0, args );
};
@@ -1956,8 +2087,10 @@ Expr = Sizzle.selectors = {
},
pseudos: {
+
// Potentially complex pseudos
- "not": markFunction(function( selector ) {
+ "not": markFunction( function( selector ) {
+
// Trim the selector passed to compile
// to avoid treating leading and trailing
// spaces as combinators
@@ -1966,39 +2099,40 @@ Expr = Sizzle.selectors = {
matcher = compile( selector.replace( rtrim, "$1" ) );
return matcher[ expando ] ?
- markFunction(function( seed, matches, context, xml ) {
+ markFunction( function( seed, matches, _context, xml ) {
var elem,
unmatched = matcher( seed, null, xml, [] ),
i = seed.length;
// Match elements unmatched by `matcher`
while ( i-- ) {
- if ( (elem = unmatched[i]) ) {
- seed[i] = !(matches[i] = elem);
+ if ( ( elem = unmatched[ i ] ) ) {
+ seed[ i ] = !( matches[ i ] = elem );
}
}
- }) :
- function( elem, context, xml ) {
- input[0] = elem;
+ } ) :
+ function( elem, _context, xml ) {
+ input[ 0 ] = elem;
matcher( input, null, xml, results );
+
// Don't keep the element (issue #299)
- input[0] = null;
+ input[ 0 ] = null;
return !results.pop();
};
- }),
+ } ),
- "has": markFunction(function( selector ) {
+ "has": markFunction( function( selector ) {
return function( elem ) {
return Sizzle( selector, elem ).length > 0;
};
- }),
+ } ),
- "contains": markFunction(function( text ) {
+ "contains": markFunction( function( text ) {
text = text.replace( runescape, funescape );
return function( elem ) {
- return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
+ return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;
};
- }),
+ } ),
// "Whether an element is represented by a :lang() selector
// is based solely on the element's language value
@@ -2008,25 +2142,26 @@ Expr = Sizzle.selectors = {
// The identifier C does not have to be a valid language name."
// http://www.w3.org/TR/selectors/#lang-pseudo
"lang": markFunction( function( lang ) {
+
// lang value must be a valid identifier
- if ( !ridentifier.test(lang || "") ) {
+ if ( !ridentifier.test( lang || "" ) ) {
Sizzle.error( "unsupported lang: " + lang );
}
lang = lang.replace( runescape, funescape ).toLowerCase();
return function( elem ) {
var elemLang;
do {
- if ( (elemLang = documentIsHTML ?
+ if ( ( elemLang = documentIsHTML ?
elem.lang :
- elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
+ elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) {
elemLang = elemLang.toLowerCase();
return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
}
- } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
+ } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );
return false;
};
- }),
+ } ),
// Miscellaneous
"target": function( elem ) {
@@ -2039,7 +2174,9 @@ Expr = Sizzle.selectors = {
},
"focus": function( elem ) {
- return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
+ return elem === document.activeElement &&
+ ( !document.hasFocus || document.hasFocus() ) &&
+ !!( elem.type || elem.href || ~elem.tabIndex );
},
// Boolean properties
@@ -2047,16 +2184,20 @@ Expr = Sizzle.selectors = {
"disabled": createDisabledPseudo( true ),
"checked": function( elem ) {
+
// In CSS3, :checked should return both checked and selected elements
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
var nodeName = elem.nodeName.toLowerCase();
- return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
+ return ( nodeName === "input" && !!elem.checked ) ||
+ ( nodeName === "option" && !!elem.selected );
},
"selected": function( elem ) {
+
// Accessing this property makes selected-by-default
// options in Safari work properly
if ( elem.parentNode ) {
+ // eslint-disable-next-line no-unused-expressions
elem.parentNode.selectedIndex;
}
@@ -2065,6 +2206,7 @@ Expr = Sizzle.selectors = {
// Contents
"empty": function( elem ) {
+
// http://www.w3.org/TR/selectors/#empty-pseudo
// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
// but not by others (comment: 8; processing instruction: 7; etc.)
@@ -2078,7 +2220,7 @@ Expr = Sizzle.selectors = {
},
"parent": function( elem ) {
- return !Expr.pseudos["empty"]( elem );
+ return !Expr.pseudos[ "empty" ]( elem );
},
// Element/input types
@@ -2102,57 +2244,62 @@ Expr = Sizzle.selectors = {
// Support: IE<8
// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
- ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
+ ( ( attr = elem.getAttribute( "type" ) ) == null ||
+ attr.toLowerCase() === "text" );
},
// Position-in-collection
- "first": createPositionalPseudo(function() {
+ "first": createPositionalPseudo( function() {
return [ 0 ];
- }),
+ } ),
- "last": createPositionalPseudo(function( matchIndexes, length ) {
+ "last": createPositionalPseudo( function( _matchIndexes, length ) {
return [ length - 1 ];
- }),
+ } ),
- "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) {
return [ argument < 0 ? argument + length : argument ];
- }),
+ } ),
- "even": createPositionalPseudo(function( matchIndexes, length ) {
+ "even": createPositionalPseudo( function( matchIndexes, length ) {
var i = 0;
for ( ; i < length; i += 2 ) {
matchIndexes.push( i );
}
return matchIndexes;
- }),
+ } ),
- "odd": createPositionalPseudo(function( matchIndexes, length ) {
+ "odd": createPositionalPseudo( function( matchIndexes, length ) {
var i = 1;
for ( ; i < length; i += 2 ) {
matchIndexes.push( i );
}
return matchIndexes;
- }),
+ } ),
- "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
- var i = argument < 0 ? argument + length : argument;
+ "lt": createPositionalPseudo( function( matchIndexes, length, argument ) {
+ var i = argument < 0 ?
+ argument + length :
+ argument > length ?
+ length :
+ argument;
for ( ; --i >= 0; ) {
matchIndexes.push( i );
}
return matchIndexes;
- }),
+ } ),
- "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ "gt": createPositionalPseudo( function( matchIndexes, length, argument ) {
var i = argument < 0 ? argument + length : argument;
for ( ; ++i < length; ) {
matchIndexes.push( i );
}
return matchIndexes;
- })
+ } )
}
};
-Expr.pseudos["nth"] = Expr.pseudos["eq"];
+Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ];
// Add button/input type pseudos
for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
@@ -2183,37 +2330,39 @@ tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
while ( soFar ) {
// Comma and first run
- if ( !matched || (match = rcomma.exec( soFar )) ) {
+ if ( !matched || ( match = rcomma.exec( soFar ) ) ) {
if ( match ) {
+
// Don't consume trailing commas as valid
- soFar = soFar.slice( match[0].length ) || soFar;
+ soFar = soFar.slice( match[ 0 ].length ) || soFar;
}
- groups.push( (tokens = []) );
+ groups.push( ( tokens = [] ) );
}
matched = false;
// Combinators
- if ( (match = rcombinators.exec( soFar )) ) {
+ if ( ( match = rcombinators.exec( soFar ) ) ) {
matched = match.shift();
- tokens.push({
+ tokens.push( {
value: matched,
+
// Cast descendant combinators to space
- type: match[0].replace( rtrim, " " )
- });
+ type: match[ 0 ].replace( rtrim, " " )
+ } );
soFar = soFar.slice( matched.length );
}
// Filters
for ( type in Expr.filter ) {
- if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
- (match = preFilters[ type ]( match ))) ) {
+ if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||
+ ( match = preFilters[ type ]( match ) ) ) ) {
matched = match.shift();
- tokens.push({
+ tokens.push( {
value: matched,
type: type,
matches: match
- });
+ } );
soFar = soFar.slice( matched.length );
}
}
@@ -2230,6 +2379,7 @@ tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
soFar.length :
soFar ?
Sizzle.error( selector ) :
+
// Cache the tokens
tokenCache( selector, groups ).slice( 0 );
};
@@ -2239,7 +2389,7 @@ function toSelector( tokens ) {
len = tokens.length,
selector = "";
for ( ; i < len; i++ ) {
- selector += tokens[i].value;
+ selector += tokens[ i ].value;
}
return selector;
}
@@ -2252,9 +2402,10 @@ function addCombinator( matcher, combinator, base ) {
doneName = done++;
return combinator.first ?
+
// Check against closest ancestor/preceding element
function( elem, context, xml ) {
- while ( (elem = elem[ dir ]) ) {
+ while ( ( elem = elem[ dir ] ) ) {
if ( elem.nodeType === 1 || checkNonElements ) {
return matcher( elem, context, xml );
}
@@ -2269,7 +2420,7 @@ function addCombinator( matcher, combinator, base ) {
// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
if ( xml ) {
- while ( (elem = elem[ dir ]) ) {
+ while ( ( elem = elem[ dir ] ) ) {
if ( elem.nodeType === 1 || checkNonElements ) {
if ( matcher( elem, context, xml ) ) {
return true;
@@ -2277,27 +2428,29 @@ function addCombinator( matcher, combinator, base ) {
}
}
} else {
- while ( (elem = elem[ dir ]) ) {
+ while ( ( elem = elem[ dir ] ) ) {
if ( elem.nodeType === 1 || checkNonElements ) {
- outerCache = elem[ expando ] || (elem[ expando ] = {});
+ outerCache = elem[ expando ] || ( elem[ expando ] = {} );
// Support: IE <9 only
// Defend against cloned attroperties (jQuery gh-1709)
- uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
+ uniqueCache = outerCache[ elem.uniqueID ] ||
+ ( outerCache[ elem.uniqueID ] = {} );
if ( skip && skip === elem.nodeName.toLowerCase() ) {
elem = elem[ dir ] || elem;
- } else if ( (oldCache = uniqueCache[ key ]) &&
+ } else if ( ( oldCache = uniqueCache[ key ] ) &&
oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
// Assign to newCache so results back-propagate to previous elements
- return (newCache[ 2 ] = oldCache[ 2 ]);
+ return ( newCache[ 2 ] = oldCache[ 2 ] );
} else {
+
// Reuse newcache so results back-propagate to previous elements
uniqueCache[ key ] = newCache;
// A match means we're done; a fail means we have to keep checking
- if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
+ if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {
return true;
}
}
@@ -2313,20 +2466,20 @@ function elementMatcher( matchers ) {
function( elem, context, xml ) {
var i = matchers.length;
while ( i-- ) {
- if ( !matchers[i]( elem, context, xml ) ) {
+ if ( !matchers[ i ]( elem, context, xml ) ) {
return false;
}
}
return true;
} :
- matchers[0];
+ matchers[ 0 ];
}
function multipleContexts( selector, contexts, results ) {
var i = 0,
len = contexts.length;
for ( ; i < len; i++ ) {
- Sizzle( selector, contexts[i], results );
+ Sizzle( selector, contexts[ i ], results );
}
return results;
}
@@ -2339,7 +2492,7 @@ function condense( unmatched, map, filter, context, xml ) {
mapped = map != null;
for ( ; i < len; i++ ) {
- if ( (elem = unmatched[i]) ) {
+ if ( ( elem = unmatched[ i ] ) ) {
if ( !filter || filter( elem, context, xml ) ) {
newUnmatched.push( elem );
if ( mapped ) {
@@ -2359,14 +2512,18 @@ function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postS
if ( postFinder && !postFinder[ expando ] ) {
postFinder = setMatcher( postFinder, postSelector );
}
- return markFunction(function( seed, results, context, xml ) {
+ return markFunction( function( seed, results, context, xml ) {
var temp, i, elem,
preMap = [],
postMap = [],
preexisting = results.length,
// Get initial elements from seed or context
- elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
+ elems = seed || multipleContexts(
+ selector || "*",
+ context.nodeType ? [ context ] : context,
+ []
+ ),
// Prefilter to get matcher input, preserving a map for seed-results synchronization
matcherIn = preFilter && ( seed || !selector ) ?
@@ -2374,6 +2531,7 @@ function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postS
elems,
matcherOut = matcher ?
+
// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
@@ -2397,8 +2555,8 @@ function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postS
// Un-match failing elements by moving them back to matcherIn
i = temp.length;
while ( i-- ) {
- if ( (elem = temp[i]) ) {
- matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
+ if ( ( elem = temp[ i ] ) ) {
+ matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );
}
}
}
@@ -2406,25 +2564,27 @@ function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postS
if ( seed ) {
if ( postFinder || preFilter ) {
if ( postFinder ) {
+
// Get the final matcherOut by condensing this intermediate into postFinder contexts
temp = [];
i = matcherOut.length;
while ( i-- ) {
- if ( (elem = matcherOut[i]) ) {
+ if ( ( elem = matcherOut[ i ] ) ) {
+
// Restore matcherIn since elem is not yet a final match
- temp.push( (matcherIn[i] = elem) );
+ temp.push( ( matcherIn[ i ] = elem ) );
}
}
- postFinder( null, (matcherOut = []), temp, xml );
+ postFinder( null, ( matcherOut = [] ), temp, xml );
}
// Move matched elements from seed to results to keep them synchronized
i = matcherOut.length;
while ( i-- ) {
- if ( (elem = matcherOut[i]) &&
- (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
+ if ( ( elem = matcherOut[ i ] ) &&
+ ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) {
- seed[temp] = !(results[temp] = elem);
+ seed[ temp ] = !( results[ temp ] = elem );
}
}
}
@@ -2442,14 +2602,14 @@ function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postS
push.apply( results, matcherOut );
}
}
- });
+ } );
}
function matcherFromTokens( tokens ) {
var checkContext, matcher, j,
len = tokens.length,
- leadingRelative = Expr.relative[ tokens[0].type ],
- implicitRelative = leadingRelative || Expr.relative[" "],
+ leadingRelative = Expr.relative[ tokens[ 0 ].type ],
+ implicitRelative = leadingRelative || Expr.relative[ " " ],
i = leadingRelative ? 1 : 0,
// The foundational matcher ensures that elements are reachable from top-level context(s)
@@ -2461,38 +2621,43 @@ function matcherFromTokens( tokens ) {
}, implicitRelative, true ),
matchers = [ function( elem, context, xml ) {
var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
- (checkContext = context).nodeType ?
+ ( checkContext = context ).nodeType ?
matchContext( elem, context, xml ) :
matchAnyContext( elem, context, xml ) );
+
// Avoid hanging onto element (issue #299)
checkContext = null;
return ret;
} ];
for ( ; i < len; i++ ) {
- if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
- matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
+ if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {
+ matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
} else {
- matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
+ matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );
// Return special upon seeing a positional matcher
if ( matcher[ expando ] ) {
+
// Find the next relative operator (if any) for proper handling
j = ++i;
for ( ; j < len; j++ ) {
- if ( Expr.relative[ tokens[j].type ] ) {
+ if ( Expr.relative[ tokens[ j ].type ] ) {
break;
}
}
return setMatcher(
i > 1 && elementMatcher( matchers ),
i > 1 && toSelector(
- // If the preceding token was a descendant combinator, insert an implicit any-element `*`
- tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
+
+ // If the preceding token was a descendant combinator, insert an implicit any-element `*`
+ tokens
+ .slice( 0, i - 1 )
+ .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } )
).replace( rtrim, "$1" ),
matcher,
i < j && matcherFromTokens( tokens.slice( i, j ) ),
- j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
+ j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),
j < len && toSelector( tokens )
);
}
@@ -2513,28 +2678,40 @@ function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
unmatched = seed && [],
setMatched = [],
contextBackup = outermostContext,
+
// We must always have either seed elements or outermost context
- elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
+ elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ),
+
// Use integer dirruns iff this is the outermost matcher
- dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
+ dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),
len = elems.length;
if ( outermost ) {
- outermostContext = context === document || context || outermost;
+
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ outermostContext = context == document || context || outermost;
}
// Add elements passing elementMatchers directly to results
// Support: IE<9, Safari
// Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id
- for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
+ for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {
if ( byElement && elem ) {
j = 0;
- if ( !context && elem.ownerDocument !== document ) {
+
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if ( !context && elem.ownerDocument != document ) {
setDocument( elem );
xml = !documentIsHTML;
}
- while ( (matcher = elementMatchers[j++]) ) {
- if ( matcher( elem, context || document, xml) ) {
+ while ( ( matcher = elementMatchers[ j++ ] ) ) {
+ if ( matcher( elem, context || document, xml ) ) {
results.push( elem );
break;
}
@@ -2546,8 +2723,9 @@ function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
// Track unmatched elements for set filters
if ( bySet ) {
+
// They will have gone through all possible matchers
- if ( (elem = !matcher && elem) ) {
+ if ( ( elem = !matcher && elem ) ) {
matchedCount--;
}
@@ -2571,16 +2749,17 @@ function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
// numerically zero.
if ( bySet && i !== matchedCount ) {
j = 0;
- while ( (matcher = setMatchers[j++]) ) {
+ while ( ( matcher = setMatchers[ j++ ] ) ) {
matcher( unmatched, setMatched, context, xml );
}
if ( seed ) {
+
// Reintegrate element matches to eliminate the need for sorting
if ( matchedCount > 0 ) {
while ( i-- ) {
- if ( !(unmatched[i] || setMatched[i]) ) {
- setMatched[i] = pop.call( results );
+ if ( !( unmatched[ i ] || setMatched[ i ] ) ) {
+ setMatched[ i ] = pop.call( results );
}
}
}
@@ -2621,13 +2800,14 @@ compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
cached = compilerCache[ selector + " " ];
if ( !cached ) {
+
// Generate a function of recursive functions that can be used to check each element
if ( !match ) {
match = tokenize( selector );
}
i = match.length;
while ( i-- ) {
- cached = matcherFromTokens( match[i] );
+ cached = matcherFromTokens( match[ i ] );
if ( cached[ expando ] ) {
setMatchers.push( cached );
} else {
@@ -2636,7 +2816,10 @@ compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
}
// Cache the compiled function
- cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
+ cached = compilerCache(
+ selector,
+ matcherFromGroupMatchers( elementMatchers, setMatchers )
+ );
// Save selector and tokenization
cached.selector = selector;
@@ -2656,7 +2839,7 @@ compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
select = Sizzle.select = function( selector, context, results, seed ) {
var i, tokens, token, type, find,
compiled = typeof selector === "function" && selector,
- match = !seed && tokenize( (selector = compiled.selector || selector) );
+ match = !seed && tokenize( ( selector = compiled.selector || selector ) );
results = results || [];
@@ -2665,11 +2848,12 @@ select = Sizzle.select = function( selector, context, results, seed ) {
if ( match.length === 1 ) {
// Reduce context if the leading compound selector is an ID
- tokens = match[0] = match[0].slice( 0 );
- if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
- context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {
+ tokens = match[ 0 ] = match[ 0 ].slice( 0 );
+ if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" &&
+ context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {
- context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
+ context = ( Expr.find[ "ID" ]( token.matches[ 0 ]
+ .replace( runescape, funescape ), context ) || [] )[ 0 ];
if ( !context ) {
return results;
@@ -2682,20 +2866,22 @@ select = Sizzle.select = function( selector, context, results, seed ) {
}
// Fetch a seed set for right-to-left matching
- i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
+ i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length;
while ( i-- ) {
- token = tokens[i];
+ token = tokens[ i ];
// Abort if we hit a combinator
- if ( Expr.relative[ (type = token.type) ] ) {
+ if ( Expr.relative[ ( type = token.type ) ] ) {
break;
}
- if ( (find = Expr.find[ type ]) ) {
+ if ( ( find = Expr.find[ type ] ) ) {
+
// Search, expanding context for leading sibling combinators
- if ( (seed = find(
- token.matches[0].replace( runescape, funescape ),
- rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
- )) ) {
+ if ( ( seed = find(
+ token.matches[ 0 ].replace( runescape, funescape ),
+ rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) ||
+ context
+ ) ) ) {
// If seed is empty or no tokens remain, we can return early
tokens.splice( i, 1 );
@@ -2726,7 +2912,7 @@ select = Sizzle.select = function( selector, context, results, seed ) {
// One-time assignments
// Sort stability
-support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
+support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando;
// Support: Chrome 14-35+
// Always assume duplicates if they aren't passed to the comparison function
@@ -2737,58 +2923,59 @@ setDocument();
// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
// Detached nodes confoundingly follow *each other*
-support.sortDetached = assert(function( el ) {
+support.sortDetached = assert( function( el ) {
+
// Should return 1, but returns 4 (following)
- return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;
-});
+ return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1;
+} );
// Support: IE<8
// Prevent attribute/property "interpolation"
// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
-if ( !assert(function( el ) {
+if ( !assert( function( el ) {
el.innerHTML = " ";
- return el.firstChild.getAttribute("href") === "#" ;
-}) ) {
+ return el.firstChild.getAttribute( "href" ) === "#";
+} ) ) {
addHandle( "type|href|height|width", function( elem, name, isXML ) {
if ( !isXML ) {
return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
}
- });
+ } );
}
// Support: IE<9
// Use defaultValue in place of getAttribute("value")
-if ( !support.attributes || !assert(function( el ) {
+if ( !support.attributes || !assert( function( el ) {
el.innerHTML = " ";
el.firstChild.setAttribute( "value", "" );
return el.firstChild.getAttribute( "value" ) === "";
-}) ) {
- addHandle( "value", function( elem, name, isXML ) {
+} ) ) {
+ addHandle( "value", function( elem, _name, isXML ) {
if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
return elem.defaultValue;
}
- });
+ } );
}
// Support: IE<9
// Use getAttributeNode to fetch booleans when getAttribute lies
-if ( !assert(function( el ) {
- return el.getAttribute("disabled") == null;
-}) ) {
+if ( !assert( function( el ) {
+ return el.getAttribute( "disabled" ) == null;
+} ) ) {
addHandle( booleans, function( elem, name, isXML ) {
var val;
if ( !isXML ) {
return elem[ name ] === true ? name.toLowerCase() :
- (val = elem.getAttributeNode( name )) && val.specified ?
+ ( val = elem.getAttributeNode( name ) ) && val.specified ?
val.value :
- null;
+ null;
}
- });
+ } );
}
return Sizzle;
-})( window );
+} )( window );
@@ -2841,18 +3028,16 @@ var rneedsContext = jQuery.expr.match.needsContext;
function nodeName( elem, name ) {
- return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
+ return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
-};
+}
var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
-var risSimple = /^.[^:#\[\.,]*$/;
-
// Implement the identical functionality for filter and not
function winnow( elements, qualifier, not ) {
- if ( jQuery.isFunction( qualifier ) ) {
+ if ( isFunction( qualifier ) ) {
return jQuery.grep( elements, function( elem, i ) {
return !!qualifier.call( elem, i, elem ) !== not;
} );
@@ -2872,16 +3057,8 @@ function winnow( elements, qualifier, not ) {
} );
}
- // Simple selector that can be filtered directly, removing non-Elements
- if ( risSimple.test( qualifier ) ) {
- return jQuery.filter( qualifier, elements, not );
- }
-
- // Complex selector, compare the two sets, removing non-Elements
- qualifier = jQuery.filter( qualifier, elements );
- return jQuery.grep( elements, function( elem ) {
- return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1;
- } );
+ // Filtered directly for both simple and complex selectors
+ return jQuery.filter( qualifier, elements, not );
}
jQuery.filter = function( expr, elems, not ) {
@@ -3002,7 +3179,7 @@ var rootjQuery,
for ( match in context ) {
// Properties of context are called as methods if possible
- if ( jQuery.isFunction( this[ match ] ) ) {
+ if ( isFunction( this[ match ] ) ) {
this[ match ]( context[ match ] );
// ...and otherwise set as attributes
@@ -3045,7 +3222,7 @@ var rootjQuery,
// HANDLE: $(function)
// Shortcut for document ready
- } else if ( jQuery.isFunction( selector ) ) {
+ } else if ( isFunction( selector ) ) {
return root.ready !== undefined ?
root.ready( selector ) :
@@ -3167,7 +3344,7 @@ jQuery.each( {
parents: function( elem ) {
return dir( elem, "parentNode" );
},
- parentsUntil: function( elem, i, until ) {
+ parentsUntil: function( elem, _i, until ) {
return dir( elem, "parentNode", until );
},
next: function( elem ) {
@@ -3182,10 +3359,10 @@ jQuery.each( {
prevAll: function( elem ) {
return dir( elem, "previousSibling" );
},
- nextUntil: function( elem, i, until ) {
+ nextUntil: function( elem, _i, until ) {
return dir( elem, "nextSibling", until );
},
- prevUntil: function( elem, i, until ) {
+ prevUntil: function( elem, _i, until ) {
return dir( elem, "previousSibling", until );
},
siblings: function( elem ) {
@@ -3195,18 +3372,24 @@ jQuery.each( {
return siblings( elem.firstChild );
},
contents: function( elem ) {
- if ( nodeName( elem, "iframe" ) ) {
- return elem.contentDocument;
- }
+ if ( elem.contentDocument != null &&
- // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
- // Treat the template element as a regular one in browsers that
- // don't support it.
- if ( nodeName( elem, "template" ) ) {
- elem = elem.content || elem;
- }
+ // Support: IE 11+
+ // elements with no `data` attribute has an object
+ // `contentDocument` with a `null` prototype.
+ getProto( elem.contentDocument ) ) {
- return jQuery.merge( [], elem.childNodes );
+ return elem.contentDocument;
+ }
+
+ // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
+ // Treat the template element as a regular one in browsers that
+ // don't support it.
+ if ( nodeName( elem, "template" ) ) {
+ elem = elem.content || elem;
+ }
+
+ return jQuery.merge( [], elem.childNodes );
}
}, function( name, fn ) {
jQuery.fn[ name ] = function( until, selector ) {
@@ -3360,11 +3543,11 @@ jQuery.Callbacks = function( options ) {
( function add( args ) {
jQuery.each( args, function( _, arg ) {
- if ( jQuery.isFunction( arg ) ) {
+ if ( isFunction( arg ) ) {
if ( !options.unique || !self.has( arg ) ) {
list.push( arg );
}
- } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
+ } else if ( arg && arg.length && toType( arg ) !== "string" ) {
// Inspect recursively
add( arg );
@@ -3479,11 +3662,11 @@ function adoptValue( value, resolve, reject, noValue ) {
try {
// Check for promise aspect first to privilege synchronous behavior
- if ( value && jQuery.isFunction( ( method = value.promise ) ) ) {
+ if ( value && isFunction( ( method = value.promise ) ) ) {
method.call( value ).done( resolve ).fail( reject );
// Other thenables
- } else if ( value && jQuery.isFunction( ( method = value.then ) ) ) {
+ } else if ( value && isFunction( ( method = value.then ) ) ) {
method.call( value, resolve, reject );
// Other non-thenables
@@ -3538,17 +3721,17 @@ jQuery.extend( {
var fns = arguments;
return jQuery.Deferred( function( newDefer ) {
- jQuery.each( tuples, function( i, tuple ) {
+ jQuery.each( tuples, function( _i, tuple ) {
// Map tuples (progress, done, fail) to arguments (done, fail, progress)
- var fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
+ var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
// deferred.progress(function() { bind to newDefer or newDefer.notify })
// deferred.done(function() { bind to newDefer or newDefer.resolve })
// deferred.fail(function() { bind to newDefer or newDefer.reject })
deferred[ tuple[ 1 ] ]( function() {
var returned = fn && fn.apply( this, arguments );
- if ( returned && jQuery.isFunction( returned.promise ) ) {
+ if ( returned && isFunction( returned.promise ) ) {
returned.promise()
.progress( newDefer.notify )
.done( newDefer.resolve )
@@ -3602,7 +3785,7 @@ jQuery.extend( {
returned.then;
// Handle a returned thenable
- if ( jQuery.isFunction( then ) ) {
+ if ( isFunction( then ) ) {
// Special processors (notify) just wait for resolution
if ( special ) {
@@ -3698,7 +3881,7 @@ jQuery.extend( {
resolve(
0,
newDefer,
- jQuery.isFunction( onProgress ) ?
+ isFunction( onProgress ) ?
onProgress :
Identity,
newDefer.notifyWith
@@ -3710,7 +3893,7 @@ jQuery.extend( {
resolve(
0,
newDefer,
- jQuery.isFunction( onFulfilled ) ?
+ isFunction( onFulfilled ) ?
onFulfilled :
Identity
)
@@ -3721,7 +3904,7 @@ jQuery.extend( {
resolve(
0,
newDefer,
- jQuery.isFunction( onRejected ) ?
+ isFunction( onRejected ) ?
onRejected :
Thrower
)
@@ -3761,8 +3944,15 @@ jQuery.extend( {
// fulfilled_callbacks.disable
tuples[ 3 - i ][ 2 ].disable,
+ // rejected_handlers.disable
+ // fulfilled_handlers.disable
+ tuples[ 3 - i ][ 3 ].disable,
+
// progress_callbacks.lock
- tuples[ 0 ][ 2 ].lock
+ tuples[ 0 ][ 2 ].lock,
+
+ // progress_handlers.lock
+ tuples[ 0 ][ 3 ].lock
);
}
@@ -3811,8 +4001,8 @@ jQuery.extend( {
resolveContexts = Array( i ),
resolveValues = slice.call( arguments ),
- // the master Deferred
- master = jQuery.Deferred(),
+ // the primary Deferred
+ primary = jQuery.Deferred(),
// subordinate callback factory
updateFunc = function( i ) {
@@ -3820,30 +4010,30 @@ jQuery.extend( {
resolveContexts[ i ] = this;
resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
if ( !( --remaining ) ) {
- master.resolveWith( resolveContexts, resolveValues );
+ primary.resolveWith( resolveContexts, resolveValues );
}
};
};
// Single- and empty arguments are adopted like Promise.resolve
if ( remaining <= 1 ) {
- adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
+ adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject,
!remaining );
// Use .then() to unwrap secondary thenables (cf. gh-3000)
- if ( master.state() === "pending" ||
- jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
+ if ( primary.state() === "pending" ||
+ isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
- return master.then();
+ return primary.then();
}
}
// Multiple arguments are aggregated like Promise.all array elements
while ( i-- ) {
- adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
+ adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject );
}
- return master.promise();
+ return primary.promise();
}
} );
@@ -3960,7 +4150,7 @@ var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
bulk = key == null;
// Sets many values
- if ( jQuery.type( key ) === "object" ) {
+ if ( toType( key ) === "object" ) {
chainable = true;
for ( i in key ) {
access( elems, fn, i, key[ i ], true, emptyGet, raw );
@@ -3970,7 +4160,7 @@ var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
} else if ( value !== undefined ) {
chainable = true;
- if ( !jQuery.isFunction( value ) ) {
+ if ( !isFunction( value ) ) {
raw = true;
}
@@ -3984,7 +4174,7 @@ var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
// ...except when executing function values
} else {
bulk = fn;
- fn = function( elem, key, value ) {
+ fn = function( elem, _key, value ) {
return bulk.call( jQuery( elem ), value );
};
}
@@ -3994,8 +4184,8 @@ var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
for ( ; i < len; i++ ) {
fn(
elems[ i ], key, raw ?
- value :
- value.call( elems[ i ], i, fn( elems[ i ], key ) )
+ value :
+ value.call( elems[ i ], i, fn( elems[ i ], key ) )
);
}
}
@@ -4012,6 +4202,23 @@ var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
return len ? fn( elems[ 0 ], key ) : emptyGet;
};
+
+
+// Matches dashed string for camelizing
+var rmsPrefix = /^-ms-/,
+ rdashAlpha = /-([a-z])/g;
+
+// Used by camelCase as callback to replace()
+function fcamelCase( _all, letter ) {
+ return letter.toUpperCase();
+}
+
+// Convert dashed to camelCase; used by the css and data modules
+// Support: IE <=9 - 11, Edge 12 - 15
+// Microsoft forgot to hump their vendor prefix (#9572)
+function camelCase( string ) {
+ return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+}
var acceptData = function( owner ) {
// Accepts only:
@@ -4074,14 +4281,14 @@ Data.prototype = {
// Handle: [ owner, key, value ] args
// Always use camelCase key (gh-2257)
if ( typeof data === "string" ) {
- cache[ jQuery.camelCase( data ) ] = value;
+ cache[ camelCase( data ) ] = value;
// Handle: [ owner, { properties } ] args
} else {
// Copy the properties one-by-one to the cache object
for ( prop in data ) {
- cache[ jQuery.camelCase( prop ) ] = data[ prop ];
+ cache[ camelCase( prop ) ] = data[ prop ];
}
}
return cache;
@@ -4091,7 +4298,7 @@ Data.prototype = {
this.cache( owner ) :
// Always use camelCase key (gh-2257)
- owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ];
+ owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
},
access: function( owner, key, value ) {
@@ -4139,9 +4346,9 @@ Data.prototype = {
// If key is an array of keys...
// We always set camelCase keys, so remove that.
- key = key.map( jQuery.camelCase );
+ key = key.map( camelCase );
} else {
- key = jQuery.camelCase( key );
+ key = camelCase( key );
// If a key with the spaces exists, use it.
// Otherwise, create an array by matching non-whitespace
@@ -4287,7 +4494,7 @@ jQuery.fn.extend( {
if ( attrs[ i ] ) {
name = attrs[ i ].name;
if ( name.indexOf( "data-" ) === 0 ) {
- name = jQuery.camelCase( name.slice( 5 ) );
+ name = camelCase( name.slice( 5 ) );
dataAttr( elem, name, data[ name ] );
}
}
@@ -4491,6 +4698,26 @@ var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
+var documentElement = document.documentElement;
+
+
+
+ var isAttached = function( elem ) {
+ return jQuery.contains( elem.ownerDocument, elem );
+ },
+ composed = { composed: true };
+
+ // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only
+ // Check attachment across shadow DOM boundaries when possible (gh-3504)
+ // Support: iOS 10.0-10.2 only
+ // Early iOS 10 versions support `attachShadow` but not `getRootNode`,
+ // leading to errors. We need to check for `getRootNode`.
+ if ( documentElement.getRootNode ) {
+ isAttached = function( elem ) {
+ return jQuery.contains( elem.ownerDocument, elem ) ||
+ elem.getRootNode( composed ) === elem.ownerDocument;
+ };
+ }
var isHiddenWithinTree = function( elem, el ) {
// isHiddenWithinTree might be called from jQuery#filter function;
@@ -4505,37 +4732,15 @@ var isHiddenWithinTree = function( elem, el ) {
// Support: Firefox <=43 - 45
// Disconnected elements can have computed display: none, so first confirm that elem is
// in the document.
- jQuery.contains( elem.ownerDocument, elem ) &&
+ isAttached( elem ) &&
jQuery.css( elem, "display" ) === "none";
};
-var swap = function( elem, options, callback, args ) {
- var ret, name,
- old = {};
-
- // Remember the old values, and insert the new ones
- for ( name in options ) {
- old[ name ] = elem.style[ name ];
- elem.style[ name ] = options[ name ];
- }
-
- ret = callback.apply( elem, args || [] );
-
- // Revert the old values
- for ( name in options ) {
- elem.style[ name ] = old[ name ];
- }
-
- return ret;
-};
-
-
function adjustCSS( elem, prop, valueParts, tween ) {
- var adjusted,
- scale = 1,
+ var adjusted, scale,
maxIterations = 20,
currentValue = tween ?
function() {
@@ -4548,35 +4753,39 @@ function adjustCSS( elem, prop, valueParts, tween ) {
unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
// Starting value computation is required for potential unit mismatches
- initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
+ initialInUnit = elem.nodeType &&
+ ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
rcssNum.exec( jQuery.css( elem, prop ) );
if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
+ // Support: Firefox <=54
+ // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
+ initial = initial / 2;
+
// Trust units reported by jQuery.css
unit = unit || initialInUnit[ 3 ];
- // Make sure we update the tween properties later on
- valueParts = valueParts || [];
-
// Iteratively approximate from a nonzero starting point
initialInUnit = +initial || 1;
- do {
-
- // If previous iteration zeroed out, double until we get *something*.
- // Use string for doubling so we don't accidentally see scale as unchanged below
- scale = scale || ".5";
+ while ( maxIterations-- ) {
- // Adjust and apply
- initialInUnit = initialInUnit / scale;
+ // Evaluate and update our best guess (doubling guesses that zero out).
+ // Finish if the scale equals or crosses 1 (making the old*new product non-positive).
jQuery.style( elem, prop, initialInUnit + unit );
+ if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {
+ maxIterations = 0;
+ }
+ initialInUnit = initialInUnit / scale;
- // Update scale, tolerating zero or NaN from tween.cur()
- // Break the loop if scale is unchanged or perfect, or if we've just had enough.
- } while (
- scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
- );
+ }
+
+ initialInUnit = initialInUnit * 2;
+ jQuery.style( elem, prop, initialInUnit + unit );
+
+ // Make sure we update the tween properties later on
+ valueParts = valueParts || [];
}
if ( valueParts ) {
@@ -4692,17 +4901,46 @@ jQuery.fn.extend( {
} );
var rcheckableType = ( /^(?:checkbox|radio)$/i );
-var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
+var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i );
-var rscriptType = ( /^$|\/(?:java|ecma)script/i );
+var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );
-// We have to close these tags to support XHTML (#13200)
-var wrapMap = {
+( function() {
+ var fragment = document.createDocumentFragment(),
+ div = fragment.appendChild( document.createElement( "div" ) ),
+ input = document.createElement( "input" );
+
+ // Support: Android 4.0 - 4.3 only
+ // Check state lost if the name is set (#11217)
+ // Support: Windows Web Apps (WWA)
+ // `name` and `type` must use .setAttribute for WWA (#14901)
+ input.setAttribute( "type", "radio" );
+ input.setAttribute( "checked", "checked" );
+ input.setAttribute( "name", "t" );
+
+ div.appendChild( input );
+
+ // Support: Android <=4.1 only
+ // Older WebKit doesn't clone checked state correctly in fragments
+ support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+ // Support: IE <=11 only
+ // Make sure textarea (and checkbox) defaultValue is properly cloned
+ div.innerHTML = "";
+ support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
// Support: IE <=9 only
- option: [ 1, "", " " ],
+ // IE <=9 replaces tags with their contents when inserted outside of
+ // the select element.
+ div.innerHTML = " ";
+ support.option = !!div.lastChild;
+} )();
+
+
+// We have to close these tags to support XHTML (#13200)
+var wrapMap = {
// XHTML parsers do not magically insert elements in the
// same way that tag soup parsers do. So we cannot shorten
@@ -4715,12 +4953,14 @@ var wrapMap = {
_default: [ 0, "", "" ]
};
-// Support: IE <=9 only
-wrapMap.optgroup = wrapMap.option;
-
wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
wrapMap.th = wrapMap.td;
+// Support: IE <=9 only
+if ( !support.option ) {
+ wrapMap.optgroup = wrapMap.option = [ 1, "", " " ];
+}
+
function getAll( context, tag ) {
@@ -4764,7 +5004,7 @@ function setGlobalEval( elems, refElements ) {
var rhtml = /<|?\w+;/;
function buildFragment( elems, context, scripts, selection, ignored ) {
- var elem, tmp, tag, wrap, contains, j,
+ var elem, tmp, tag, wrap, attached, j,
fragment = context.createDocumentFragment(),
nodes = [],
i = 0,
@@ -4776,7 +5016,7 @@ function buildFragment( elems, context, scripts, selection, ignored ) {
if ( elem || elem === 0 ) {
// Add nodes directly
- if ( jQuery.type( elem ) === "object" ) {
+ if ( toType( elem ) === "object" ) {
// Support: Android <=4.0 only, PhantomJS 1 only
// push.apply(_, arraylike) throws on ancient WebKit
@@ -4828,13 +5068,13 @@ function buildFragment( elems, context, scripts, selection, ignored ) {
continue;
}
- contains = jQuery.contains( elem.ownerDocument, elem );
+ attached = isAttached( elem );
// Append to fragment
tmp = getAll( fragment.appendChild( elem ), "script" );
// Preserve script evaluation history
- if ( contains ) {
+ if ( attached ) {
setGlobalEval( tmp );
}
@@ -4853,38 +5093,7 @@ function buildFragment( elems, context, scripts, selection, ignored ) {
}
-( function() {
- var fragment = document.createDocumentFragment(),
- div = fragment.appendChild( document.createElement( "div" ) ),
- input = document.createElement( "input" );
-
- // Support: Android 4.0 - 4.3 only
- // Check state lost if the name is set (#11217)
- // Support: Windows Web Apps (WWA)
- // `name` and `type` must use .setAttribute for WWA (#14901)
- input.setAttribute( "type", "radio" );
- input.setAttribute( "checked", "checked" );
- input.setAttribute( "name", "t" );
-
- div.appendChild( input );
-
- // Support: Android <=4.1 only
- // Older WebKit doesn't clone checked state correctly in fragments
- support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
-
- // Support: IE <=11 only
- // Make sure textarea (and checkbox) defaultValue is properly cloned
- div.innerHTML = "";
- support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
-} )();
-var documentElement = document.documentElement;
-
-
-
-var
- rkeyEvent = /^key/,
- rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
- rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
+var rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
function returnTrue() {
return true;
@@ -4894,8 +5103,19 @@ function returnFalse() {
return false;
}
+// Support: IE <=9 - 11+
+// focus() and blur() are asynchronous, except when they are no-op.
+// So expect focus to be synchronous when the element is already active,
+// and blur to be synchronous when the element is not already active.
+// (focus and blur are always synchronous in other supported browsers,
+// this just defines when we can count on it).
+function expectSync( elem, type ) {
+ return ( elem === safeActiveElement() ) === ( type === "focus" );
+}
+
// Support: IE <=9 only
-// See #13393 for more info
+// Accessing document.activeElement can throw unexpectedly
+// https://bugs.jquery.com/ticket/13393
function safeActiveElement() {
try {
return document.activeElement;
@@ -4978,8 +5198,8 @@ jQuery.event = {
special, handlers, type, namespaces, origType,
elemData = dataPriv.get( elem );
- // Don't attach events to noData or text/comment nodes (but allow plain objects)
- if ( !elemData ) {
+ // Only attach events to objects that accept data
+ if ( !acceptData( elem ) ) {
return;
}
@@ -5003,7 +5223,7 @@ jQuery.event = {
// Init the element's event structure and main handler, if this is the first
if ( !( events = elemData.events ) ) {
- events = elemData.events = {};
+ events = elemData.events = Object.create( null );
}
if ( !( eventHandle = elemData.handle ) ) {
eventHandle = elemData.handle = function( e ) {
@@ -5161,12 +5381,15 @@ jQuery.event = {
dispatch: function( nativeEvent ) {
- // Make a writable jQuery.Event from the native event object
- var event = jQuery.event.fix( nativeEvent );
-
var i, j, ret, matched, handleObj, handlerQueue,
args = new Array( arguments.length ),
- handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
+
+ // Make a writable jQuery.Event from the native event object
+ event = jQuery.event.fix( nativeEvent ),
+
+ handlers = (
+ dataPriv.get( this, "events" ) || Object.create( null )
+ )[ event.type ] || [],
special = jQuery.event.special[ event.type ] || {};
// Use the fix-ed jQuery.Event rather than the (read-only) native event
@@ -5195,9 +5418,10 @@ jQuery.event = {
while ( ( handleObj = matched.handlers[ j++ ] ) &&
!event.isImmediatePropagationStopped() ) {
- // Triggered event must either 1) have no namespace, or 2) have namespace(s)
- // a subset or equal to those in the bound event (both can have no namespace).
- if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
+ // If the event is namespaced, then each handler is only invoked if it is
+ // specially universal or its namespaces are a superset of the event's.
+ if ( !event.rnamespace || handleObj.namespace === false ||
+ event.rnamespace.test( handleObj.namespace ) ) {
event.handleObj = handleObj;
event.data = handleObj.data;
@@ -5286,15 +5510,15 @@ jQuery.event = {
enumerable: true,
configurable: true,
- get: jQuery.isFunction( hook ) ?
+ get: isFunction( hook ) ?
function() {
if ( this.originalEvent ) {
- return hook( this.originalEvent );
+ return hook( this.originalEvent );
}
} :
function() {
if ( this.originalEvent ) {
- return this.originalEvent[ name ];
+ return this.originalEvent[ name ];
}
},
@@ -5321,39 +5545,51 @@ jQuery.event = {
// Prevent triggered image.load events from bubbling to window.load
noBubble: true
},
- focus: {
+ click: {
- // Fire native event if possible so blur/focus sequence is correct
- trigger: function() {
- if ( this !== safeActiveElement() && this.focus ) {
- this.focus();
- return false;
- }
- },
- delegateType: "focusin"
- },
- blur: {
- trigger: function() {
- if ( this === safeActiveElement() && this.blur ) {
- this.blur();
- return false;
+ // Utilize native event to ensure correct state for checkable inputs
+ setup: function( data ) {
+
+ // For mutual compressibility with _default, replace `this` access with a local var.
+ // `|| data` is dead code meant only to preserve the variable through minification.
+ var el = this || data;
+
+ // Claim the first handler
+ if ( rcheckableType.test( el.type ) &&
+ el.click && nodeName( el, "input" ) ) {
+
+ // dataPriv.set( el, "click", ... )
+ leverageNative( el, "click", returnTrue );
}
+
+ // Return false to allow normal processing in the caller
+ return false;
},
- delegateType: "focusout"
- },
- click: {
+ trigger: function( data ) {
- // For checkbox, fire native event so checked state will be right
- trigger: function() {
- if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) {
- this.click();
- return false;
+ // For mutual compressibility with _default, replace `this` access with a local var.
+ // `|| data` is dead code meant only to preserve the variable through minification.
+ var el = this || data;
+
+ // Force setup before triggering a click
+ if ( rcheckableType.test( el.type ) &&
+ el.click && nodeName( el, "input" ) ) {
+
+ leverageNative( el, "click" );
}
+
+ // Return non-false to allow normal event-path propagation
+ return true;
},
- // For cross-browser consistency, don't fire native .click() on links
+ // For cross-browser consistency, suppress native .click() on links
+ // Also prevent it if we're currently inside a leveraged native-event stack
_default: function( event ) {
- return nodeName( event.target, "a" );
+ var target = event.target;
+ return rcheckableType.test( target.type ) &&
+ target.click && nodeName( target, "input" ) &&
+ dataPriv.get( target, "click" ) ||
+ nodeName( target, "a" );
}
},
@@ -5370,6 +5606,99 @@ jQuery.event = {
}
};
+// Ensure the presence of an event listener that handles manually-triggered
+// synthetic events by interrupting progress until reinvoked in response to
+// *native* events that it fires directly, ensuring that state changes have
+// already occurred before other listeners are invoked.
+function leverageNative( el, type, expectSync ) {
+
+ // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add
+ if ( !expectSync ) {
+ if ( dataPriv.get( el, type ) === undefined ) {
+ jQuery.event.add( el, type, returnTrue );
+ }
+ return;
+ }
+
+ // Register the controller as a special universal handler for all event namespaces
+ dataPriv.set( el, type, false );
+ jQuery.event.add( el, type, {
+ namespace: false,
+ handler: function( event ) {
+ var notAsync, result,
+ saved = dataPriv.get( this, type );
+
+ if ( ( event.isTrigger & 1 ) && this[ type ] ) {
+
+ // Interrupt processing of the outer synthetic .trigger()ed event
+ // Saved data should be false in such cases, but might be a leftover capture object
+ // from an async native handler (gh-4350)
+ if ( !saved.length ) {
+
+ // Store arguments for use when handling the inner native event
+ // There will always be at least one argument (an event object), so this array
+ // will not be confused with a leftover capture object.
+ saved = slice.call( arguments );
+ dataPriv.set( this, type, saved );
+
+ // Trigger the native event and capture its result
+ // Support: IE <=9 - 11+
+ // focus() and blur() are asynchronous
+ notAsync = expectSync( this, type );
+ this[ type ]();
+ result = dataPriv.get( this, type );
+ if ( saved !== result || notAsync ) {
+ dataPriv.set( this, type, false );
+ } else {
+ result = {};
+ }
+ if ( saved !== result ) {
+
+ // Cancel the outer synthetic event
+ event.stopImmediatePropagation();
+ event.preventDefault();
+
+ // Support: Chrome 86+
+ // In Chrome, if an element having a focusout handler is blurred by
+ // clicking outside of it, it invokes the handler synchronously. If
+ // that handler calls `.remove()` on the element, the data is cleared,
+ // leaving `result` undefined. We need to guard against this.
+ return result && result.value;
+ }
+
+ // If this is an inner synthetic event for an event with a bubbling surrogate
+ // (focus or blur), assume that the surrogate already propagated from triggering the
+ // native event and prevent that from happening again here.
+ // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the
+ // bubbling surrogate propagates *after* the non-bubbling base), but that seems
+ // less bad than duplication.
+ } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {
+ event.stopPropagation();
+ }
+
+ // If this is a native event triggered above, everything is now in order
+ // Fire an inner synthetic event with the original arguments
+ } else if ( saved.length ) {
+
+ // ...and capture the result
+ dataPriv.set( this, type, {
+ value: jQuery.event.trigger(
+
+ // Support: IE <=9 - 11+
+ // Extend with the prototype to reset the above stopImmediatePropagation()
+ jQuery.extend( saved[ 0 ], jQuery.Event.prototype ),
+ saved.slice( 1 ),
+ this
+ )
+ } );
+
+ // Abort handling of the native event
+ event.stopImmediatePropagation();
+ }
+ }
+ } );
+}
+
jQuery.removeEvent = function( elem, type, handle ) {
// This "if" is needed for plain objects
@@ -5421,7 +5750,7 @@ jQuery.Event = function( src, props ) {
}
// Create a timestamp if incoming event doesn't have one
- this.timeStamp = src && src.timeStamp || jQuery.now();
+ this.timeStamp = src && src.timeStamp || Date.now();
// Mark it as fixed
this[ jQuery.expando ] = true;
@@ -5482,6 +5811,7 @@ jQuery.each( {
shiftKey: true,
view: true,
"char": true,
+ code: true,
charCode: true,
key: true,
keyCode: true,
@@ -5498,35 +5828,41 @@ jQuery.each( {
targetTouches: true,
toElement: true,
touches: true,
+ which: true
+}, jQuery.event.addProp );
+
+jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) {
+ jQuery.event.special[ type ] = {
- which: function( event ) {
- var button = event.button;
+ // Utilize native event if possible so blur/focus sequence is correct
+ setup: function() {
- // Add which for key events
- if ( event.which == null && rkeyEvent.test( event.type ) ) {
- return event.charCode != null ? event.charCode : event.keyCode;
- }
+ // Claim the first handler
+ // dataPriv.set( this, "focus", ... )
+ // dataPriv.set( this, "blur", ... )
+ leverageNative( this, type, expectSync );
- // Add which for click: 1 === left; 2 === middle; 3 === right
- if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
- if ( button & 1 ) {
- return 1;
- }
+ // Return false to allow normal processing in the caller
+ return false;
+ },
+ trigger: function() {
- if ( button & 2 ) {
- return 3;
- }
+ // Force setup before trigger
+ leverageNative( this, type );
- if ( button & 4 ) {
- return 2;
- }
+ // Return non-false to allow normal event-path propagation
+ return true;
+ },
- return 0;
- }
+ // Suppress native focus or blur as it's already being fired
+ // in leverageNative.
+ _default: function() {
+ return true;
+ },
- return event.which;
- }
-}, jQuery.event.addProp );
+ delegateType: delegateType
+ };
+} );
// Create mouseenter/leave events using mouseover/out and event-time checks
// so that event delegation works in jQuery.
@@ -5613,21 +5949,13 @@ jQuery.fn.extend( {
var
- /* eslint-disable max-len */
-
- // See https://github.com/eslint/eslint/issues/3229
- rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
-
- /* eslint-enable */
-
- // Support: IE <=10 - 11, Edge 12 - 13
+ // Support: IE <=10 - 11, Edge 12 - 13 only
// In IE/Edge using regex groups here causes severe slowdowns.
// See https://connect.microsoft.com/IE/feedback/details/1736512/
rnoInnerhtml = /
+ <% end %>
diff --git a/source/stylesheets/_normalize.scss b/source/stylesheets/_normalize.scss
index 46f646a5c00..a38db2a1001 100644
--- a/source/stylesheets/_normalize.scss
+++ b/source/stylesheets/_normalize.scss
@@ -1,4 +1,4 @@
-/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
+/*! normalize.css v3.0.2 | MIT License | github.com/necolas/normalize.css */
/**
* 1. Set default font family to sans-serif.
diff --git a/source/stylesheets/print.css.scss b/source/stylesheets/print.css.scss
index adf8b66bd5f..aea88c3065d 100644
--- a/source/stylesheets/print.css.scss
+++ b/source/stylesheets/print.css.scss
@@ -144,4 +144,10 @@ body {
aside.success:before {
@extend %icon-ok-sign;
}
-}
\ No newline at end of file
+}
+
+.copy-clipboard {
+ @media print {
+ display: none
+ }
+}
diff --git a/source/stylesheets/screen.css.scss b/source/stylesheets/screen.css.scss
index 83da68cca2c..0ce124e14da 100644
--- a/source/stylesheets/screen.css.scss
+++ b/source/stylesheets/screen.css.scss
@@ -278,12 +278,13 @@ html, body {
}
.lang-selector {
+ display: flex;
background-color: $lang-select-bg;
width: 100%;
font-weight: bold;
+ overflow-x: auto;
a {
- display: block;
- float:left;
+ display: inline;
color: $lang-select-text;
text-decoration: none;
padding: 0 10px;
@@ -511,6 +512,10 @@ html, body {
// This is all the stuff that appears in the right half of the page
.content {
+ &>div.highlight {
+ clear:none;
+ }
+
pre, blockquote {
background-color: $code-bg;
color: #fff;
@@ -604,6 +609,10 @@ html, body {
%right-col + %left-col {
margin-top: $main-padding;
}
+
+ .highlight + p {
+ margin-top: 20px;
+ }
}
.highlight .c, .highlight .cm, .highlight .c1, .highlight .cs {
@@ -613,3 +622,16 @@ html, body {
.highlight, .highlight .w {
background-color: $code-bg;
}
+
+.copy-clipboard {
+ float: right;
+ fill: #9DAAB6;
+ cursor: pointer;
+ opacity: 0.4;
+ height: 18px;
+ width: 18px;
+}
+
+.copy-clipboard:hover {
+ opacity: 0.8;
+}