overhauled completely
|
@ -0,0 +1,114 @@
|
||||||
|
### About
|
||||||
|
This is the code for the website [https://investigating-archiving-git.gitlab.io/](https://investigating-archiving-git.gitlab.io/), an informational site for the Sloan-funded project, "Investigating and Archiving the Scholarly Git Experience." This site is built using [Nikola](https://getnikola.com/), a static site generator that relies on python3. The instructions for compiling and building the website are below.
|
||||||
|
|
||||||
|
### Building
|
||||||
|
I would recommend you use a virtualenv to build and view this website. This is a Python tool to create isolated Python environments. The HitchHiker's Guide to Python has a [great guide](http://docs.python-guide.org/en/latest/dev/virtualenvs/) on virtual environments that I used to learn how to use/interact with virtualenvs.
|
||||||
|
|
||||||
|
Here's how to make and activate a virtual environment:
|
||||||
|
<pre><code># install the tool virtualenv
|
||||||
|
$ pip install virtualenv
|
||||||
|
|
||||||
|
# create the Python 3 virtual environment
|
||||||
|
$ virtualenv -p python3 venv
|
||||||
|
|
||||||
|
# activate the virtual environment
|
||||||
|
$ source venv/bin/activate
|
||||||
|
</pre></code>
|
||||||
|
|
||||||
|
Now, you can get started and install all of the dependecies of this site in its own environment:
|
||||||
|
|
||||||
|
<pre><code># install the dependencies
|
||||||
|
$ pip install Nikola['extras']
|
||||||
|
|
||||||
|
# clone this repo
|
||||||
|
$ git clone git@gitlab.com:VickySteeves/investigating-archiving-git.gitlab.io.git
|
||||||
|
|
||||||
|
# change directory (cd) so you are in the right folder for the website
|
||||||
|
$ cd investigating-archiving-git.gitlab.io
|
||||||
|
|
||||||
|
# build the website
|
||||||
|
$ nikola build
|
||||||
|
|
||||||
|
# see the website
|
||||||
|
$ nikola serve -b
|
||||||
|
</pre></code>
|
||||||
|
|
||||||
|
### Authoring Blog Posts
|
||||||
|
|
||||||
|
All blog posts should go in the `updates` folder. Blog posts should be Text (`.txt`), reStructured Text (`.rst`), Markdown (`.md`), or `.html`. If you'd like to write a post in another format, you'll have to edit the `conf.py` [file](https://gitlab.com/investigating-archiving-git/investigating-archiving-git.gitlab.io/blob/master/conf.py) to add other [accepted input formats](https://getnikola.com/handbook.html#supported-input-formats), starting at [line 126](https://gitlab.com/investigating-archiving-git/investigating-archiving-git.gitlab.io/blob/master/conf.py#L126).
|
||||||
|
|
||||||
|
When you author blog posts, you should always have the following metadata at the beginning of the file:
|
||||||
|
|
||||||
|
+ Title -- this is what appears on the live post
|
||||||
|
+ Slug -- the end of the URL to the post. It should have no spaces, only Aa-Zz, 0-9, -, and _
|
||||||
|
+ Date -- YYYY-MM-DD
|
||||||
|
+ Author -- keep your name consistent with every post, please!
|
||||||
|
+ Link -- this will go to the source link for the post on GitLab (should look like: https://gitlab.com/investigating-archiving-git/investigating-archiving-git.gitlab.io/blob/master/updates/2019-05-06.html)
|
||||||
|
+ Description -- this is used for SEO purposes, so a small description of the post
|
||||||
|
+ Type -- Nikola has [two post types](https://getnikola.com/handbook.html#post-types). For our purposes, we'll always use `text`.
|
||||||
|
|
||||||
|
If your posts are in HTML, they should look something like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
<!--
|
||||||
|
.. title:
|
||||||
|
.. slug:
|
||||||
|
.. date:
|
||||||
|
.. author:
|
||||||
|
.. link:
|
||||||
|
.. description:
|
||||||
|
.. type: text
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<p>Content of your post</p>
|
||||||
|
|
||||||
|
<img src="/images/something.png">
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Here is a guide to writing basic HTML: https://www.w3schools.com/html/html_basic.asp
|
||||||
|
|
||||||
|
For Markdown, text, and reStructred Text, it should look something like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
.. title:
|
||||||
|
.. slug:
|
||||||
|
.. date:
|
||||||
|
.. author:
|
||||||
|
.. link:
|
||||||
|
.. description:
|
||||||
|
.. type: text
|
||||||
|
|
||||||
|
Content of your post
|
||||||
|
|
||||||
|
.. image:: /images/something.png
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
There are a few handy guides for writing in these formats as well:
|
||||||
|
|
||||||
|
+ Markdown: https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet
|
||||||
|
+ reStructured Text: https://github.com/ralsina/rst-cheatsheet/blob/master/rst-cheatsheet.rst
|
||||||
|
|
||||||
|
All image files for the blog posts should go into the `images` folder. Make sure when you reference your image from the post, you add the `/` before the calling the images folder to help Nikola find it.
|
||||||
|
|
||||||
|
If you don't want to show the complete content of your post in the blog index and RSS feed, you can display just the beginning of them using the `TEASER` magical comment. The Nikola documentation provides a way to do this for each type of post here: https://getnikola.com/handbook.html#teasers. I usually do this to make reading the blog index easier.
|
||||||
|
|
||||||
|
When you're done authoring the blog posts and want to preview it locally, build and serve the website the same way you would otherwise:
|
||||||
|
|
||||||
|
```
|
||||||
|
# build the website
|
||||||
|
$ nikola build
|
||||||
|
|
||||||
|
# browser pops up and shows site
|
||||||
|
$ nikola serve -b
|
||||||
|
```
|
||||||
|
|
||||||
|
Happy writing!
|
225
conf.py
|
@ -5,110 +5,20 @@ import time
|
||||||
# !! This is the configuration of Nikola. !! #
|
# !! This is the configuration of Nikola. !! #
|
||||||
# !! You should edit it to your liking. !! #
|
# !! You should edit it to your liking. !! #
|
||||||
|
|
||||||
|
|
||||||
# ! Some settings can be different in different languages.
|
|
||||||
# ! A comment stating (translatable) is used to denote those.
|
|
||||||
# ! There are two ways to specify a translatable setting:
|
|
||||||
# ! (a) BLOG_TITLE = "My Blog"
|
|
||||||
# ! (b) BLOG_TITLE = {"en": "My Blog", "es": "Mi Blog"}
|
|
||||||
# ! Option (a) is used when you don't want that setting translated.
|
|
||||||
# ! Option (b) is used for settings that are different in different languages.
|
|
||||||
|
|
||||||
# Data about this site
|
# Data about this site
|
||||||
BLOG_AUTHOR = "LISSA Advisory Board" # (translatable)
|
BLOG_AUTHOR = "LISSA Steering Committee" # (translatable)
|
||||||
BLOG_TITLE = "LIS Scholarship Archive" # (translatable)
|
BLOG_TITLE = "LISSA" # (translatable)
|
||||||
# This is the main URL for your site. It will be used
|
# This is the main URL for your site. It will be used
|
||||||
# in a prominent link. Don't forget the protocol (http/https)!
|
# in a prominent link. Don't forget the protocol (http/https)!
|
||||||
SITE_URL = "https://lissarchive.org/"
|
SITE_URL = "https://lissarchive.org/"
|
||||||
# This is the URL where Nikola's output will be deployed.
|
# This is the URL where Nikola's output will be deployed.
|
||||||
# If not set, defaults to SITE_URL
|
# If not set, defaults to SITE_URL
|
||||||
# BASE_URL = "https://lissarchive.org/"
|
|
||||||
BLOG_EMAIL = "lissarchive@gmail.com"
|
BLOG_EMAIL = "lissarchive@gmail.com"
|
||||||
BLOG_DESCRIPTION = "An informational website for the LIS Scholarship Archive" # (translatable)
|
BLOG_DESCRIPTION = "An informational website for the LIS Scholarship Archive" # (translatable)
|
||||||
|
|
||||||
|
|
||||||
# Nikola is multilingual!
|
|
||||||
#
|
|
||||||
# Currently supported languages are:
|
|
||||||
#
|
|
||||||
# en English
|
|
||||||
# ar Arabic
|
|
||||||
# az Azerbaijani
|
|
||||||
# bg Bulgarian
|
|
||||||
# bs Bosnian
|
|
||||||
# ca Catalan
|
|
||||||
# cs Czech [ALTERNATIVELY cz]
|
|
||||||
# da Danish
|
|
||||||
# de German
|
|
||||||
# el Greek [NOT gr]
|
|
||||||
# eo Esperanto
|
|
||||||
# es Spanish
|
|
||||||
# et Estonian
|
|
||||||
# eu Basque
|
|
||||||
# fa Persian
|
|
||||||
# fi Finnish
|
|
||||||
# fr French
|
|
||||||
# gl Galician
|
|
||||||
# he Hebrew
|
|
||||||
# hi Hindi
|
|
||||||
# hr Croatian
|
|
||||||
# hu Hungarian
|
|
||||||
# id Indonesian
|
|
||||||
# it Italian
|
|
||||||
# ja Japanese [NOT jp]
|
|
||||||
# ko Korean
|
|
||||||
# lt Lithuanian
|
|
||||||
# ml Malayalam
|
|
||||||
# nb Norwegian (Bokmål)
|
|
||||||
# nl Dutch
|
|
||||||
# pa Punjabi
|
|
||||||
# pl Polish
|
|
||||||
# pt Portuguese
|
|
||||||
# pt_br Portuguese (Brazil)
|
|
||||||
# ru Russian
|
|
||||||
# sk Slovak
|
|
||||||
# sl Slovene
|
|
||||||
# sq Albanian
|
|
||||||
# sr Serbian (Cyrillic)
|
|
||||||
# sr_latin Serbian (Latin)
|
|
||||||
# sv Swedish
|
|
||||||
# te Telugu
|
|
||||||
# th Thai
|
|
||||||
# tr Turkish [NOT tr_TR]
|
|
||||||
# uk Ukrainian
|
|
||||||
# ur Urdu
|
|
||||||
# vi Vietnamese
|
|
||||||
# zh_cn Chinese (Simplified)
|
|
||||||
# zh_tw Chinese (Traditional)
|
|
||||||
#
|
|
||||||
# If you want to use Nikola with a non-supported language you have to provide
|
|
||||||
# a module containing the necessary translations
|
|
||||||
# (cf. the modules at nikola/data/themes/base/messages/).
|
|
||||||
# If a specific post is not translated to a language, then the version
|
|
||||||
# in the default language will be shown instead.
|
|
||||||
|
|
||||||
# What is the default language?
|
# What is the default language?
|
||||||
DEFAULT_LANG = "en"
|
DEFAULT_LANG = "en"
|
||||||
|
|
||||||
# What other languages do you have?
|
|
||||||
# The format is {"translationcode" : "path/to/translation" }
|
|
||||||
# the path will be used as a prefix for the generated pages location
|
|
||||||
TRANSLATIONS = {
|
|
||||||
DEFAULT_LANG: "",
|
|
||||||
# Example for another language:
|
|
||||||
# "es": "./es",
|
|
||||||
}
|
|
||||||
|
|
||||||
# What will translated input files be named like?
|
|
||||||
|
|
||||||
# If you have a page something.rst, then something.pl.rst will be considered
|
|
||||||
# its Polish translation.
|
|
||||||
# (in the above example: path == "something", ext == "rst", lang == "pl")
|
|
||||||
# this pattern is also used for metadata:
|
|
||||||
# something.meta -> something.pl.meta
|
|
||||||
|
|
||||||
TRANSLATIONS_PATTERN = '{path}.{lang}.{ext}'
|
|
||||||
|
|
||||||
# Links for the sidebar / navigation bar. (translatable)
|
# Links for the sidebar / navigation bar. (translatable)
|
||||||
# This is a dict. The keys are languages, and values are tuples.
|
# This is a dict. The keys are languages, and values are tuples.
|
||||||
#
|
#
|
||||||
|
@ -135,32 +45,30 @@ TRANSLATIONS_PATTERN = '{path}.{lang}.{ext}'
|
||||||
# else they won’t be highlighted when active.
|
# else they won’t be highlighted when active.
|
||||||
|
|
||||||
NAVIGATION_LINKS = {
|
NAVIGATION_LINKS = {
|
||||||
DEFAULT_LANG: (
|
DEFAULT_LANG: (
|
||||||
("/", "Home"),
|
(
|
||||||
(
|
(
|
||||||
(
|
('/about/', 'Mission'),
|
||||||
('/about/', 'Mission'),
|
('/guidelines/', 'Submission Guidelines'),
|
||||||
('/guidelines/', 'Submission Guidelines'),
|
('/faq/', 'FAQ'),
|
||||||
('/faq/', 'FAQ'),
|
('/steering-committee/', 'Steering Committee'),
|
||||||
('/steering-committee/', 'Steering Committee'),
|
('/contact/', 'Contact'),
|
||||||
('/contact/', 'Contact'),
|
),
|
||||||
),
|
'About'
|
||||||
'About'
|
),
|
||||||
),
|
('/updates/', 'Updates'),
|
||||||
('/updates/', 'Updates'),
|
('https://osf.io/preprints/lissa/discover','Discover Works <i class="fas fa-external-link-alt"></i>'),
|
||||||
('https://osf.io/preprints/lissa/discover','Discover Works <i class="fas fa-external-link-alt"></i>'),
|
('https://osf.io/preprints/lissa/submit','Submit <i class="fas fa-external-link-alt"></i>'),
|
||||||
('https://osf.io/preprints/lissa/submit','Submit <i class="fas fa-external-link-alt"></i>')
|
)
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Alternative navigation links. Works the same way NAVIGATION_LINKS does,
|
# Alternative navigation links. Works the same way NAVIGATION_LINKS does,
|
||||||
# although themes may not always support them. (translatable)
|
# although themes may not always support them. (translatable)
|
||||||
# (Bootstrap 4: right-side of navbar, Bootblog 4: right side of title)
|
# (Bootstrap 4: right-side of navbar, Bootblog 4: right side of title)
|
||||||
NAVIGATION_ALT_LINKS = {
|
NAVIGATION_ALT_LINKS = {
|
||||||
DEFAULT_LANG: {
|
DEFAULT_LANG: {
|
||||||
('https://twitter.com/lissarchive','<i class="fab fa-twitter"></i>'),
|
('/rss.xml','<i class="fas fa-rss"></i> <span class="d-md-none">RSS</span>'),
|
||||||
('mailto:lissarchive@gmail.com','<i class="far fa-envelope"></i>'),
|
('https://gitlab.com/VickySteeves/lissarchive','<i class="fab fa-gitlab"></i> <span class="d-md-none">GitLab</span>')
|
||||||
('https://lissarchive.org/rss.xml','<i class="fas fa-rss"></i>'),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +98,7 @@ THEME_CONFIG = {
|
||||||
# Strip HTML from featured post text.
|
# Strip HTML from featured post text.
|
||||||
'featured_strip_html': False,
|
'featured_strip_html': False,
|
||||||
# Contents of the sidebar, If empty, the sidebar is not displayed.
|
# Contents of the sidebar, If empty, the sidebar is not displayed.
|
||||||
'sidebar': ''
|
'sidebar': '',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,11 +137,12 @@ THEME_CONFIG = {
|
||||||
# )
|
# )
|
||||||
|
|
||||||
POSTS = (
|
POSTS = (
|
||||||
("posts/*.rst", "updates", "post.tmpl"),
|
("updates/*.rst", "updates", "post.tmpl"),
|
||||||
("posts/*.md", "updates", "post.tmpl"),
|
("updates/*.md", "updates", "post.tmpl"),
|
||||||
("posts/*.txt", "updates", "post.tmpl"),
|
("updates/*.txt", "updates", "post.tmpl"),
|
||||||
("posts/*.html", "updates", "post.tmpl"),
|
("updates/*.html", "updates", "post.tmpl"),
|
||||||
)
|
)
|
||||||
|
|
||||||
PAGES = (
|
PAGES = (
|
||||||
("pages/*.rst", "", "page.tmpl"),
|
("pages/*.rst", "", "page.tmpl"),
|
||||||
("pages/*.md", "", "page.tmpl"),
|
("pages/*.md", "", "page.tmpl"),
|
||||||
|
@ -241,7 +150,6 @@ PAGES = (
|
||||||
("pages/*.html", "", "page.tmpl"),
|
("pages/*.html", "", "page.tmpl"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# Below this point, everything is optional
|
# Below this point, everything is optional
|
||||||
|
|
||||||
# Post's dates are considered in UTC by default, if you want to use
|
# Post's dates are considered in UTC by default, if you want to use
|
||||||
|
@ -256,12 +164,12 @@ TIMEZONE = "America/New_York"
|
||||||
# If you want to use ISO 8601 (also valid RFC 3339) throughout Nikola
|
# If you want to use ISO 8601 (also valid RFC 3339) throughout Nikola
|
||||||
# (especially in new_post), set this to True.
|
# (especially in new_post), set this to True.
|
||||||
# Note that this does not affect DATE_FORMAT.
|
# Note that this does not affect DATE_FORMAT.
|
||||||
# FORCE_ISO8601 = False
|
FORCE_ISO8601 = True
|
||||||
|
|
||||||
# Date format used to display post dates. (translatable)
|
# Date format used to display post dates. (translatable)
|
||||||
# Used by babel.dates, CLDR style: http://cldr.unicode.org/translation/date-time
|
# Used by babel.dates, CLDR style: http://cldr.unicode.org/translation/date-time
|
||||||
# You can also use 'full', 'long', 'medium', or 'short'
|
# You can also use 'full', 'long', 'medium', or 'short'
|
||||||
DATE_FORMAT = 'dd-MM-YYYY'
|
DATE_FORMAT = 'YYYY-MM-dd'
|
||||||
|
|
||||||
# Date format used to display post dates, if local dates are used. (translatable)
|
# Date format used to display post dates, if local dates are used. (translatable)
|
||||||
# Used by moment.js: https://momentjs.com/docs/#/displaying/format/
|
# Used by moment.js: https://momentjs.com/docs/#/displaying/format/
|
||||||
|
@ -347,7 +255,7 @@ COMPILERS = {
|
||||||
# Nikola supports logo display. If you have one, you can put the URL here.
|
# Nikola supports logo display. If you have one, you can put the URL here.
|
||||||
# Final output is <img src="LOGO_URL" id="logo" alt="BLOG_TITLE">.
|
# Final output is <img src="LOGO_URL" id="logo" alt="BLOG_TITLE">.
|
||||||
# The URL may be relative to the site root.
|
# The URL may be relative to the site root.
|
||||||
LOGO_URL = '/images/lis-schol-archive-navbar-white.png'
|
LOGO_URL = '/images/logo.png'
|
||||||
|
|
||||||
# If you want to hide the title of your website (for example, if your logo
|
# If you want to hide the title of your website (for example, if your logo
|
||||||
# already contains the text), set this to False.
|
# already contains the text), set this to False.
|
||||||
|
@ -514,29 +422,27 @@ HIDDEN_CATEGORIES = []
|
||||||
|
|
||||||
# If ENABLE_AUTHOR_PAGES is set to True and there is more than one
|
# If ENABLE_AUTHOR_PAGES is set to True and there is more than one
|
||||||
# author, author pages are generated.
|
# author, author pages are generated.
|
||||||
# ENABLE_AUTHOR_PAGES = True
|
ENABLE_AUTHOR_PAGES = True
|
||||||
|
|
||||||
# Path to author pages. Final locations are:
|
# Path to author pages. Final locations are:
|
||||||
# output / TRANSLATION[lang] / AUTHOR_PATH / index.html (list of authors)
|
# output / TRANSLATION[lang] / AUTHOR_PATH / index.html (list of authors)
|
||||||
# output / TRANSLATION[lang] / AUTHOR_PATH / author.html (list of posts by an author)
|
# output / TRANSLATION[lang] / AUTHOR_PATH / author.html (list of posts by an author)
|
||||||
# output / TRANSLATION[lang] / AUTHOR_PATH / author RSS_EXTENSION (RSS feed for an author)
|
# output / TRANSLATION[lang] / AUTHOR_PATH / author RSS_EXTENSION (RSS feed for an author)
|
||||||
# (translatable)
|
# (translatable)
|
||||||
# AUTHOR_PATH = "authors"
|
AUTHOR_PATH = "authors"
|
||||||
|
|
||||||
# If AUTHOR_PAGES_ARE_INDEXES is set to True, each author's page will contain
|
# If AUTHOR_PAGES_ARE_INDEXES is set to True, each author's page will contain
|
||||||
# the posts themselves. If set to False, it will be just a list of links.
|
# the posts themselves. If set to False, it will be just a list of links.
|
||||||
# AUTHOR_PAGES_ARE_INDEXES = False
|
AUTHOR_PAGES_ARE_INDEXES = False
|
||||||
|
|
||||||
# Set descriptions for author pages to make them more interesting. The
|
# Set descriptions for author pages to make them more interesting. The
|
||||||
# default is no description. The value is used in the meta description
|
# default is no description. The value is used in the meta description
|
||||||
# and displayed underneath the author list or index page’s title.
|
# and displayed underneath the author list or index page’s title.
|
||||||
# AUTHOR_PAGES_DESCRIPTIONS = {
|
AUTHOR_PAGES_DESCRIPTIONS = {
|
||||||
# DEFAULT_LANG: {
|
DEFAULT_LANG: {
|
||||||
# "Juanjo Conti": "Python coder and writer.",
|
|
||||||
# "Roberto Alsina": "Nikola father."
|
|
||||||
# },
|
|
||||||
# }
|
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
# If you do not want to display an author publicly, you can mark it as hidden.
|
# If you do not want to display an author publicly, you can mark it as hidden.
|
||||||
# The author will not be displayed on the author list page and posts.
|
# The author will not be displayed on the author list page and posts.
|
||||||
|
@ -641,20 +547,6 @@ REDIRECTIONS = []
|
||||||
# ]
|
# ]
|
||||||
# }
|
# }
|
||||||
|
|
||||||
# github_deploy configuration
|
|
||||||
# For more details, read the manual:
|
|
||||||
# https://getnikola.com/handbook.html#deploying-to-github
|
|
||||||
# You will need to configure the deployment branch on GitHub.
|
|
||||||
# GITHUB_SOURCE_BRANCH = 'src'
|
|
||||||
# GITHUB_DEPLOY_BRANCH = 'master'
|
|
||||||
|
|
||||||
# The name of the remote where you wish to push to, using github_deploy.
|
|
||||||
# GITHUB_REMOTE_NAME = 'origin'
|
|
||||||
|
|
||||||
# Whether or not github_deploy should commit to the source branch automatically
|
|
||||||
# before deploying.
|
|
||||||
# GITHUB_COMMIT_SOURCE = True
|
|
||||||
|
|
||||||
# Where the output site should be located
|
# Where the output site should be located
|
||||||
# If you don't use an absolute path, it will be considered as relative
|
# If you don't use an absolute path, it will be considered as relative
|
||||||
# to the location of conf.py
|
# to the location of conf.py
|
||||||
|
@ -889,8 +781,8 @@ IMAGE_FOLDERS = {'images': 'images'}
|
||||||
# Used to create favicon link like this:
|
# Used to create favicon link like this:
|
||||||
# <link rel="name" href="file" sizes="size"/>
|
# <link rel="name" href="file" sizes="size"/>
|
||||||
FAVICONS = (
|
FAVICONS = (
|
||||||
("icon", "/favicon.ico", "16x16"),
|
("icon", "/favicon.ico", "16x16"),
|
||||||
("icon", "/icon_128x128.png", "128x128"),
|
("icon", "/icon_128x128.png", "128x128"),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Show teasers (instead of full posts) in indexes? Defaults to False.
|
# Show teasers (instead of full posts) in indexes? Defaults to False.
|
||||||
|
@ -925,19 +817,16 @@ FEED_READ_MORE_LINK = '<p><a href="{link}">{read_more}…</a> ({min_remaining_re
|
||||||
FEED_LINKS_APPEND_QUERY = False
|
FEED_LINKS_APPEND_QUERY = False
|
||||||
|
|
||||||
# A HTML fragment describing the license, for the sidebar.
|
# A HTML fragment describing the license, for the sidebar.
|
||||||
# (translatable)
|
# (translatable) I recommend using the Creative Commons' wizard:
|
||||||
LICENSE = '<a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>'
|
|
||||||
# I recommend using the Creative Commons' wizard:
|
|
||||||
# https://creativecommons.org/choose/
|
# https://creativecommons.org/choose/
|
||||||
# LICENSE = """
|
LICENSE = """<a rel="license" href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
|
||||||
# <a rel="license" href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
|
<img alt="Creative Commons License BY-NC-SA"
|
||||||
# <img alt="Creative Commons License BY-NC-SA"
|
style="border-width:0; margin-bottom:12px;"
|
||||||
# style="border-width:0; margin-bottom:12px;"
|
src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png"></a>"""
|
||||||
# src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png"></a>"""
|
|
||||||
|
|
||||||
# A small copyright notice for the page footer (in HTML).
|
# A small copyright notice for the page footer (in HTML).
|
||||||
# (translatable)
|
# (translatable)
|
||||||
CONTENT_FOOTER = 'Original content on this site has a {license} {date} | <a href="mailto:{email}"><i class="far fa-envelope"></i></a> <a href="https://lissarchive.org/rss.xml"><i class="fas fa-rss"></i></a> <a href="https://twitter.com/lissarchive"><i class="fab fa-twitter"></i></a></a>'
|
CONTENT_FOOTER = 'Original contents licensed {license} {date}. Please email quesitons/comments to <a href="mailto:{email}">{author}</a>.'
|
||||||
|
|
||||||
# Things that will be passed to CONTENT_FOOTER.format(). This is done
|
# Things that will be passed to CONTENT_FOOTER.format(). This is done
|
||||||
# for translatability, as dicts are not formattable. Nikola will
|
# for translatability, as dicts are not formattable. Nikola will
|
||||||
|
@ -966,8 +855,8 @@ CONTENT_FOOTER_FORMATS = {
|
||||||
|
|
||||||
# A simple copyright tag for inclusion in RSS feeds that works just
|
# A simple copyright tag for inclusion in RSS feeds that works just
|
||||||
# like CONTENT_FOOTER and CONTENT_FOOTER_FORMATS
|
# like CONTENT_FOOTER and CONTENT_FOOTER_FORMATS
|
||||||
RSS_COPYRIGHT = 'Contents <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a> {date} <a href="mailto:{email}">{author}</a> {license}'
|
RSS_COPYRIGHT = 'Contents © {date} <a href="mailto:{email}">{author}</a> {license}'
|
||||||
RSS_COPYRIGHT_PLAIN = 'Contents <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a> {date} {author} {license}'
|
RSS_COPYRIGHT_PLAIN = 'Contents © {date} {author} {license}'
|
||||||
RSS_COPYRIGHT_FORMATS = CONTENT_FOOTER_FORMATS
|
RSS_COPYRIGHT_FORMATS = CONTENT_FOOTER_FORMATS
|
||||||
|
|
||||||
# To use comments, you can choose between different third party comment
|
# To use comments, you can choose between different third party comment
|
||||||
|
@ -1121,7 +1010,7 @@ SHOW_SOURCELINK = False
|
||||||
|
|
||||||
# Modify the number of Post per Index Page
|
# Modify the number of Post per Index Page
|
||||||
# Defaults to 10
|
# Defaults to 10
|
||||||
# INDEX_DISPLAY_POST_COUNT = 10
|
INDEX_DISPLAY_POST_COUNT = 5
|
||||||
|
|
||||||
# By default, Nikola generates RSS files for the website and for tags, and
|
# By default, Nikola generates RSS files for the website and for tags, and
|
||||||
# links to it. Set this to False to disable everything RSS-related.
|
# links to it. Set this to False to disable everything RSS-related.
|
||||||
|
@ -1138,7 +1027,7 @@ SHOW_SOURCELINK = False
|
||||||
|
|
||||||
# Only include teasers in Atom and RSS feeds. Disabling include the full
|
# Only include teasers in Atom and RSS feeds. Disabling include the full
|
||||||
# content. Defaults to True.
|
# content. Defaults to True.
|
||||||
# FEED_TEASERS = True
|
FEED_TEASERS = False
|
||||||
|
|
||||||
# Strip HTML from Atom and RSS feed summaries and content. Defaults to False.
|
# Strip HTML from Atom and RSS feed summaries and content. Defaults to False.
|
||||||
# FEED_PLAIN = False
|
# FEED_PLAIN = False
|
||||||
|
@ -1212,23 +1101,7 @@ SHOW_SOURCELINK = False
|
||||||
# Google Analytics or whatever else you use. Added to the bottom of <body>
|
# Google Analytics or whatever else you use. Added to the bottom of <body>
|
||||||
# in the default template (base.tmpl).
|
# in the default template (base.tmpl).
|
||||||
# (translatable)
|
# (translatable)
|
||||||
BODY_END = """
|
# BODY_END = ""
|
||||||
<!-- Matomo -->
|
|
||||||
<script type='text/javascript'>
|
|
||||||
var _paq = window._paq || [];
|
|
||||||
/* tracker methods like 'setCustomDimension" should be called before 'trackPageView' */
|
|
||||||
_paq.push(['trackPageView']);
|
|
||||||
_paq.push(['enableLinkTracking']);
|
|
||||||
(function() {
|
|
||||||
var u='//analytics.vickysteeves.hosting.nyu.edu/';
|
|
||||||
_paq.push(['setTrackerUrl', u+'matomo.php']);
|
|
||||||
_paq.push(['setSiteId', '4']);
|
|
||||||
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
|
||||||
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
<noscript><p><img src='//analytics.vickysteeves.hosting.nyu.edu/matomo.php?idsite=4&rec=1' style='border:0;' alt='' /></p></noscript>
|
|
||||||
<!-- End Matomo Code -->"""
|
|
||||||
|
|
||||||
# The possibility to extract metadata from the filename by using a
|
# The possibility to extract metadata from the filename by using a
|
||||||
# regular expression.
|
# regular expression.
|
||||||
|
|
Before Width: | Height: | Size: 422 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 28 KiB |
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
<p>We welcome content from the library and information science (LIS) community and allied fields, including but not limited to:</p>
|
<p>We welcome content from the library and information science (LIS) community and allied fields, including but not limited to:</p>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row mx-auto">
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-3">
|
<div class="col-xs-3">
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
<!--
|
||||||
|
.. title: LIS Scholarship Archive
|
||||||
|
.. slug: index
|
||||||
|
.. date: 2018-11-05 14:28:00 UTC-04:00
|
||||||
|
.. hidetitle: True
|
||||||
|
.. description: homepage for LIS Scholarship Archive informational website.
|
||||||
|
.. type: text
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="jumbotron">
|
||||||
|
<h1 class="display-4 text-center">The LIS Scholarship Archive</h1>
|
||||||
|
<p class="lead text-center">A free, open scholarly platform for library and information science</p>
|
||||||
|
<p>LISSA is a place where anyone can have access to library and information science scholarship, in all its forms. As librarians and archivists, we are committed to service permanence, sustainability, discoverability, and ease of access and use. The materials and associated metadata on LISSA are publicly available and readily indexable.</p>
|
||||||
|
<a class="btn btn-primary btn-lg" href="/about/" role="button">Learn more</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-deck">
|
||||||
|
<div class="card mb-3 bg-light">
|
||||||
|
<h4 class="card-header">Committee Updates <i class="fas fa-pencil-alt"></i></h4>
|
||||||
|
<div class="card-body">
|
||||||
|
{{% post-list stop=3 %}}{{% /post-list %}}
|
||||||
|
</div>
|
||||||
|
<p class="card-text text-muted card-footer"><a href="/updates/">Read more from us <i class="fas fa-angle-double-right"></i></a></p>
|
||||||
|
</div>
|
||||||
|
<div class="card mb-3 bg-light">
|
||||||
|
<h4 class="card-header">New on LISSA <i class="fas fa-book-reader"></i></h4>
|
||||||
|
<div class="card-body">
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://osf.io/preprints/lissa/gw9pm/">Coping with impostor feelings: evidence-based recommendations from a mixed methods study</a></li>
|
||||||
|
<li><a href="https://osf.io/preprints/lissa/xsbd4/">Atenção online de artigos do periódico Ciência e Agrotecnologia</a></li>
|
||||||
|
<li><a href="https://osf.io/5yzc4/">Practicing Care: Constructing Social Responsibility Through Feminist Care Ethics</a></li>
|
||||||
|
<ul>
|
||||||
|
</div>
|
||||||
|
<p class="card-text text-muted card-footer"><a href="https://osf.io/preprints/lissa/discover">See everything on LISSA <i class="fas fa-angle-double-right"></i></a></p>
|
||||||
|
</div>
|
||||||
|
<div class="card mb-3 bg-light">
|
||||||
|
<h4 class="card-header">@LISSArchive <i class="fab fa-twitter"></i></h4>
|
||||||
|
<div class="card-body">
|
||||||
|
<p lang="en" dir="ltr">I was just recommending <a href="https://twitter.com/LISSArchive?ref_src=twsrc%5Etfw">@LISSArchive</a> to a librarian colleague as a preprint outlet for our field, and I mentioned I hadn't tried it myself, and then I thought, wait why not? So now I've tried it. <a href="https://t.co/2fzTMKo5Fv">https://t.co/2fzTMKo5Fv</a></p>— AJ Boston | <a href="https://twitter.com/AJ_Boston/status/1172235961008152576?ref_src=twsrc%5Etfw">September 12, 2019</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
|
||||||
|
</div>
|
||||||
|
<p class="card-text text-muted card-footer"><a href="https://twitter.com/search?q=%23IASGE&src=recent_search_click&f=live">See all @LISSArchive tweets <i class="fas fa-angle-double-right"></i></a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -1,12 +0,0 @@
|
||||||
.. title: LISSA
|
|
||||||
.. slug: index
|
|
||||||
.. date: 2017-01-06 14:24:09 UTC-05:00
|
|
||||||
.. tags:
|
|
||||||
.. link:
|
|
||||||
.. description:
|
|
||||||
.. type: text
|
|
||||||
.. hidetitle: True
|
|
||||||
.. template:post_list_directive
|
|
||||||
|
|
||||||
.. post-list::
|
|
||||||
:tags: home
|
|
|
@ -17,33 +17,39 @@
|
||||||
<div class="col-lg-4 col-sm-6 text-center mb-4">
|
<div class="col-lg-4 col-sm-6 text-center mb-4">
|
||||||
<img class="rounded-circle img-fluid d-block mx-auto" src="/images/people/vicky.jpg" alt="Vicky Steeves">
|
<img class="rounded-circle img-fluid d-block mx-auto" src="/images/people/vicky.jpg" alt="Vicky Steeves">
|
||||||
<h3><a href="https://vickysteeves.com">Vicky Steeves</a></h3>
|
<h3><a href="https://vickysteeves.com">Vicky Steeves</a></h3>
|
||||||
<p>New York University</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-4 col-sm-6 text-center mb-4">
|
<div class="col-lg-4 col-sm-6 text-center mb-4">
|
||||||
<img class="rounded-circle img-fluid d-block mx-auto" src="/images/people/april.jpg" alt="April Hathcock">
|
<img class="rounded-circle img-fluid d-block mx-auto" src="/images/people/april.jpg" alt="April Hathcock">
|
||||||
<h3><a href="https://aprilhathcock.wordpress.com/">April Hathcock</a></h3>
|
<h3><a href="https://aprilhathcock.wordpress.com/">April Hathcock</a></h3>
|
||||||
<p>New York University</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-4 col-sm-6 text-center mb-4">
|
|
||||||
<img class="rounded-circle img-fluid d-block mx-auto" src="/images/people/chealsye.png" alt="Chealsye Bowley">
|
|
||||||
<h3><a href="https://twitter.com/chealsye">Chealsye Bowley</a></h3>
|
|
||||||
<p>Ubiquity Press</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-4 col-sm-6 text-center mb-4">
|
|
||||||
<img class="rounded-circle img-fluid d-block mx-auto" src="/images/people/kevin.jpg" alt="Kevin Smith">
|
|
||||||
<h3><a href="https://lib.ku.edu/kevin-l-smith">Kevin Smith</a></h3>
|
|
||||||
<p>University of Kansas</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-4 col-sm-6 text-center mb-4">
|
<div class="col-lg-4 col-sm-6 text-center mb-4">
|
||||||
<img class="rounded-circle img-fluid d-block mx-auto" src="/images/people/megan.png" alt="Megan Wacha">
|
<img class="rounded-circle img-fluid d-block mx-auto" src="/images/people/megan.png" alt="Megan Wacha">
|
||||||
<h3><a href="http://www.meganwacha.info/">Megan Wacha</a></h3>
|
<h3><a href="http://www.meganwacha.info/">Megan Wacha</a></h3>
|
||||||
<p>City University of NY</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-4 col-sm-6 text-center mb-4">
|
<div class="col-lg-4 col-sm-6 text-center mb-4">
|
||||||
<img class="rounded-circle img-fluid d-block mx-auto" src="/images/people/blank.png" alt="person icon">
|
<img class="rounded-circle img-fluid d-block mx-auto" src="/images/people/chealsye.png" alt="Chealsye Bowley">
|
||||||
<h3>Possibly you?</h3>
|
<h3><a href="https://twitter.com/chealsye">Chealsye Bowley</a></h3>
|
||||||
<p><a href="mailto:lissarchive@gmail.com">Email us</a> to express interest in being on the steering committee</p>
|
</div>
|
||||||
|
<div class="col-lg-4 col-sm-6 text-center mb-4">
|
||||||
|
<img class="rounded-circle img-fluid d-block mx-auto" src="/images/people/shanna.jpg" alt="Shanna Hollich">
|
||||||
|
<h3><a href="https://www.wilson.edu/shanna-hollich">Shanna Hollich</a></h3>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-lg-4 col-sm-6 text-center mb-4">
|
||||||
|
<img class="rounded-circle img-fluid d-block mx-auto" src="/images/people/jim.jpg" alt="Jim DelRosso">
|
||||||
|
<h3><a href="https://www.library.cornell.edu/about/news/library-insider/staff-profile-jim-delrosso">Jim DelRosso</a></h3>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-4 col-sm-6 text-center mb-4">
|
||||||
|
<img class="rounded-circle img-fluid d-block mx-auto" src="/images/people/dina.jpg" alt="Dina Meky">
|
||||||
|
<h3><a href="https://library.northeastern.edu/about/library-staff-directory/dina-meky"></a>Dina Meky</h3>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-4 col-sm-6 text-center mb-4">
|
||||||
|
<img class="rounded-circle img-fluid d-block mx-auto" src="/images/people/blank.png" alt="Makoroba Sow">
|
||||||
|
<h3><a href="#"></a>Makoroba Sow</h3>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-4 col-sm-6 text-center mb-4">
|
||||||
|
<img class="rounded-circle img-fluid d-block mx-auto" src="/images/people/blank.png" alt="Syr Reifsteck">
|
||||||
|
<h3><a href="https://www.linkedin.com/in/syr-reifsteck-169192112/?originalSubdomain=ca"></a>Syr Reifsteck</h3>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/*!
|
/*!
|
||||||
* Bootstrap Reboot v4.0.0 (https://getbootstrap.com)
|
* Bootstrap Reboot v4.4.1 (https://getbootstrap.com/)
|
||||||
* Copyright 2011-2018 The Bootstrap Authors
|
* Copyright 2011-2019 The Bootstrap Authors
|
||||||
* Copyright 2011-2018 Twitter, Inc.
|
* Copyright 2011-2019 Twitter, Inc.
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||||
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
|
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]){color:inherit;text-decoration:none}a:not([href]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
|
||||||
/*# sourceMappingURL=bootstrap-reboot.min.css.map */
|
/*# sourceMappingURL=bootstrap-reboot.min.css.map */
|
|
@ -1,229 +1,115 @@
|
||||||
/* -------------------- FONTS -------------------- */
|
body {
|
||||||
|
color:#323232;
|
||||||
@import url('../webfronts/Arvo');
|
font-size:1.1rem;
|
||||||
|
|
||||||
@import url('../webfronts/Quicksand');
|
|
||||||
|
|
||||||
/* -------------------- BODY -------------------- */
|
|
||||||
|
|
||||||
a:hover, a:focus {
|
|
||||||
color: #dc7e4a;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
.jumbotron {
|
||||||
color: #8966a0;
|
padding: 1rem 2rem 1rem 2rem ;
|
||||||
text-decoration: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.u-url {
|
.center {
|
||||||
text-decoration: none;
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
body p{
|
/* --------------------NAVBAR--------------------------*/
|
||||||
font-size: 1.06em;
|
|
||||||
|
.navbar {
|
||||||
|
font-size: 1.1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul > li {
|
|
||||||
font-size: 1.06em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------- FOOTER -------------------- */
|
|
||||||
|
|
||||||
#footer {
|
|
||||||
text-align: center;
|
|
||||||
padding-top: 0.5em;
|
|
||||||
padding-bottom:0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------- BANNER ABOVE NAVBAR -------------------- */
|
|
||||||
|
|
||||||
#banner > h1 {
|
|
||||||
font-family: 'Arvo', serif;
|
|
||||||
font-weight:700;
|
|
||||||
color: #8966a0;
|
|
||||||
text-align:center;
|
|
||||||
margin-top:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#banner > h2 {
|
|
||||||
font-family: 'Quicksand', sans-serif;
|
|
||||||
font-weight:700;
|
|
||||||
color: #dc7e4a;
|
|
||||||
text-align:center;
|
|
||||||
margin-top:0;
|
|
||||||
margin-bottom:0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------- NAVBAR -------------------- */
|
|
||||||
|
|
||||||
.bg-dark {
|
.bg-dark {
|
||||||
background-color: #8966a0 !important;
|
background-color: #492B5D !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item {
|
.dropdown-item:focus, .dropdown-item:hover {
|
||||||
padding-right: 0.7em;
|
background-color: #492B5D;
|
||||||
padding-left: 0.7em;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-dark .navbar-nav > li > a {
|
#blog-title {
|
||||||
text-decoration: none;
|
vertical-align: -moz-middle-with-baseline;
|
||||||
font-size: 1.08em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-dark .nav-item .dropdown:focus, .navbar-dark .nav-item .dropdown:hover, .navbar-dark .nav-item .dropdown:active {
|
/* --------------------TABLES--------------------------*/
|
||||||
color: #dc7e4a !important;
|
.table .thead-dark th {
|
||||||
|
font-size: 1.1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-dark.navbar-dark .navbar-nav .nav-link:focus, .bg-dark.navbar-dark .navbar-nav .nav-link:hover, .bg-dark.navbar-dark .navbar-nav .active > .nav-link {
|
.table th, .table td {
|
||||||
color: #dc7e4a !important;
|
font-size: 1.1rem;
|
||||||
|
color:black;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-item.active, .dropdown-item:active {
|
/* --------------------UNDERLINING LINKS--------------------------*/
|
||||||
background-color: #dc7e4a !important;
|
|
||||||
|
.body-content p a {
|
||||||
|
text-decoration:underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item .dropdown {
|
.body-content li a {
|
||||||
color: #dc7e4a !important;
|
text-decoration:underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-item:hover, .dropdown-item:focus {
|
.pager li a {
|
||||||
background-color: #7da066;
|
text-decoration:none;
|
||||||
color: #ffffff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------MOBILE NAV------ */
|
footer a {
|
||||||
|
text-decoration:underline;
|
||||||
.navbar-dark .navbar-toggle:hover, .navbar-dark .navbar-toggle:focus {
|
|
||||||
background-color: #dc7e4a;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-dark .navbar-toggle {
|
.card-deck li a {
|
||||||
border-color: #dc7e4a;
|
text-decoration:none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 767px) {
|
.card-deck p a {
|
||||||
.navbar-dark .navbar-nav .open .dropdown-menu > .active > a, .navbar-dark .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar-dark .navbar-nav .open .dropdown-menu > .active > a:focus {
|
text-decoration:none;
|
||||||
color: #ffffff;
|
|
||||||
background-color: #dc7e4a;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------- BUTTONS -------------------- */
|
/* --------------------CARDS--------------------------*/
|
||||||
|
|
||||||
.btn-primary {
|
.card-body {
|
||||||
color: #ffffff;
|
padding-left:1.25rem;
|
||||||
background-color: #6a4e7d;
|
padding-right:1.25rem;
|
||||||
border-color: #6a4e7d;
|
padding-top:1rem;
|
||||||
}
|
padding-bottom:0.5rem;
|
||||||
.btn-primary:focus,
|
|
||||||
.btn-primary.focus {
|
|
||||||
color: #ffffff;
|
|
||||||
background-color: #563f65;
|
|
||||||
border-color: #000000;
|
|
||||||
}
|
|
||||||
.btn-primary:hover {
|
|
||||||
color: #ffffff;
|
|
||||||
background-color: #563f65;
|
|
||||||
border-color: #4c3759;
|
|
||||||
}
|
|
||||||
.btn-primary:active,
|
|
||||||
.btn-primary.active,
|
|
||||||
.open > .dropdown-toggle.btn-primary {
|
|
||||||
color: #ffffff;
|
|
||||||
background-color: #563f65;
|
|
||||||
border-color: #563f65;
|
|
||||||
}
|
|
||||||
.btn-primary:active:hover,
|
|
||||||
.btn-primary.active:hover,
|
|
||||||
.open > .dropdown-toggle.btn-primary:hover,
|
|
||||||
.btn-primary:active:focus,
|
|
||||||
.btn-primary.active:focus,
|
|
||||||
.open > .dropdown-toggle.btn-primary:focus,
|
|
||||||
.btn-primary:active.focus,
|
|
||||||
.btn-primary.active.focus,
|
|
||||||
.open > .dropdown-toggle.btn-primary.focus {
|
|
||||||
color: #ffffff;
|
|
||||||
background-color: #563f65;
|
|
||||||
border-color: #563f65;
|
|
||||||
}
|
|
||||||
.btn-primary:active,
|
|
||||||
.btn-primary.active,
|
|
||||||
.open > .dropdown-toggle.btn-primary {
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
.btn-primary.disabled:hover,
|
|
||||||
.btn-primary[disabled]:hover,
|
|
||||||
fieldset[disabled] .btn-primary:hover,
|
|
||||||
.btn-primary.disabled:focus,
|
|
||||||
.btn-primary[disabled]:focus,
|
|
||||||
fieldset[disabled] .btn-primary:focus,
|
|
||||||
.btn-primary.disabled.focus,
|
|
||||||
.btn-primary[disabled].focus,
|
|
||||||
fieldset[disabled] .btn-primary.focus {
|
|
||||||
background-color: #563f65;
|
|
||||||
border-color: #563f65;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-secondary {
|
/* --------------------RESPONSIVE DISPLAY HEADINGS--------------------------*/
|
||||||
color: #ffffff;
|
@media (max-width: 575.98px) {
|
||||||
background-color: #b8a3c6;
|
.display-1 {
|
||||||
border-color: #b8a3c6;
|
font-size: 3rem;
|
||||||
}
|
font-weight: 300;
|
||||||
.btn-secondary:focus,
|
line-height: 1.0;
|
||||||
.btn-secondary.focus {
|
}
|
||||||
color: #ffffff;
|
|
||||||
background-color: #9c7eaf;
|
.display-2 {
|
||||||
border-color: #9c7eaf;
|
font-size: 2.75rem;
|
||||||
}
|
font-weight: 300;
|
||||||
.btn-secondary:hover {
|
line-height: 1.0;
|
||||||
color: #ffffff;
|
}
|
||||||
background-color: #9c7eaf;
|
|
||||||
border-color: #8966a0;
|
.display-3 {
|
||||||
}
|
font-size: 2.25rem;
|
||||||
.btn-secondary:active,
|
font-weight: 300;
|
||||||
.btn-secondary.active,
|
line-height: 1.0;
|
||||||
.open > .dropdown-toggle.btn-secondary {
|
}
|
||||||
color: #ffffff;
|
|
||||||
background-color: #9c7eaf;
|
.display-4 {
|
||||||
border-color: #9c7eaf;
|
font-size: 1.75rem;
|
||||||
}
|
font-weight: 300;
|
||||||
.btn-secondary:active:hover,
|
line-height: 1.0;
|
||||||
.btn-secondary.active:hover,
|
}
|
||||||
.open > .dropdown-toggle.btn-secondary:hover,
|
|
||||||
.btn-secondary:active:focus,
|
|
||||||
.btn-secondary.active:focus,
|
|
||||||
.open > .dropdown-toggle.btn-secondary:focus,
|
|
||||||
.btn-secondary:active.focus,
|
|
||||||
.btn-secondary.active.focus,
|
|
||||||
.open > .dropdown-toggle.btn-secondary.focus {
|
|
||||||
color: #ffffff;
|
|
||||||
background-color: #9c7eaf;
|
|
||||||
border-color: #9c7eaf;
|
|
||||||
}
|
|
||||||
.btn-secondary:active,
|
|
||||||
.btn-secondary.active,
|
|
||||||
.open > .dropdown-toggle.btn-secondary {
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
.btn-secondary.disabled:hover,
|
|
||||||
.btn-secondary[disabled]:hover,
|
|
||||||
fieldset[disabled] .btn-secondary:hover,
|
|
||||||
.btn-secondary.disabled:focus,
|
|
||||||
.btn-secondary[disabled]:focus,
|
|
||||||
fieldset[disabled] .btn-secondary:focus,
|
|
||||||
.btn-secondary.disabled.focus,
|
|
||||||
.btn-secondary[disabled].focus,
|
|
||||||
fieldset[disabled] .btn-secondary.focus {
|
|
||||||
background-color: #9c7eaf;
|
|
||||||
border-color: #9c7eaf;
|
|
||||||
}
|
|
||||||
.btn-secondary .badge {
|
|
||||||
color: #9c7eaf;
|
|
||||||
background-color: #ffffff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------- FONT AWESOME -------------------- */
|
/*!
|
||||||
|
* Font Awesome Free 5.8.2 by @fontawesome - https://fontawesome.com
|
||||||
|
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||||
|
*/
|
||||||
.fa,
|
.fa,
|
||||||
.fas,
|
.fas,
|
||||||
.far,
|
.far,
|
||||||
|
@ -370,7 +256,7 @@ fieldset[disabled] .btn-secondary.focus {
|
||||||
-webkit-transform: scale(1, -1);
|
-webkit-transform: scale(1, -1);
|
||||||
transform: scale(1, -1); }
|
transform: scale(1, -1); }
|
||||||
|
|
||||||
.fa-flip-horizontal.fa-flip-vertical {
|
.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical {
|
||||||
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
|
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
|
||||||
-webkit-transform: scale(-1, -1);
|
-webkit-transform: scale(-1, -1);
|
||||||
transform: scale(-1, -1); }
|
transform: scale(-1, -1); }
|
||||||
|
@ -379,7 +265,8 @@ fieldset[disabled] .btn-secondary.focus {
|
||||||
:root .fa-rotate-180,
|
:root .fa-rotate-180,
|
||||||
:root .fa-rotate-270,
|
:root .fa-rotate-270,
|
||||||
:root .fa-flip-horizontal,
|
:root .fa-flip-horizontal,
|
||||||
:root .fa-flip-vertical {
|
:root .fa-flip-vertical,
|
||||||
|
:root .fa-flip-both {
|
||||||
-webkit-filter: none;
|
-webkit-filter: none;
|
||||||
filter: none; }
|
filter: none; }
|
||||||
|
|
||||||
|
@ -448,6 +335,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-air-freshener:before {
|
.fa-air-freshener:before {
|
||||||
content: "\f5d0"; }
|
content: "\f5d0"; }
|
||||||
|
|
||||||
|
.fa-airbnb:before {
|
||||||
|
content: "\f834"; }
|
||||||
|
|
||||||
.fa-algolia:before {
|
.fa-algolia:before {
|
||||||
content: "\f36c"; }
|
content: "\f36c"; }
|
||||||
|
|
||||||
|
@ -655,6 +545,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-backward:before {
|
.fa-backward:before {
|
||||||
content: "\f04a"; }
|
content: "\f04a"; }
|
||||||
|
|
||||||
|
.fa-bacon:before {
|
||||||
|
content: "\f7e5"; }
|
||||||
|
|
||||||
.fa-balance-scale:before {
|
.fa-balance-scale:before {
|
||||||
content: "\f24e"; }
|
content: "\f24e"; }
|
||||||
|
|
||||||
|
@ -697,6 +590,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-battery-three-quarters:before {
|
.fa-battery-three-quarters:before {
|
||||||
content: "\f241"; }
|
content: "\f241"; }
|
||||||
|
|
||||||
|
.fa-battle-net:before {
|
||||||
|
content: "\f835"; }
|
||||||
|
|
||||||
.fa-bed:before {
|
.fa-bed:before {
|
||||||
content: "\f236"; }
|
content: "\f236"; }
|
||||||
|
|
||||||
|
@ -796,6 +692,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-book-dead:before {
|
.fa-book-dead:before {
|
||||||
content: "\f6b7"; }
|
content: "\f6b7"; }
|
||||||
|
|
||||||
|
.fa-book-medical:before {
|
||||||
|
content: "\f7e6"; }
|
||||||
|
|
||||||
.fa-book-open:before {
|
.fa-book-open:before {
|
||||||
content: "\f518"; }
|
content: "\f518"; }
|
||||||
|
|
||||||
|
@ -805,6 +704,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-bookmark:before {
|
.fa-bookmark:before {
|
||||||
content: "\f02e"; }
|
content: "\f02e"; }
|
||||||
|
|
||||||
|
.fa-bootstrap:before {
|
||||||
|
content: "\f836"; }
|
||||||
|
|
||||||
.fa-bowling-ball:before {
|
.fa-bowling-ball:before {
|
||||||
content: "\f436"; }
|
content: "\f436"; }
|
||||||
|
|
||||||
|
@ -823,6 +725,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-brain:before {
|
.fa-brain:before {
|
||||||
content: "\f5dc"; }
|
content: "\f5dc"; }
|
||||||
|
|
||||||
|
.fa-bread-slice:before {
|
||||||
|
content: "\f7ec"; }
|
||||||
|
|
||||||
.fa-briefcase:before {
|
.fa-briefcase:before {
|
||||||
content: "\f0b1"; }
|
content: "\f0b1"; }
|
||||||
|
|
||||||
|
@ -841,6 +746,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-btc:before {
|
.fa-btc:before {
|
||||||
content: "\f15a"; }
|
content: "\f15a"; }
|
||||||
|
|
||||||
|
.fa-buffer:before {
|
||||||
|
content: "\f837"; }
|
||||||
|
|
||||||
.fa-bug:before {
|
.fa-bug:before {
|
||||||
content: "\f188"; }
|
content: "\f188"; }
|
||||||
|
|
||||||
|
@ -1048,6 +956,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-check-square:before {
|
.fa-check-square:before {
|
||||||
content: "\f14a"; }
|
content: "\f14a"; }
|
||||||
|
|
||||||
|
.fa-cheese:before {
|
||||||
|
content: "\f7ef"; }
|
||||||
|
|
||||||
.fa-chess:before {
|
.fa-chess:before {
|
||||||
content: "\f439"; }
|
content: "\f439"; }
|
||||||
|
|
||||||
|
@ -1102,6 +1013,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-chrome:before {
|
.fa-chrome:before {
|
||||||
content: "\f268"; }
|
content: "\f268"; }
|
||||||
|
|
||||||
|
.fa-chromecast:before {
|
||||||
|
content: "\f838"; }
|
||||||
|
|
||||||
.fa-church:before {
|
.fa-church:before {
|
||||||
content: "\f51d"; }
|
content: "\f51d"; }
|
||||||
|
|
||||||
|
@ -1114,6 +1028,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-city:before {
|
.fa-city:before {
|
||||||
content: "\f64f"; }
|
content: "\f64f"; }
|
||||||
|
|
||||||
|
.fa-clinic-medical:before {
|
||||||
|
content: "\f7f2"; }
|
||||||
|
|
||||||
.fa-clipboard:before {
|
.fa-clipboard:before {
|
||||||
content: "\f328"; }
|
content: "\f328"; }
|
||||||
|
|
||||||
|
@ -1213,6 +1130,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-comment-dots:before {
|
.fa-comment-dots:before {
|
||||||
content: "\f4ad"; }
|
content: "\f4ad"; }
|
||||||
|
|
||||||
|
.fa-comment-medical:before {
|
||||||
|
content: "\f7f5"; }
|
||||||
|
|
||||||
.fa-comment-slash:before {
|
.fa-comment-slash:before {
|
||||||
content: "\f4b3"; }
|
content: "\f4b3"; }
|
||||||
|
|
||||||
|
@ -1330,6 +1250,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-crown:before {
|
.fa-crown:before {
|
||||||
content: "\f521"; }
|
content: "\f521"; }
|
||||||
|
|
||||||
|
.fa-crutch:before {
|
||||||
|
content: "\f7f7"; }
|
||||||
|
|
||||||
.fa-css3:before {
|
.fa-css3:before {
|
||||||
content: "\f13c"; }
|
content: "\f13c"; }
|
||||||
|
|
||||||
|
@ -1546,6 +1469,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-edit:before {
|
.fa-edit:before {
|
||||||
content: "\f044"; }
|
content: "\f044"; }
|
||||||
|
|
||||||
|
.fa-egg:before {
|
||||||
|
content: "\f7fb"; }
|
||||||
|
|
||||||
.fa-eject:before {
|
.fa-eject:before {
|
||||||
content: "\f052"; }
|
content: "\f052"; }
|
||||||
|
|
||||||
|
@ -1603,6 +1529,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-euro-sign:before {
|
.fa-euro-sign:before {
|
||||||
content: "\f153"; }
|
content: "\f153"; }
|
||||||
|
|
||||||
|
.fa-evernote:before {
|
||||||
|
content: "\f839"; }
|
||||||
|
|
||||||
.fa-exchange-alt:before {
|
.fa-exchange-alt:before {
|
||||||
content: "\f362"; }
|
content: "\f362"; }
|
||||||
|
|
||||||
|
@ -1939,6 +1868,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-git:before {
|
.fa-git:before {
|
||||||
content: "\f1d3"; }
|
content: "\f1d3"; }
|
||||||
|
|
||||||
|
.fa-git-alt:before {
|
||||||
|
content: "\f841"; }
|
||||||
|
|
||||||
.fa-git-square:before {
|
.fa-git-square:before {
|
||||||
content: "\f1d2"; }
|
content: "\f1d2"; }
|
||||||
|
|
||||||
|
@ -2125,6 +2057,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-hackerrank:before {
|
.fa-hackerrank:before {
|
||||||
content: "\f5f7"; }
|
content: "\f5f7"; }
|
||||||
|
|
||||||
|
.fa-hamburger:before {
|
||||||
|
content: "\f805"; }
|
||||||
|
|
||||||
.fa-hammer:before {
|
.fa-hammer:before {
|
||||||
content: "\f6e3"; }
|
content: "\f6e3"; }
|
||||||
|
|
||||||
|
@ -2143,6 +2078,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-hand-lizard:before {
|
.fa-hand-lizard:before {
|
||||||
content: "\f258"; }
|
content: "\f258"; }
|
||||||
|
|
||||||
|
.fa-hand-middle-finger:before {
|
||||||
|
content: "\f806"; }
|
||||||
|
|
||||||
.fa-hand-paper:before {
|
.fa-hand-paper:before {
|
||||||
content: "\f256"; }
|
content: "\f256"; }
|
||||||
|
|
||||||
|
@ -2185,6 +2123,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-hanukiah:before {
|
.fa-hanukiah:before {
|
||||||
content: "\f6e6"; }
|
content: "\f6e6"; }
|
||||||
|
|
||||||
|
.fa-hard-hat:before {
|
||||||
|
content: "\f807"; }
|
||||||
|
|
||||||
.fa-hashtag:before {
|
.fa-hashtag:before {
|
||||||
content: "\f292"; }
|
content: "\f292"; }
|
||||||
|
|
||||||
|
@ -2272,6 +2213,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-hot-tub:before {
|
.fa-hot-tub:before {
|
||||||
content: "\f593"; }
|
content: "\f593"; }
|
||||||
|
|
||||||
|
.fa-hotdog:before {
|
||||||
|
content: "\f80f"; }
|
||||||
|
|
||||||
.fa-hotel:before {
|
.fa-hotel:before {
|
||||||
content: "\f594"; }
|
content: "\f594"; }
|
||||||
|
|
||||||
|
@ -2308,6 +2252,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-i-cursor:before {
|
.fa-i-cursor:before {
|
||||||
content: "\f246"; }
|
content: "\f246"; }
|
||||||
|
|
||||||
|
.fa-ice-cream:before {
|
||||||
|
content: "\f810"; }
|
||||||
|
|
||||||
.fa-icicles:before {
|
.fa-icicles:before {
|
||||||
content: "\f7ad"; }
|
content: "\f7ad"; }
|
||||||
|
|
||||||
|
@ -2368,6 +2315,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-italic:before {
|
.fa-italic:before {
|
||||||
content: "\f033"; }
|
content: "\f033"; }
|
||||||
|
|
||||||
|
.fa-itch-io:before {
|
||||||
|
content: "\f83a"; }
|
||||||
|
|
||||||
.fa-itunes:before {
|
.fa-itunes:before {
|
||||||
content: "\f3b4"; }
|
content: "\f3b4"; }
|
||||||
|
|
||||||
|
@ -2464,6 +2414,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-laptop-code:before {
|
.fa-laptop-code:before {
|
||||||
content: "\f5fc"; }
|
content: "\f5fc"; }
|
||||||
|
|
||||||
|
.fa-laptop-medical:before {
|
||||||
|
content: "\f812"; }
|
||||||
|
|
||||||
.fa-laravel:before {
|
.fa-laravel:before {
|
||||||
content: "\f3bd"; }
|
content: "\f3bd"; }
|
||||||
|
|
||||||
|
@ -2890,6 +2843,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-pagelines:before {
|
.fa-pagelines:before {
|
||||||
content: "\f18c"; }
|
content: "\f18c"; }
|
||||||
|
|
||||||
|
.fa-pager:before {
|
||||||
|
content: "\f815"; }
|
||||||
|
|
||||||
.fa-paint-brush:before {
|
.fa-paint-brush:before {
|
||||||
content: "\f1fc"; }
|
content: "\f1fc"; }
|
||||||
|
|
||||||
|
@ -2974,6 +2930,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-people-carry:before {
|
.fa-people-carry:before {
|
||||||
content: "\f4ce"; }
|
content: "\f4ce"; }
|
||||||
|
|
||||||
|
.fa-pepper-hot:before {
|
||||||
|
content: "\f816"; }
|
||||||
|
|
||||||
.fa-percent:before {
|
.fa-percent:before {
|
||||||
content: "\f295"; }
|
content: "\f295"; }
|
||||||
|
|
||||||
|
@ -3037,6 +2996,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-pinterest-square:before {
|
.fa-pinterest-square:before {
|
||||||
content: "\f0d3"; }
|
content: "\f0d3"; }
|
||||||
|
|
||||||
|
.fa-pizza-slice:before {
|
||||||
|
content: "\f818"; }
|
||||||
|
|
||||||
.fa-place-of-worship:before {
|
.fa-place-of-worship:before {
|
||||||
content: "\f67f"; }
|
content: "\f67f"; }
|
||||||
|
|
||||||
|
@ -3316,6 +3278,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-safari:before {
|
.fa-safari:before {
|
||||||
content: "\f267"; }
|
content: "\f267"; }
|
||||||
|
|
||||||
|
.fa-salesforce:before {
|
||||||
|
content: "\f83b"; }
|
||||||
|
|
||||||
.fa-sass:before {
|
.fa-sass:before {
|
||||||
content: "\f41e"; }
|
content: "\f41e"; }
|
||||||
|
|
||||||
|
@ -3595,6 +3560,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-speakap:before {
|
.fa-speakap:before {
|
||||||
content: "\f3f3"; }
|
content: "\f3f3"; }
|
||||||
|
|
||||||
|
.fa-speaker-deck:before {
|
||||||
|
content: "\f83c"; }
|
||||||
|
|
||||||
.fa-spider:before {
|
.fa-spider:before {
|
||||||
content: "\f717"; }
|
content: "\f717"; }
|
||||||
|
|
||||||
|
@ -3628,6 +3596,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-stack-overflow:before {
|
.fa-stack-overflow:before {
|
||||||
content: "\f16c"; }
|
content: "\f16c"; }
|
||||||
|
|
||||||
|
.fa-stackpath:before {
|
||||||
|
content: "\f842"; }
|
||||||
|
|
||||||
.fa-stamp:before {
|
.fa-stamp:before {
|
||||||
content: "\f5bf"; }
|
content: "\f5bf"; }
|
||||||
|
|
||||||
|
@ -3760,6 +3731,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-swimming-pool:before {
|
.fa-swimming-pool:before {
|
||||||
content: "\f5c5"; }
|
content: "\f5c5"; }
|
||||||
|
|
||||||
|
.fa-symfony:before {
|
||||||
|
content: "\f83d"; }
|
||||||
|
|
||||||
.fa-synagogue:before {
|
.fa-synagogue:before {
|
||||||
content: "\f69b"; }
|
content: "\f69b"; }
|
||||||
|
|
||||||
|
@ -3967,6 +3941,12 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-trash-alt:before {
|
.fa-trash-alt:before {
|
||||||
content: "\f2ed"; }
|
content: "\f2ed"; }
|
||||||
|
|
||||||
|
.fa-trash-restore:before {
|
||||||
|
content: "\f829"; }
|
||||||
|
|
||||||
|
.fa-trash-restore-alt:before {
|
||||||
|
content: "\f82a"; }
|
||||||
|
|
||||||
.fa-tree:before {
|
.fa-tree:before {
|
||||||
content: "\f1bb"; }
|
content: "\f1bb"; }
|
||||||
|
|
||||||
|
@ -4123,6 +4103,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-user-ninja:before {
|
.fa-user-ninja:before {
|
||||||
content: "\f504"; }
|
content: "\f504"; }
|
||||||
|
|
||||||
|
.fa-user-nurse:before {
|
||||||
|
content: "\f82f"; }
|
||||||
|
|
||||||
.fa-user-plus:before {
|
.fa-user-plus:before {
|
||||||
content: "\f234"; }
|
content: "\f234"; }
|
||||||
|
|
||||||
|
@ -4258,6 +4241,12 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-water:before {
|
.fa-water:before {
|
||||||
content: "\f773"; }
|
content: "\f773"; }
|
||||||
|
|
||||||
|
.fa-wave-square:before {
|
||||||
|
content: "\f83e"; }
|
||||||
|
|
||||||
|
.fa-waze:before {
|
||||||
|
content: "\f83f"; }
|
||||||
|
|
||||||
.fa-weebly:before {
|
.fa-weebly:before {
|
||||||
content: "\f5cc"; }
|
content: "\f5cc"; }
|
||||||
|
|
||||||
|
@ -4369,6 +4358,9 @@ readers do not read off random characters that represent icons */
|
||||||
.fa-yahoo:before {
|
.fa-yahoo:before {
|
||||||
content: "\f19e"; }
|
content: "\f19e"; }
|
||||||
|
|
||||||
|
.fa-yammer:before {
|
||||||
|
content: "\f840"; }
|
||||||
|
|
||||||
.fa-yandex:before {
|
.fa-yandex:before {
|
||||||
content: "\f413"; }
|
content: "\f413"; }
|
||||||
|
|
||||||
|
@ -4420,6 +4412,7 @@ readers do not read off random characters that represent icons */
|
||||||
font-family: 'Font Awesome 5 Brands';
|
font-family: 'Font Awesome 5 Brands';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
font-display: auto;
|
||||||
src: url("../webfonts/fa-brands-400.eot");
|
src: url("../webfonts/fa-brands-400.eot");
|
||||||
src: url("../webfonts/fa-brands-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.woff") format("woff"), url("../webfonts/fa-brands-400.ttf") format("truetype"), url("../webfonts/fa-brands-400.svg#fontawesome") format("svg"); }
|
src: url("../webfonts/fa-brands-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.woff") format("woff"), url("../webfonts/fa-brands-400.ttf") format("truetype"), url("../webfonts/fa-brands-400.svg#fontawesome") format("svg"); }
|
||||||
|
|
||||||
|
@ -4429,6 +4422,7 @@ readers do not read off random characters that represent icons */
|
||||||
font-family: 'Font Awesome 5 Free';
|
font-family: 'Font Awesome 5 Free';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
font-display: auto;
|
||||||
src: url("../webfonts/fa-regular-400.eot");
|
src: url("../webfonts/fa-regular-400.eot");
|
||||||
src: url("../webfonts/fa-regular-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.woff") format("woff"), url("../webfonts/fa-regular-400.ttf") format("truetype"), url("../webfonts/fa-regular-400.svg#fontawesome") format("svg"); }
|
src: url("../webfonts/fa-regular-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.woff") format("woff"), url("../webfonts/fa-regular-400.ttf") format("truetype"), url("../webfonts/fa-regular-400.svg#fontawesome") format("svg"); }
|
||||||
|
|
||||||
|
@ -4439,6 +4433,7 @@ readers do not read off random characters that represent icons */
|
||||||
font-family: 'Font Awesome 5 Free';
|
font-family: 'Font Awesome 5 Free';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
|
font-display: auto;
|
||||||
src: url("../webfonts/fa-solid-900.eot");
|
src: url("../webfonts/fa-solid-900.eot");
|
||||||
src: url("../webfonts/fa-solid-900.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.woff") format("woff"), url("../webfonts/fa-solid-900.ttf") format("truetype"), url("../webfonts/fa-solid-900.svg#fontawesome") format("svg"); }
|
src: url("../webfonts/fa-solid-900.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.woff") format("woff"), url("../webfonts/fa-solid-900.ttf") format("truetype"), url("../webfonts/fa-solid-900.svg#fontawesome") format("svg"); }
|
||||||
|
|
||||||
|
|
|
@ -1,234 +0,0 @@
|
||||||
img {
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.titlebox {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
td.label {
|
|
||||||
/* Issue #290 */
|
|
||||||
background-color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footnote-reference {
|
|
||||||
/* Issue 290 */
|
|
||||||
vertical-align: super;
|
|
||||||
font-size: xx-small;
|
|
||||||
}
|
|
||||||
|
|
||||||
.caption {
|
|
||||||
/* Issue 292 */
|
|
||||||
text-align: center;
|
|
||||||
padding-top: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.figure > img,
|
|
||||||
div.figure > a > img {
|
|
||||||
/* Issue 292 */
|
|
||||||
display: block;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
blockquote p, blockquote {
|
|
||||||
font-size: 1.25rem;
|
|
||||||
font-weight: 300;
|
|
||||||
line-height: 1.25;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.bricks > li {
|
|
||||||
display: inline;
|
|
||||||
background-color: lightblue;
|
|
||||||
padding: 8px;
|
|
||||||
border-radius: 5px;
|
|
||||||
line-height: 3;
|
|
||||||
white-space:nowrap;
|
|
||||||
margin: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre, pre code {
|
|
||||||
white-space: pre;
|
|
||||||
word-wrap: normal;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
article.post-micro {
|
|
||||||
font-family: Georgia, 'Times New Roman', Times, serif;
|
|
||||||
font-size: 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.image-block {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tags {
|
|
||||||
padding-left: 0;
|
|
||||||
margin-left: -5px;
|
|
||||||
list-style: none;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.tags > li {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
.tags > li a {
|
|
||||||
display: inline-block;
|
|
||||||
padding: .25em .4em;
|
|
||||||
font-size: 75%;
|
|
||||||
font-weight: 700;
|
|
||||||
line-height: 1;
|
|
||||||
color: #fff;
|
|
||||||
text-align: center;
|
|
||||||
white-space: nowrap;
|
|
||||||
vertical-align: baseline;
|
|
||||||
border-radius: .25rem;
|
|
||||||
background-color: #868e96;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tags > li a:hover {
|
|
||||||
color: #fff;
|
|
||||||
text-decoration: none;
|
|
||||||
background-color: #6c757d;
|
|
||||||
}
|
|
||||||
|
|
||||||
.metadata p:before,
|
|
||||||
.postlist .listdate:after {
|
|
||||||
content: " — ";
|
|
||||||
}
|
|
||||||
|
|
||||||
.metadata p:first-of-type:before {
|
|
||||||
content: "";
|
|
||||||
}
|
|
||||||
|
|
||||||
.metadata p {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.posttranslations h3 {
|
|
||||||
display: inline;
|
|
||||||
font-size: 1em;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.posttranslations h3:last-child {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.entry-content {
|
|
||||||
margin-top: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* for alignment with Bootstrap's .entry-content styling */
|
|
||||||
.entry-summary {
|
|
||||||
margin-top: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Custom page footer */
|
|
||||||
#footer {
|
|
||||||
padding-top: 19px;
|
|
||||||
color: #777;
|
|
||||||
border-top: 1px solid #e5e5e5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.codetable {
|
|
||||||
table-layout: fixed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.codetable pre {
|
|
||||||
overflow-x: scroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* hat tip bootstrap/html5 boilerplate */
|
|
||||||
@media print {
|
|
||||||
*, *:before, *:after {
|
|
||||||
font-family: Garamond, Junicode, serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-size: 12pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
article .entry-title a[href]:after,
|
|
||||||
article .metadata a[href]:after,
|
|
||||||
article .tags a[href]:after {
|
|
||||||
content: "";
|
|
||||||
}
|
|
||||||
|
|
||||||
article .metadata .sourceline {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
article .metadata .linkline a[href]:after {
|
|
||||||
content: " (" attr(href) ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
border-radius: 0.25rem;
|
|
||||||
padding: 0.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.postindexpager {
|
|
||||||
padding-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.navbar-nav {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.pager {
|
|
||||||
display: flex;
|
|
||||||
padding-left: 0;
|
|
||||||
list-style: none;
|
|
||||||
border-radius: .25rem;
|
|
||||||
padding-left: 0;
|
|
||||||
margin: 0.5rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.pager li.previous {
|
|
||||||
margin-right: auto;
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.pager li.next {
|
|
||||||
margin-left: auto;
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ul.pager li a {
|
|
||||||
display: inline;
|
|
||||||
position: relative;
|
|
||||||
padding: .5rem .75rem;
|
|
||||||
margin-left: -1px;
|
|
||||||
line-height: 1.25;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
border-radius: .25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.codetable td {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.codetable td.linenos pre {
|
|
||||||
border-top-right-radius: 0;
|
|
||||||
border-bottom-right-radius: 0;
|
|
||||||
border-right: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.codetable td.code pre.code {
|
|
||||||
margin-left: 0;
|
|
||||||
margin-right: 0;
|
|
||||||
border-top-left-radius: 0;
|
|
||||||
border-bottom-left-radius: 0;
|
|
||||||
}
|
|
|
@ -1,181 +0,0 @@
|
||||||
import $ from 'jquery'
|
|
||||||
import Util from './util'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Bootstrap (v4.0.0): alert.js
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const Alert = (($) => {
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Constants
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const NAME = 'alert'
|
|
||||||
const VERSION = '4.0.0'
|
|
||||||
const DATA_KEY = 'bs.alert'
|
|
||||||
const EVENT_KEY = `.${DATA_KEY}`
|
|
||||||
const DATA_API_KEY = '.data-api'
|
|
||||||
const JQUERY_NO_CONFLICT = $.fn[NAME]
|
|
||||||
const TRANSITION_DURATION = 150
|
|
||||||
|
|
||||||
const Selector = {
|
|
||||||
DISMISS : '[data-dismiss="alert"]'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Event = {
|
|
||||||
CLOSE : `close${EVENT_KEY}`,
|
|
||||||
CLOSED : `closed${EVENT_KEY}`,
|
|
||||||
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const ClassName = {
|
|
||||||
ALERT : 'alert',
|
|
||||||
FADE : 'fade',
|
|
||||||
SHOW : 'show'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Class Definition
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Alert {
|
|
||||||
constructor(element) {
|
|
||||||
this._element = element
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getters
|
|
||||||
|
|
||||||
static get VERSION() {
|
|
||||||
return VERSION
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public
|
|
||||||
|
|
||||||
close(element) {
|
|
||||||
element = element || this._element
|
|
||||||
|
|
||||||
const rootElement = this._getRootElement(element)
|
|
||||||
const customEvent = this._triggerCloseEvent(rootElement)
|
|
||||||
|
|
||||||
if (customEvent.isDefaultPrevented()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this._removeElement(rootElement)
|
|
||||||
}
|
|
||||||
|
|
||||||
dispose() {
|
|
||||||
$.removeData(this._element, DATA_KEY)
|
|
||||||
this._element = null
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private
|
|
||||||
|
|
||||||
_getRootElement(element) {
|
|
||||||
const selector = Util.getSelectorFromElement(element)
|
|
||||||
let parent = false
|
|
||||||
|
|
||||||
if (selector) {
|
|
||||||
parent = $(selector)[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!parent) {
|
|
||||||
parent = $(element).closest(`.${ClassName.ALERT}`)[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
return parent
|
|
||||||
}
|
|
||||||
|
|
||||||
_triggerCloseEvent(element) {
|
|
||||||
const closeEvent = $.Event(Event.CLOSE)
|
|
||||||
|
|
||||||
$(element).trigger(closeEvent)
|
|
||||||
return closeEvent
|
|
||||||
}
|
|
||||||
|
|
||||||
_removeElement(element) {
|
|
||||||
$(element).removeClass(ClassName.SHOW)
|
|
||||||
|
|
||||||
if (!Util.supportsTransitionEnd() ||
|
|
||||||
!$(element).hasClass(ClassName.FADE)) {
|
|
||||||
this._destroyElement(element)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
$(element)
|
|
||||||
.one(Util.TRANSITION_END, (event) => this._destroyElement(element, event))
|
|
||||||
.emulateTransitionEnd(TRANSITION_DURATION)
|
|
||||||
}
|
|
||||||
|
|
||||||
_destroyElement(element) {
|
|
||||||
$(element)
|
|
||||||
.detach()
|
|
||||||
.trigger(Event.CLOSED)
|
|
||||||
.remove()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static
|
|
||||||
|
|
||||||
static _jQueryInterface(config) {
|
|
||||||
return this.each(function () {
|
|
||||||
const $element = $(this)
|
|
||||||
let data = $element.data(DATA_KEY)
|
|
||||||
|
|
||||||
if (!data) {
|
|
||||||
data = new Alert(this)
|
|
||||||
$element.data(DATA_KEY, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config === 'close') {
|
|
||||||
data[config](this)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
static _handleDismiss(alertInstance) {
|
|
||||||
return function (event) {
|
|
||||||
if (event) {
|
|
||||||
event.preventDefault()
|
|
||||||
}
|
|
||||||
|
|
||||||
alertInstance.close(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Data Api implementation
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
$(document).on(
|
|
||||||
Event.CLICK_DATA_API,
|
|
||||||
Selector.DISMISS,
|
|
||||||
Alert._handleDismiss(new Alert())
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* jQuery
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
$.fn[NAME] = Alert._jQueryInterface
|
|
||||||
$.fn[NAME].Constructor = Alert
|
|
||||||
$.fn[NAME].noConflict = function () {
|
|
||||||
$.fn[NAME] = JQUERY_NO_CONFLICT
|
|
||||||
return Alert._jQueryInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
return Alert
|
|
||||||
})($)
|
|
||||||
|
|
||||||
export default Alert
|
|
|
@ -1,175 +0,0 @@
|
||||||
import $ from 'jquery'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Bootstrap (v4.0.0): button.js
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const Button = (($) => {
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Constants
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const NAME = 'button'
|
|
||||||
const VERSION = '4.0.0'
|
|
||||||
const DATA_KEY = 'bs.button'
|
|
||||||
const EVENT_KEY = `.${DATA_KEY}`
|
|
||||||
const DATA_API_KEY = '.data-api'
|
|
||||||
const JQUERY_NO_CONFLICT = $.fn[NAME]
|
|
||||||
|
|
||||||
const ClassName = {
|
|
||||||
ACTIVE : 'active',
|
|
||||||
BUTTON : 'btn',
|
|
||||||
FOCUS : 'focus'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Selector = {
|
|
||||||
DATA_TOGGLE_CARROT : '[data-toggle^="button"]',
|
|
||||||
DATA_TOGGLE : '[data-toggle="buttons"]',
|
|
||||||
INPUT : 'input',
|
|
||||||
ACTIVE : '.active',
|
|
||||||
BUTTON : '.btn'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Event = {
|
|
||||||
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`,
|
|
||||||
FOCUS_BLUR_DATA_API : `focus${EVENT_KEY}${DATA_API_KEY} ` +
|
|
||||||
`blur${EVENT_KEY}${DATA_API_KEY}`
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Class Definition
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Button {
|
|
||||||
constructor(element) {
|
|
||||||
this._element = element
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getters
|
|
||||||
|
|
||||||
static get VERSION() {
|
|
||||||
return VERSION
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public
|
|
||||||
|
|
||||||
toggle() {
|
|
||||||
let triggerChangeEvent = true
|
|
||||||
let addAriaPressed = true
|
|
||||||
const rootElement = $(this._element).closest(
|
|
||||||
Selector.DATA_TOGGLE
|
|
||||||
)[0]
|
|
||||||
|
|
||||||
if (rootElement) {
|
|
||||||
const input = $(this._element).find(Selector.INPUT)[0]
|
|
||||||
|
|
||||||
if (input) {
|
|
||||||
if (input.type === 'radio') {
|
|
||||||
if (input.checked &&
|
|
||||||
$(this._element).hasClass(ClassName.ACTIVE)) {
|
|
||||||
triggerChangeEvent = false
|
|
||||||
} else {
|
|
||||||
const activeElement = $(rootElement).find(Selector.ACTIVE)[0]
|
|
||||||
|
|
||||||
if (activeElement) {
|
|
||||||
$(activeElement).removeClass(ClassName.ACTIVE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (triggerChangeEvent) {
|
|
||||||
if (input.hasAttribute('disabled') ||
|
|
||||||
rootElement.hasAttribute('disabled') ||
|
|
||||||
input.classList.contains('disabled') ||
|
|
||||||
rootElement.classList.contains('disabled')) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
input.checked = !$(this._element).hasClass(ClassName.ACTIVE)
|
|
||||||
$(input).trigger('change')
|
|
||||||
}
|
|
||||||
|
|
||||||
input.focus()
|
|
||||||
addAriaPressed = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addAriaPressed) {
|
|
||||||
this._element.setAttribute('aria-pressed',
|
|
||||||
!$(this._element).hasClass(ClassName.ACTIVE))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (triggerChangeEvent) {
|
|
||||||
$(this._element).toggleClass(ClassName.ACTIVE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dispose() {
|
|
||||||
$.removeData(this._element, DATA_KEY)
|
|
||||||
this._element = null
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static
|
|
||||||
|
|
||||||
static _jQueryInterface(config) {
|
|
||||||
return this.each(function () {
|
|
||||||
let data = $(this).data(DATA_KEY)
|
|
||||||
|
|
||||||
if (!data) {
|
|
||||||
data = new Button(this)
|
|
||||||
$(this).data(DATA_KEY, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config === 'toggle') {
|
|
||||||
data[config]()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Data Api implementation
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
$(document)
|
|
||||||
.on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {
|
|
||||||
event.preventDefault()
|
|
||||||
|
|
||||||
let button = event.target
|
|
||||||
|
|
||||||
if (!$(button).hasClass(ClassName.BUTTON)) {
|
|
||||||
button = $(button).closest(Selector.BUTTON)
|
|
||||||
}
|
|
||||||
|
|
||||||
Button._jQueryInterface.call($(button), 'toggle')
|
|
||||||
})
|
|
||||||
.on(Event.FOCUS_BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {
|
|
||||||
const button = $(event.target).closest(Selector.BUTTON)[0]
|
|
||||||
$(button).toggleClass(ClassName.FOCUS, /^focus(in)?$/.test(event.type))
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* jQuery
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
$.fn[NAME] = Button._jQueryInterface
|
|
||||||
$.fn[NAME].Constructor = Button
|
|
||||||
$.fn[NAME].noConflict = function () {
|
|
||||||
$.fn[NAME] = JQUERY_NO_CONFLICT
|
|
||||||
return Button._jQueryInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
return Button
|
|
||||||
})($)
|
|
||||||
|
|
||||||
export default Button
|
|
|
@ -1,518 +0,0 @@
|
||||||
import $ from 'jquery'
|
|
||||||
import Util from './util'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Bootstrap (v4.0.0): carousel.js
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const Carousel = (($) => {
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Constants
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const NAME = 'carousel'
|
|
||||||
const VERSION = '4.0.0'
|
|
||||||
const DATA_KEY = 'bs.carousel'
|
|
||||||
const EVENT_KEY = `.${DATA_KEY}`
|
|
||||||
const DATA_API_KEY = '.data-api'
|
|
||||||
const JQUERY_NO_CONFLICT = $.fn[NAME]
|
|
||||||
const TRANSITION_DURATION = 600
|
|
||||||
const ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key
|
|
||||||
const ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key
|
|
||||||
const TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch
|
|
||||||
|
|
||||||
const Default = {
|
|
||||||
interval : 5000,
|
|
||||||
keyboard : true,
|
|
||||||
slide : false,
|
|
||||||
pause : 'hover',
|
|
||||||
wrap : true
|
|
||||||
}
|
|
||||||
|
|
||||||
const DefaultType = {
|
|
||||||
interval : '(number|boolean)',
|
|
||||||
keyboard : 'boolean',
|
|
||||||
slide : '(boolean|string)',
|
|
||||||
pause : '(string|boolean)',
|
|
||||||
wrap : 'boolean'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Direction = {
|
|
||||||
NEXT : 'next',
|
|
||||||
PREV : 'prev',
|
|
||||||
LEFT : 'left',
|
|
||||||
RIGHT : 'right'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Event = {
|
|
||||||
SLIDE : `slide${EVENT_KEY}`,
|
|
||||||
SLID : `slid${EVENT_KEY}`,
|
|
||||||
KEYDOWN : `keydown${EVENT_KEY}`,
|
|
||||||
MOUSEENTER : `mouseenter${EVENT_KEY}`,
|
|
||||||
MOUSELEAVE : `mouseleave${EVENT_KEY}`,
|
|
||||||
TOUCHEND : `touchend${EVENT_KEY}`,
|
|
||||||
LOAD_DATA_API : `load${EVENT_KEY}${DATA_API_KEY}`,
|
|
||||||
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const ClassName = {
|
|
||||||
CAROUSEL : 'carousel',
|
|
||||||
ACTIVE : 'active',
|
|
||||||
SLIDE : 'slide',
|
|
||||||
RIGHT : 'carousel-item-right',
|
|
||||||
LEFT : 'carousel-item-left',
|
|
||||||
NEXT : 'carousel-item-next',
|
|
||||||
PREV : 'carousel-item-prev',
|
|
||||||
ITEM : 'carousel-item'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Selector = {
|
|
||||||
ACTIVE : '.active',
|
|
||||||
ACTIVE_ITEM : '.active.carousel-item',
|
|
||||||
ITEM : '.carousel-item',
|
|
||||||
NEXT_PREV : '.carousel-item-next, .carousel-item-prev',
|
|
||||||
INDICATORS : '.carousel-indicators',
|
|
||||||
DATA_SLIDE : '[data-slide], [data-slide-to]',
|
|
||||||
DATA_RIDE : '[data-ride="carousel"]'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Class Definition
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Carousel {
|
|
||||||
constructor(element, config) {
|
|
||||||
this._items = null
|
|
||||||
this._interval = null
|
|
||||||
this._activeElement = null
|
|
||||||
|
|
||||||
this._isPaused = false
|
|
||||||
this._isSliding = false
|
|
||||||
|
|
||||||
this.touchTimeout = null
|
|
||||||
|
|
||||||
this._config = this._getConfig(config)
|
|
||||||
this._element = $(element)[0]
|
|
||||||
this._indicatorsElement = $(this._element).find(Selector.INDICATORS)[0]
|
|
||||||
|
|
||||||
this._addEventListeners()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getters
|
|
||||||
|
|
||||||
static get VERSION() {
|
|
||||||
return VERSION
|
|
||||||
}
|
|
||||||
|
|
||||||
static get Default() {
|
|
||||||
return Default
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public
|
|
||||||
|
|
||||||
next() {
|
|
||||||
if (!this._isSliding) {
|
|
||||||
this._slide(Direction.NEXT)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nextWhenVisible() {
|
|
||||||
// Don't call next when the page isn't visible
|
|
||||||
// or the carousel or its parent isn't visible
|
|
||||||
if (!document.hidden &&
|
|
||||||
($(this._element).is(':visible') && $(this._element).css('visibility') !== 'hidden')) {
|
|
||||||
this.next()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
prev() {
|
|
||||||
if (!this._isSliding) {
|
|
||||||
this._slide(Direction.PREV)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pause(event) {
|
|
||||||
if (!event) {
|
|
||||||
this._isPaused = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($(this._element).find(Selector.NEXT_PREV)[0] &&
|
|
||||||
Util.supportsTransitionEnd()) {
|
|
||||||
Util.triggerTransitionEnd(this._element)
|
|
||||||
this.cycle(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
clearInterval(this._interval)
|
|
||||||
this._interval = null
|
|
||||||
}
|
|
||||||
|
|
||||||
cycle(event) {
|
|
||||||
if (!event) {
|
|
||||||
this._isPaused = false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._interval) {
|
|
||||||
clearInterval(this._interval)
|
|
||||||
this._interval = null
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._config.interval && !this._isPaused) {
|
|
||||||
this._interval = setInterval(
|
|
||||||
(document.visibilityState ? this.nextWhenVisible : this.next).bind(this),
|
|
||||||
this._config.interval
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
to(index) {
|
|
||||||
this._activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0]
|
|
||||||
|
|
||||||
const activeIndex = this._getItemIndex(this._activeElement)
|
|
||||||
|
|
||||||
if (index > this._items.length - 1 || index < 0) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._isSliding) {
|
|
||||||
$(this._element).one(Event.SLID, () => this.to(index))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (activeIndex === index) {
|
|
||||||
this.pause()
|
|
||||||
this.cycle()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const direction = index > activeIndex
|
|
||||||
? Direction.NEXT
|
|
||||||
: Direction.PREV
|
|
||||||
|
|
||||||
this._slide(direction, this._items[index])
|
|
||||||
}
|
|
||||||
|
|
||||||
dispose() {
|
|
||||||
$(this._element).off(EVENT_KEY)
|
|
||||||
$.removeData(this._element, DATA_KEY)
|
|
||||||
|
|
||||||
this._items = null
|
|
||||||
this._config = null
|
|
||||||
this._element = null
|
|
||||||
this._interval = null
|
|
||||||
this._isPaused = null
|
|
||||||
this._isSliding = null
|
|
||||||
this._activeElement = null
|
|
||||||
this._indicatorsElement = null
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private
|
|
||||||
|
|
||||||
_getConfig(config) {
|
|
||||||
config = {
|
|
||||||
...Default,
|
|
||||||
...config
|
|
||||||
}
|
|
||||||
Util.typeCheckConfig(NAME, config, DefaultType)
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
|
|
||||||
_addEventListeners() {
|
|
||||||
if (this._config.keyboard) {
|
|
||||||
$(this._element)
|
|
||||||
.on(Event.KEYDOWN, (event) => this._keydown(event))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._config.pause === 'hover') {
|
|
||||||
$(this._element)
|
|
||||||
.on(Event.MOUSEENTER, (event) => this.pause(event))
|
|
||||||
.on(Event.MOUSELEAVE, (event) => this.cycle(event))
|
|
||||||
if ('ontouchstart' in document.documentElement) {
|
|
||||||
// If it's a touch-enabled device, mouseenter/leave are fired as
|
|
||||||
// part of the mouse compatibility events on first tap - the carousel
|
|
||||||
// would stop cycling until user tapped out of it;
|
|
||||||
// here, we listen for touchend, explicitly pause the carousel
|
|
||||||
// (as if it's the second time we tap on it, mouseenter compat event
|
|
||||||
// is NOT fired) and after a timeout (to allow for mouse compatibility
|
|
||||||
// events to fire) we explicitly restart cycling
|
|
||||||
$(this._element).on(Event.TOUCHEND, () => {
|
|
||||||
this.pause()
|
|
||||||
if (this.touchTimeout) {
|
|
||||||
clearTimeout(this.touchTimeout)
|
|
||||||
}
|
|
||||||
this.touchTimeout = setTimeout((event) => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_keydown(event) {
|
|
||||||
if (/input|textarea/i.test(event.target.tagName)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (event.which) {
|
|
||||||
case ARROW_LEFT_KEYCODE:
|
|
||||||
event.preventDefault()
|
|
||||||
this.prev()
|
|
||||||
break
|
|
||||||
case ARROW_RIGHT_KEYCODE:
|
|
||||||
event.preventDefault()
|
|
||||||
this.next()
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_getItemIndex(element) {
|
|
||||||
this._items = $.makeArray($(element).parent().find(Selector.ITEM))
|
|
||||||
return this._items.indexOf(element)
|
|
||||||
}
|
|
||||||
|
|
||||||
_getItemByDirection(direction, activeElement) {
|
|
||||||
const isNextDirection = direction === Direction.NEXT
|
|
||||||
const isPrevDirection = direction === Direction.PREV
|
|
||||||
const activeIndex = this._getItemIndex(activeElement)
|
|
||||||
const lastItemIndex = this._items.length - 1
|
|
||||||
const isGoingToWrap = isPrevDirection && activeIndex === 0 ||
|
|
||||||
isNextDirection && activeIndex === lastItemIndex
|
|
||||||
|
|
||||||
if (isGoingToWrap && !this._config.wrap) {
|
|
||||||
return activeElement
|
|
||||||
}
|
|
||||||
|
|
||||||
const delta = direction === Direction.PREV ? -1 : 1
|
|
||||||
const itemIndex = (activeIndex + delta) % this._items.length
|
|
||||||
|
|
||||||
return itemIndex === -1
|
|
||||||
? this._items[this._items.length - 1] : this._items[itemIndex]
|
|
||||||
}
|
|
||||||
|
|
||||||
_triggerSlideEvent(relatedTarget, eventDirectionName) {
|
|
||||||
const targetIndex = this._getItemIndex(relatedTarget)
|
|
||||||
const fromIndex = this._getItemIndex($(this._element).find(Selector.ACTIVE_ITEM)[0])
|
|
||||||
const slideEvent = $.Event(Event.SLIDE, {
|
|
||||||
relatedTarget,
|
|
||||||
direction: eventDirectionName,
|
|
||||||
from: fromIndex,
|
|
||||||
to: targetIndex
|
|
||||||
})
|
|
||||||
|
|
||||||
$(this._element).trigger(slideEvent)
|
|
||||||
|
|
||||||
return slideEvent
|
|
||||||
}
|
|
||||||
|
|
||||||
_setActiveIndicatorElement(element) {
|
|
||||||
if (this._indicatorsElement) {
|
|
||||||
$(this._indicatorsElement)
|
|
||||||
.find(Selector.ACTIVE)
|
|
||||||
.removeClass(ClassName.ACTIVE)
|
|
||||||
|
|
||||||
const nextIndicator = this._indicatorsElement.children[
|
|
||||||
this._getItemIndex(element)
|
|
||||||
]
|
|
||||||
|
|
||||||
if (nextIndicator) {
|
|
||||||
$(nextIndicator).addClass(ClassName.ACTIVE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_slide(direction, element) {
|
|
||||||
const activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0]
|
|
||||||
const activeElementIndex = this._getItemIndex(activeElement)
|
|
||||||
const nextElement = element || activeElement &&
|
|
||||||
this._getItemByDirection(direction, activeElement)
|
|
||||||
const nextElementIndex = this._getItemIndex(nextElement)
|
|
||||||
const isCycling = Boolean(this._interval)
|
|
||||||
|
|
||||||
let directionalClassName
|
|
||||||
let orderClassName
|
|
||||||
let eventDirectionName
|
|
||||||
|
|
||||||
if (direction === Direction.NEXT) {
|
|
||||||
directionalClassName = ClassName.LEFT
|
|
||||||
orderClassName = ClassName.NEXT
|
|
||||||
eventDirectionName = Direction.LEFT
|
|
||||||
} else {
|
|
||||||
directionalClassName = ClassName.RIGHT
|
|
||||||
orderClassName = ClassName.PREV
|
|
||||||
eventDirectionName = Direction.RIGHT
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nextElement && $(nextElement).hasClass(ClassName.ACTIVE)) {
|
|
||||||
this._isSliding = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName)
|
|
||||||
if (slideEvent.isDefaultPrevented()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!activeElement || !nextElement) {
|
|
||||||
// Some weirdness is happening, so we bail
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this._isSliding = true
|
|
||||||
|
|
||||||
if (isCycling) {
|
|
||||||
this.pause()
|
|
||||||
}
|
|
||||||
|
|
||||||
this._setActiveIndicatorElement(nextElement)
|
|
||||||
|
|
||||||
const slidEvent = $.Event(Event.SLID, {
|
|
||||||
relatedTarget: nextElement,
|
|
||||||
direction: eventDirectionName,
|
|
||||||
from: activeElementIndex,
|
|
||||||
to: nextElementIndex
|
|
||||||
})
|
|
||||||
|
|
||||||
if (Util.supportsTransitionEnd() &&
|
|
||||||
$(this._element).hasClass(ClassName.SLIDE)) {
|
|
||||||
$(nextElement).addClass(orderClassName)
|
|
||||||
|
|
||||||
Util.reflow(nextElement)
|
|
||||||
|
|
||||||
$(activeElement).addClass(directionalClassName)
|
|
||||||
$(nextElement).addClass(directionalClassName)
|
|
||||||
|
|
||||||
$(activeElement)
|
|
||||||
.one(Util.TRANSITION_END, () => {
|
|
||||||
$(nextElement)
|
|
||||||
.removeClass(`${directionalClassName} ${orderClassName}`)
|
|
||||||
.addClass(ClassName.ACTIVE)
|
|
||||||
|
|
||||||
$(activeElement).removeClass(`${ClassName.ACTIVE} ${orderClassName} ${directionalClassName}`)
|
|
||||||
|
|
||||||
this._isSliding = false
|
|
||||||
|
|
||||||
setTimeout(() => $(this._element).trigger(slidEvent), 0)
|
|
||||||
})
|
|
||||||
.emulateTransitionEnd(TRANSITION_DURATION)
|
|
||||||
} else {
|
|
||||||
$(activeElement).removeClass(ClassName.ACTIVE)
|
|
||||||
$(nextElement).addClass(ClassName.ACTIVE)
|
|
||||||
|
|
||||||
this._isSliding = false
|
|
||||||
$(this._element).trigger(slidEvent)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isCycling) {
|
|
||||||
this.cycle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static
|
|
||||||
|
|
||||||
static _jQueryInterface(config) {
|
|
||||||
return this.each(function () {
|
|
||||||
let data = $(this).data(DATA_KEY)
|
|
||||||
let _config = {
|
|
||||||
...Default,
|
|
||||||
...$(this).data()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof config === 'object') {
|
|
||||||
_config = {
|
|
||||||
..._config,
|
|
||||||
...config
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const action = typeof config === 'string' ? config : _config.slide
|
|
||||||
|
|
||||||
if (!data) {
|
|
||||||
data = new Carousel(this, _config)
|
|
||||||
$(this).data(DATA_KEY, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof config === 'number') {
|
|
||||||
data.to(config)
|
|
||||||
} else if (typeof action === 'string') {
|
|
||||||
if (typeof data[action] === 'undefined') {
|
|
||||||
throw new TypeError(`No method named "${action}"`)
|
|
||||||
}
|
|
||||||
data[action]()
|
|
||||||
} else if (_config.interval) {
|
|
||||||
data.pause()
|
|
||||||
data.cycle()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
static _dataApiClickHandler(event) {
|
|
||||||
const selector = Util.getSelectorFromElement(this)
|
|
||||||
|
|
||||||
if (!selector) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const target = $(selector)[0]
|
|
||||||
|
|
||||||
if (!target || !$(target).hasClass(ClassName.CAROUSEL)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const config = {
|
|
||||||
...$(target).data(),
|
|
||||||
...$(this).data()
|
|
||||||
}
|
|
||||||
const slideIndex = this.getAttribute('data-slide-to')
|
|
||||||
|
|
||||||
if (slideIndex) {
|
|
||||||
config.interval = false
|
|
||||||
}
|
|
||||||
|
|
||||||
Carousel._jQueryInterface.call($(target), config)
|
|
||||||
|
|
||||||
if (slideIndex) {
|
|
||||||
$(target).data(DATA_KEY).to(slideIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
event.preventDefault()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Data Api implementation
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
$(document)
|
|
||||||
.on(Event.CLICK_DATA_API, Selector.DATA_SLIDE, Carousel._dataApiClickHandler)
|
|
||||||
|
|
||||||
$(window).on(Event.LOAD_DATA_API, () => {
|
|
||||||
$(Selector.DATA_RIDE).each(function () {
|
|
||||||
const $carousel = $(this)
|
|
||||||
Carousel._jQueryInterface.call($carousel, $carousel.data())
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* jQuery
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
$.fn[NAME] = Carousel._jQueryInterface
|
|
||||||
$.fn[NAME].Constructor = Carousel
|
|
||||||
$.fn[NAME].noConflict = function () {
|
|
||||||
$.fn[NAME] = JQUERY_NO_CONFLICT
|
|
||||||
return Carousel._jQueryInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
return Carousel
|
|
||||||
})($)
|
|
||||||
|
|
||||||
export default Carousel
|
|
|
@ -1,403 +0,0 @@
|
||||||
import $ from 'jquery'
|
|
||||||
import Util from './util'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Bootstrap (v4.0.0): collapse.js
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const Collapse = (($) => {
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Constants
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const NAME = 'collapse'
|
|
||||||
const VERSION = '4.0.0'
|
|
||||||
const DATA_KEY = 'bs.collapse'
|
|
||||||
const EVENT_KEY = `.${DATA_KEY}`
|
|
||||||
const DATA_API_KEY = '.data-api'
|
|
||||||
const JQUERY_NO_CONFLICT = $.fn[NAME]
|
|
||||||
const TRANSITION_DURATION = 600
|
|
||||||
|
|
||||||
const Default = {
|
|
||||||
toggle : true,
|
|
||||||
parent : ''
|
|
||||||
}
|
|
||||||
|
|
||||||
const DefaultType = {
|
|
||||||
toggle : 'boolean',
|
|
||||||
parent : '(string|element)'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Event = {
|
|
||||||
SHOW : `show${EVENT_KEY}`,
|
|
||||||
SHOWN : `shown${EVENT_KEY}`,
|
|
||||||
HIDE : `hide${EVENT_KEY}`,
|
|
||||||
HIDDEN : `hidden${EVENT_KEY}`,
|
|
||||||
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const ClassName = {
|
|
||||||
SHOW : 'show',
|
|
||||||
COLLAPSE : 'collapse',
|
|
||||||
COLLAPSING : 'collapsing',
|
|
||||||
COLLAPSED : 'collapsed'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Dimension = {
|
|
||||||
WIDTH : 'width',
|
|
||||||
HEIGHT : 'height'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Selector = {
|
|
||||||
ACTIVES : '.show, .collapsing',
|
|
||||||
DATA_TOGGLE : '[data-toggle="collapse"]'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Class Definition
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Collapse {
|
|
||||||
constructor(element, config) {
|
|
||||||
this._isTransitioning = false
|
|
||||||
this._element = element
|
|
||||||
this._config = this._getConfig(config)
|
|
||||||
this._triggerArray = $.makeArray($(
|
|
||||||
`[data-toggle="collapse"][href="#${element.id}"],` +
|
|
||||||
`[data-toggle="collapse"][data-target="#${element.id}"]`
|
|
||||||
))
|
|
||||||
const tabToggles = $(Selector.DATA_TOGGLE)
|
|
||||||
for (let i = 0; i < tabToggles.length; i++) {
|
|
||||||
const elem = tabToggles[i]
|
|
||||||
const selector = Util.getSelectorFromElement(elem)
|
|
||||||
if (selector !== null && $(selector).filter(element).length > 0) {
|
|
||||||
this._selector = selector
|
|
||||||
this._triggerArray.push(elem)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this._parent = this._config.parent ? this._getParent() : null
|
|
||||||
|
|
||||||
if (!this._config.parent) {
|
|
||||||
this._addAriaAndCollapsedClass(this._element, this._triggerArray)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._config.toggle) {
|
|
||||||
this.toggle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getters
|
|
||||||
|
|
||||||
static get VERSION() {
|
|
||||||
return VERSION
|
|
||||||
}
|
|
||||||
|
|
||||||
static get Default() {
|
|
||||||
return Default
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public
|
|
||||||
|
|
||||||
toggle() {
|
|
||||||
if ($(this._element).hasClass(ClassName.SHOW)) {
|
|
||||||
this.hide()
|
|
||||||
} else {
|
|
||||||
this.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
show() {
|
|
||||||
if (this._isTransitioning ||
|
|
||||||
$(this._element).hasClass(ClassName.SHOW)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let actives
|
|
||||||
let activesData
|
|
||||||
|
|
||||||
if (this._parent) {
|
|
||||||
actives = $.makeArray(
|
|
||||||
$(this._parent)
|
|
||||||
.find(Selector.ACTIVES)
|
|
||||||
.filter(`[data-parent="${this._config.parent}"]`)
|
|
||||||
)
|
|
||||||
if (actives.length === 0) {
|
|
||||||
actives = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (actives) {
|
|
||||||
activesData = $(actives).not(this._selector).data(DATA_KEY)
|
|
||||||
if (activesData && activesData._isTransitioning) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const startEvent = $.Event(Event.SHOW)
|
|
||||||
$(this._element).trigger(startEvent)
|
|
||||||
if (startEvent.isDefaultPrevented()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (actives) {
|
|
||||||
Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide')
|
|
||||||
if (!activesData) {
|
|
||||||
$(actives).data(DATA_KEY, null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const dimension = this._getDimension()
|
|
||||||
|
|
||||||
$(this._element)
|
|
||||||
.removeClass(ClassName.COLLAPSE)
|
|
||||||
.addClass(ClassName.COLLAPSING)
|
|
||||||
|
|
||||||
this._element.style[dimension] = 0
|
|
||||||
|
|
||||||
if (this._triggerArray.length > 0) {
|
|
||||||
$(this._triggerArray)
|
|
||||||
.removeClass(ClassName.COLLAPSED)
|
|
||||||
.attr('aria-expanded', true)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setTransitioning(true)
|
|
||||||
|
|
||||||
const complete = () => {
|
|
||||||
$(this._element)
|
|
||||||
.removeClass(ClassName.COLLAPSING)
|
|
||||||
.addClass(ClassName.COLLAPSE)
|
|
||||||
.addClass(ClassName.SHOW)
|
|
||||||
|
|
||||||
this._element.style[dimension] = ''
|
|
||||||
|
|
||||||
this.setTransitioning(false)
|
|
||||||
|
|
||||||
$(this._element).trigger(Event.SHOWN)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Util.supportsTransitionEnd()) {
|
|
||||||
complete()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)
|
|
||||||
const scrollSize = `scroll${capitalizedDimension}`
|
|
||||||
|
|
||||||
$(this._element)
|
|
||||||
.one(Util.TRANSITION_END, complete)
|
|
||||||
.emulateTransitionEnd(TRANSITION_DURATION)
|
|
||||||
|
|
||||||
this._element.style[dimension] = `${this._element[scrollSize]}px`
|
|
||||||
}
|
|
||||||
|
|
||||||
hide() {
|
|
||||||
if (this._isTransitioning ||
|
|
||||||
!$(this._element).hasClass(ClassName.SHOW)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const startEvent = $.Event(Event.HIDE)
|
|
||||||
$(this._element).trigger(startEvent)
|
|
||||||
if (startEvent.isDefaultPrevented()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const dimension = this._getDimension()
|
|
||||||
|
|
||||||
this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`
|
|
||||||
|
|
||||||
Util.reflow(this._element)
|
|
||||||
|
|
||||||
$(this._element)
|
|
||||||
.addClass(ClassName.COLLAPSING)
|
|
||||||
.removeClass(ClassName.COLLAPSE)
|
|
||||||
.removeClass(ClassName.SHOW)
|
|
||||||
|
|
||||||
if (this._triggerArray.length > 0) {
|
|
||||||
for (let i = 0; i < this._triggerArray.length; i++) {
|
|
||||||
const trigger = this._triggerArray[i]
|
|
||||||
const selector = Util.getSelectorFromElement(trigger)
|
|
||||||
if (selector !== null) {
|
|
||||||
const $elem = $(selector)
|
|
||||||
if (!$elem.hasClass(ClassName.SHOW)) {
|
|
||||||
$(trigger).addClass(ClassName.COLLAPSED)
|
|
||||||
.attr('aria-expanded', false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setTransitioning(true)
|
|
||||||
|
|
||||||
const complete = () => {
|
|
||||||
this.setTransitioning(false)
|
|
||||||
$(this._element)
|
|
||||||
.removeClass(ClassName.COLLAPSING)
|
|
||||||
.addClass(ClassName.COLLAPSE)
|
|
||||||
.trigger(Event.HIDDEN)
|
|
||||||
}
|
|
||||||
|
|
||||||
this._element.style[dimension] = ''
|
|
||||||
|
|
||||||
if (!Util.supportsTransitionEnd()) {
|
|
||||||
complete()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
$(this._element)
|
|
||||||
.one(Util.TRANSITION_END, complete)
|
|
||||||
.emulateTransitionEnd(TRANSITION_DURATION)
|
|
||||||
}
|
|
||||||
|
|
||||||
setTransitioning(isTransitioning) {
|
|
||||||
this._isTransitioning = isTransitioning
|
|
||||||
}
|
|
||||||
|
|
||||||
dispose() {
|
|
||||||
$.removeData(this._element, DATA_KEY)
|
|
||||||
|
|
||||||
this._config = null
|
|
||||||
this._parent = null
|
|
||||||
this._element = null
|
|
||||||
this._triggerArray = null
|
|
||||||
this._isTransitioning = null
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private
|
|
||||||
|
|
||||||
_getConfig(config) {
|
|
||||||
config = {
|
|
||||||
...Default,
|
|
||||||
...config
|
|
||||||
}
|
|
||||||
config.toggle = Boolean(config.toggle) // Coerce string values
|
|
||||||
Util.typeCheckConfig(NAME, config, DefaultType)
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
|
|
||||||
_getDimension() {
|
|
||||||
const hasWidth = $(this._element).hasClass(Dimension.WIDTH)
|
|
||||||
return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT
|
|
||||||
}
|
|
||||||
|
|
||||||
_getParent() {
|
|
||||||
let parent = null
|
|
||||||
if (Util.isElement(this._config.parent)) {
|
|
||||||
parent = this._config.parent
|
|
||||||
|
|
||||||
// It's a jQuery object
|
|
||||||
if (typeof this._config.parent.jquery !== 'undefined') {
|
|
||||||
parent = this._config.parent[0]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
parent = $(this._config.parent)[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
const selector =
|
|
||||||
`[data-toggle="collapse"][data-parent="${this._config.parent}"]`
|
|
||||||
|
|
||||||
$(parent).find(selector).each((i, element) => {
|
|
||||||
this._addAriaAndCollapsedClass(
|
|
||||||
Collapse._getTargetFromElement(element),
|
|
||||||
[element]
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
return parent
|
|
||||||
}
|
|
||||||
|
|
||||||
_addAriaAndCollapsedClass(element, triggerArray) {
|
|
||||||
if (element) {
|
|
||||||
const isOpen = $(element).hasClass(ClassName.SHOW)
|
|
||||||
|
|
||||||
if (triggerArray.length > 0) {
|
|
||||||
$(triggerArray)
|
|
||||||
.toggleClass(ClassName.COLLAPSED, !isOpen)
|
|
||||||
.attr('aria-expanded', isOpen)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static
|
|
||||||
|
|
||||||
static _getTargetFromElement(element) {
|
|
||||||
const selector = Util.getSelectorFromElement(element)
|
|
||||||
return selector ? $(selector)[0] : null
|
|
||||||
}
|
|
||||||
|
|
||||||
static _jQueryInterface(config) {
|
|
||||||
return this.each(function () {
|
|
||||||
const $this = $(this)
|
|
||||||
let data = $this.data(DATA_KEY)
|
|
||||||
const _config = {
|
|
||||||
...Default,
|
|
||||||
...$this.data(),
|
|
||||||
...typeof config === 'object' && config
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!data && _config.toggle && /show|hide/.test(config)) {
|
|
||||||
_config.toggle = false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!data) {
|
|
||||||
data = new Collapse(this, _config)
|
|
||||||
$this.data(DATA_KEY, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof config === 'string') {
|
|
||||||
if (typeof data[config] === 'undefined') {
|
|
||||||
throw new TypeError(`No method named "${config}"`)
|
|
||||||
}
|
|
||||||
data[config]()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Data Api implementation
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
$(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
|
|
||||||
// preventDefault only for <a> elements (which change the URL) not inside the collapsible element
|
|
||||||
if (event.currentTarget.tagName === 'A') {
|
|
||||||
event.preventDefault()
|
|
||||||
}
|
|
||||||
|
|
||||||
const $trigger = $(this)
|
|
||||||
const selector = Util.getSelectorFromElement(this)
|
|
||||||
$(selector).each(function () {
|
|
||||||
const $target = $(this)
|
|
||||||
const data = $target.data(DATA_KEY)
|
|
||||||
const config = data ? 'toggle' : $trigger.data()
|
|
||||||
Collapse._jQueryInterface.call($target, config)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* jQuery
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
$.fn[NAME] = Collapse._jQueryInterface
|
|
||||||
$.fn[NAME].Constructor = Collapse
|
|
||||||
$.fn[NAME].noConflict = function () {
|
|
||||||
$.fn[NAME] = JQUERY_NO_CONFLICT
|
|
||||||
return Collapse._jQueryInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
return Collapse
|
|
||||||
})($)
|
|
||||||
|
|
||||||
export default Collapse
|
|
|
@ -1,470 +0,0 @@
|
||||||
import $ from 'jquery'
|
|
||||||
import Popper from 'popper.js'
|
|
||||||
import Util from './util'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Bootstrap (v4.0.0): dropdown.js
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const Dropdown = (($) => {
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Constants
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const NAME = 'dropdown'
|
|
||||||
const VERSION = '4.0.0'
|
|
||||||
const DATA_KEY = 'bs.dropdown'
|
|
||||||
const EVENT_KEY = `.${DATA_KEY}`
|
|
||||||
const DATA_API_KEY = '.data-api'
|
|
||||||
const JQUERY_NO_CONFLICT = $.fn[NAME]
|
|
||||||
const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key
|
|
||||||
const SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key
|
|
||||||
const TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key
|
|
||||||
const ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key
|
|
||||||
const ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key
|
|
||||||
const RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse)
|
|
||||||
const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`)
|
|
||||||
|
|
||||||
const Event = {
|
|
||||||
HIDE : `hide${EVENT_KEY}`,
|
|
||||||
HIDDEN : `hidden${EVENT_KEY}`,
|
|
||||||
SHOW : `show${EVENT_KEY}`,
|
|
||||||
SHOWN : `shown${EVENT_KEY}`,
|
|
||||||
CLICK : `click${EVENT_KEY}`,
|
|
||||||
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`,
|
|
||||||
KEYDOWN_DATA_API : `keydown${EVENT_KEY}${DATA_API_KEY}`,
|
|
||||||
KEYUP_DATA_API : `keyup${EVENT_KEY}${DATA_API_KEY}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const ClassName = {
|
|
||||||
DISABLED : 'disabled',
|
|
||||||
SHOW : 'show',
|
|
||||||
DROPUP : 'dropup',
|
|
||||||
DROPRIGHT : 'dropright',
|
|
||||||
DROPLEFT : 'dropleft',
|
|
||||||
MENURIGHT : 'dropdown-menu-right',
|
|
||||||
MENULEFT : 'dropdown-menu-left',
|
|
||||||
POSITION_STATIC : 'position-static'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Selector = {
|
|
||||||
DATA_TOGGLE : '[data-toggle="dropdown"]',
|
|
||||||
FORM_CHILD : '.dropdown form',
|
|
||||||
MENU : '.dropdown-menu',
|
|
||||||
NAVBAR_NAV : '.navbar-nav',
|
|
||||||
VISIBLE_ITEMS : '.dropdown-menu .dropdown-item:not(.disabled)'
|
|
||||||
}
|
|
||||||
|
|
||||||
const AttachmentMap = {
|
|
||||||
TOP : 'top-start',
|
|
||||||
TOPEND : 'top-end',
|
|
||||||
BOTTOM : 'bottom-start',
|
|
||||||
BOTTOMEND : 'bottom-end',
|
|
||||||
RIGHT : 'right-start',
|
|
||||||
RIGHTEND : 'right-end',
|
|
||||||
LEFT : 'left-start',
|
|
||||||
LEFTEND : 'left-end'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Default = {
|
|
||||||
offset : 0,
|
|
||||||
flip : true,
|
|
||||||
boundary : 'scrollParent'
|
|
||||||
}
|
|
||||||
|
|
||||||
const DefaultType = {
|
|
||||||
offset : '(number|string|function)',
|
|
||||||
flip : 'boolean',
|
|
||||||
boundary : '(string|element)'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Class Definition
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Dropdown {
|
|
||||||
constructor(element, config) {
|
|
||||||
this._element = element
|
|
||||||
this._popper = null
|
|
||||||
this._config = this._getConfig(config)
|
|
||||||
this._menu = this._getMenuElement()
|
|
||||||
this._inNavbar = this._detectNavbar()
|
|
||||||
|
|
||||||
this._addEventListeners()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getters
|
|
||||||
|
|
||||||
static get VERSION() {
|
|
||||||
return VERSION
|
|
||||||
}
|
|
||||||
|
|
||||||
static get Default() {
|
|
||||||
return Default
|
|
||||||
}
|
|
||||||
|
|
||||||
static get DefaultType() {
|
|
||||||
return DefaultType
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public
|
|
||||||
|
|
||||||
toggle() {
|
|
||||||
if (this._element.disabled || $(this._element).hasClass(ClassName.DISABLED)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const parent = Dropdown._getParentFromElement(this._element)
|
|
||||||
const isActive = $(this._menu).hasClass(ClassName.SHOW)
|
|
||||||
|
|
||||||
Dropdown._clearMenus()
|
|
||||||
|
|
||||||
if (isActive) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const relatedTarget = {
|
|
||||||
relatedTarget: this._element
|
|
||||||
}
|
|
||||||
const showEvent = $.Event(Event.SHOW, relatedTarget)
|
|
||||||
|
|
||||||
$(parent).trigger(showEvent)
|
|
||||||
|
|
||||||
if (showEvent.isDefaultPrevented()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable totally Popper.js for Dropdown in Navbar
|
|
||||||
if (!this._inNavbar) {
|
|
||||||
/**
|
|
||||||
* Check for Popper dependency
|
|
||||||
* Popper - https://popper.js.org
|
|
||||||
*/
|
|
||||||
if (typeof Popper === 'undefined') {
|
|
||||||
throw new TypeError('Bootstrap dropdown require Popper.js (https://popper.js.org)')
|
|
||||||
}
|
|
||||||
let element = this._element
|
|
||||||
// For dropup with alignment we use the parent as popper container
|
|
||||||
if ($(parent).hasClass(ClassName.DROPUP)) {
|
|
||||||
if ($(this._menu).hasClass(ClassName.MENULEFT) || $(this._menu).hasClass(ClassName.MENURIGHT)) {
|
|
||||||
element = parent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If boundary is not `scrollParent`, then set position to `static`
|
|
||||||
// to allow the menu to "escape" the scroll parent's boundaries
|
|
||||||
// https://github.com/twbs/bootstrap/issues/24251
|
|
||||||
if (this._config.boundary !== 'scrollParent') {
|
|
||||||
$(parent).addClass(ClassName.POSITION_STATIC)
|
|
||||||
}
|
|
||||||
this._popper = new Popper(element, this._menu, this._getPopperConfig())
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this is a touch-enabled device we add extra
|
|
||||||
// empty mouseover listeners to the body's immediate children;
|
|
||||||
// only needed because of broken event delegation on iOS
|
|
||||||
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
|
|
||||||
if ('ontouchstart' in document.documentElement &&
|
|
||||||
$(parent).closest(Selector.NAVBAR_NAV).length === 0) {
|
|
||||||
$('body').children().on('mouseover', null, $.noop)
|
|
||||||
}
|
|
||||||
|
|
||||||
this._element.focus()
|
|
||||||
this._element.setAttribute('aria-expanded', true)
|
|
||||||
|
|
||||||
$(this._menu).toggleClass(ClassName.SHOW)
|
|
||||||
$(parent)
|
|
||||||
.toggleClass(ClassName.SHOW)
|
|
||||||
.trigger($.Event(Event.SHOWN, relatedTarget))
|
|
||||||
}
|
|
||||||
|
|
||||||
dispose() {
|
|
||||||
$.removeData(this._element, DATA_KEY)
|
|
||||||
$(this._element).off(EVENT_KEY)
|
|
||||||
this._element = null
|
|
||||||
this._menu = null
|
|
||||||
if (this._popper !== null) {
|
|
||||||
this._popper.destroy()
|
|
||||||
this._popper = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
update() {
|
|
||||||
this._inNavbar = this._detectNavbar()
|
|
||||||
if (this._popper !== null) {
|
|
||||||
this._popper.scheduleUpdate()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private
|
|
||||||
|
|
||||||
_addEventListeners() {
|
|
||||||
$(this._element).on(Event.CLICK, (event) => {
|
|
||||||
event.preventDefault()
|
|
||||||
event.stopPropagation()
|
|
||||||
this.toggle()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
_getConfig(config) {
|
|
||||||
config = {
|
|
||||||
...this.constructor.Default,
|
|
||||||
...$(this._element).data(),
|
|
||||||
...config
|
|
||||||
}
|
|
||||||
|
|
||||||
Util.typeCheckConfig(
|
|
||||||
NAME,
|
|
||||||
config,
|
|
||||||
this.constructor.DefaultType
|
|
||||||
)
|
|
||||||
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
|
|
||||||
_getMenuElement() {
|
|
||||||
if (!this._menu) {
|
|
||||||
const parent = Dropdown._getParentFromElement(this._element)
|
|
||||||
this._menu = $(parent).find(Selector.MENU)[0]
|
|
||||||
}
|
|
||||||
return this._menu
|
|
||||||
}
|
|
||||||
|
|
||||||
_getPlacement() {
|
|
||||||
const $parentDropdown = $(this._element).parent()
|
|
||||||
let placement = AttachmentMap.BOTTOM
|
|
||||||
|
|
||||||
// Handle dropup
|
|
||||||
if ($parentDropdown.hasClass(ClassName.DROPUP)) {
|
|
||||||
placement = AttachmentMap.TOP
|
|
||||||
if ($(this._menu).hasClass(ClassName.MENURIGHT)) {
|
|
||||||
placement = AttachmentMap.TOPEND
|
|
||||||
}
|
|
||||||
} else if ($parentDropdown.hasClass(ClassName.DROPRIGHT)) {
|
|
||||||
placement = AttachmentMap.RIGHT
|
|
||||||
} else if ($parentDropdown.hasClass(ClassName.DROPLEFT)) {
|
|
||||||
placement = AttachmentMap.LEFT
|
|
||||||
} else if ($(this._menu).hasClass(ClassName.MENURIGHT)) {
|
|
||||||
placement = AttachmentMap.BOTTOMEND
|
|
||||||
}
|
|
||||||
return placement
|
|
||||||
}
|
|
||||||
|
|
||||||
_detectNavbar() {
|
|
||||||
return $(this._element).closest('.navbar').length > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
_getPopperConfig() {
|
|
||||||
const offsetConf = {}
|
|
||||||
if (typeof this._config.offset === 'function') {
|
|
||||||
offsetConf.fn = (data) => {
|
|
||||||
data.offsets = {
|
|
||||||
...data.offsets,
|
|
||||||
...this._config.offset(data.offsets) || {}
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
offsetConf.offset = this._config.offset
|
|
||||||
}
|
|
||||||
const popperConfig = {
|
|
||||||
placement: this._getPlacement(),
|
|
||||||
modifiers: {
|
|
||||||
offset: offsetConf,
|
|
||||||
flip: {
|
|
||||||
enabled: this._config.flip
|
|
||||||
},
|
|
||||||
preventOverflow: {
|
|
||||||
boundariesElement: this._config.boundary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return popperConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static
|
|
||||||
|
|
||||||
static _jQueryInterface(config) {
|
|
||||||
return this.each(function () {
|
|
||||||
let data = $(this).data(DATA_KEY)
|
|
||||||
const _config = typeof config === 'object' ? config : null
|
|
||||||
|
|
||||||
if (!data) {
|
|
||||||
data = new Dropdown(this, _config)
|
|
||||||
$(this).data(DATA_KEY, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof config === 'string') {
|
|
||||||
if (typeof data[config] === 'undefined') {
|
|
||||||
throw new TypeError(`No method named "${config}"`)
|
|
||||||
}
|
|
||||||
data[config]()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
static _clearMenus(event) {
|
|
||||||
if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH ||
|
|
||||||
event.type === 'keyup' && event.which !== TAB_KEYCODE)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const toggles = $.makeArray($(Selector.DATA_TOGGLE))
|
|
||||||
for (let i = 0; i < toggles.length; i++) {
|
|
||||||
const parent = Dropdown._getParentFromElement(toggles[i])
|
|
||||||
const context = $(toggles[i]).data(DATA_KEY)
|
|
||||||
const relatedTarget = {
|
|
||||||
relatedTarget: toggles[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!context) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
const dropdownMenu = context._menu
|
|
||||||
if (!$(parent).hasClass(ClassName.SHOW)) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event && (event.type === 'click' &&
|
|
||||||
/input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) &&
|
|
||||||
$.contains(parent, event.target)) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
const hideEvent = $.Event(Event.HIDE, relatedTarget)
|
|
||||||
$(parent).trigger(hideEvent)
|
|
||||||
if (hideEvent.isDefaultPrevented()) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this is a touch-enabled device we remove the extra
|
|
||||||
// empty mouseover listeners we added for iOS support
|
|
||||||
if ('ontouchstart' in document.documentElement) {
|
|
||||||
$('body').children().off('mouseover', null, $.noop)
|
|
||||||
}
|
|
||||||
|
|
||||||
toggles[i].setAttribute('aria-expanded', 'false')
|
|
||||||
|
|
||||||
$(dropdownMenu).removeClass(ClassName.SHOW)
|
|
||||||
$(parent)
|
|
||||||
.removeClass(ClassName.SHOW)
|
|
||||||
.trigger($.Event(Event.HIDDEN, relatedTarget))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static _getParentFromElement(element) {
|
|
||||||
let parent
|
|
||||||
const selector = Util.getSelectorFromElement(element)
|
|
||||||
|
|
||||||
if (selector) {
|
|
||||||
parent = $(selector)[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
return parent || element.parentNode
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line complexity
|
|
||||||
static _dataApiKeydownHandler(event) {
|
|
||||||
// If not input/textarea:
|
|
||||||
// - And not a key in REGEXP_KEYDOWN => not a dropdown command
|
|
||||||
// If input/textarea:
|
|
||||||
// - If space key => not a dropdown command
|
|
||||||
// - If key is other than escape
|
|
||||||
// - If key is not up or down => not a dropdown command
|
|
||||||
// - If trigger inside the menu => not a dropdown command
|
|
||||||
if (/input|textarea/i.test(event.target.tagName)
|
|
||||||
? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE &&
|
|
||||||
(event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE ||
|
|
||||||
$(event.target).closest(Selector.MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
event.preventDefault()
|
|
||||||
event.stopPropagation()
|
|
||||||
|
|
||||||
if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const parent = Dropdown._getParentFromElement(this)
|
|
||||||
const isActive = $(parent).hasClass(ClassName.SHOW)
|
|
||||||
|
|
||||||
if (!isActive && (event.which !== ESCAPE_KEYCODE || event.which !== SPACE_KEYCODE) ||
|
|
||||||
isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {
|
|
||||||
if (event.which === ESCAPE_KEYCODE) {
|
|
||||||
const toggle = $(parent).find(Selector.DATA_TOGGLE)[0]
|
|
||||||
$(toggle).trigger('focus')
|
|
||||||
}
|
|
||||||
|
|
||||||
$(this).trigger('click')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const items = $(parent).find(Selector.VISIBLE_ITEMS).get()
|
|
||||||
|
|
||||||
if (items.length === 0) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let index = items.indexOf(event.target)
|
|
||||||
|
|
||||||
if (event.which === ARROW_UP_KEYCODE && index > 0) { // Up
|
|
||||||
index--
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // Down
|
|
||||||
index++
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index < 0) {
|
|
||||||
index = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
items[index].focus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Data Api implementation
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
$(document)
|
|
||||||
.on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler)
|
|
||||||
.on(Event.KEYDOWN_DATA_API, Selector.MENU, Dropdown._dataApiKeydownHandler)
|
|
||||||
.on(`${Event.CLICK_DATA_API} ${Event.KEYUP_DATA_API}`, Dropdown._clearMenus)
|
|
||||||
.on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
|
|
||||||
event.preventDefault()
|
|
||||||
event.stopPropagation()
|
|
||||||
Dropdown._jQueryInterface.call($(this), 'toggle')
|
|
||||||
})
|
|
||||||
.on(Event.CLICK_DATA_API, Selector.FORM_CHILD, (e) => {
|
|
||||||
e.stopPropagation()
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* jQuery
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
$.fn[NAME] = Dropdown._jQueryInterface
|
|
||||||
$.fn[NAME].Constructor = Dropdown
|
|
||||||
$.fn[NAME].noConflict = function () {
|
|
||||||
$.fn[NAME] = JQUERY_NO_CONFLICT
|
|
||||||
return Dropdown._jQueryInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
return Dropdown
|
|
||||||
})($, Popper)
|
|
||||||
|
|
||||||
export default Dropdown
|
|
|
@ -1,50 +0,0 @@
|
||||||
import $ from 'jquery'
|
|
||||||
import Alert from './alert'
|
|
||||||
import Button from './button'
|
|
||||||
import Carousel from './carousel'
|
|
||||||
import Collapse from './collapse'
|
|
||||||
import Dropdown from './dropdown'
|
|
||||||
import Modal from './modal'
|
|
||||||
import Popover from './popover'
|
|
||||||
import Scrollspy from './scrollspy'
|
|
||||||
import Tab from './tab'
|
|
||||||
import Tooltip from './tooltip'
|
|
||||||
import Util from './util'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Bootstrap (v4.0.0-alpha.6): index.js
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
(($) => {
|
|
||||||
if (typeof $ === 'undefined') {
|
|
||||||
throw new TypeError('Bootstrap\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\'s JavaScript.')
|
|
||||||
}
|
|
||||||
|
|
||||||
const version = $.fn.jquery.split(' ')[0].split('.')
|
|
||||||
const minMajor = 1
|
|
||||||
const ltMajor = 2
|
|
||||||
const minMinor = 9
|
|
||||||
const minPatch = 1
|
|
||||||
const maxMajor = 4
|
|
||||||
|
|
||||||
if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) {
|
|
||||||
throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0')
|
|
||||||
}
|
|
||||||
})($)
|
|
||||||
|
|
||||||
export {
|
|
||||||
Util,
|
|
||||||
Alert,
|
|
||||||
Button,
|
|
||||||
Carousel,
|
|
||||||
Collapse,
|
|
||||||
Dropdown,
|
|
||||||
Modal,
|
|
||||||
Popover,
|
|
||||||
Scrollspy,
|
|
||||||
Tab,
|
|
||||||
Tooltip
|
|
||||||
}
|
|
|
@ -1,578 +0,0 @@
|
||||||
import $ from 'jquery'
|
|
||||||
import Util from './util'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Bootstrap (v4.0.0): modal.js
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const Modal = (($) => {
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Constants
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const NAME = 'modal'
|
|
||||||
const VERSION = '4.0.0'
|
|
||||||
const DATA_KEY = 'bs.modal'
|
|
||||||
const EVENT_KEY = `.${DATA_KEY}`
|
|
||||||
const DATA_API_KEY = '.data-api'
|
|
||||||
const JQUERY_NO_CONFLICT = $.fn[NAME]
|
|
||||||
const TRANSITION_DURATION = 300
|
|
||||||
const BACKDROP_TRANSITION_DURATION = 150
|
|
||||||
const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key
|
|
||||||
|
|
||||||
const Default = {
|
|
||||||
backdrop : true,
|
|
||||||
keyboard : true,
|
|
||||||
focus : true,
|
|
||||||
show : true
|
|
||||||
}
|
|
||||||
|
|
||||||
const DefaultType = {
|
|
||||||
backdrop : '(boolean|string)',
|
|
||||||
keyboard : 'boolean',
|
|
||||||
focus : 'boolean',
|
|
||||||
show : 'boolean'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Event = {
|
|
||||||
HIDE : `hide${EVENT_KEY}`,
|
|
||||||
HIDDEN : `hidden${EVENT_KEY}`,
|
|
||||||
SHOW : `show${EVENT_KEY}`,
|
|
||||||
SHOWN : `shown${EVENT_KEY}`,
|
|
||||||
FOCUSIN : `focusin${EVENT_KEY}`,
|
|
||||||
RESIZE : `resize${EVENT_KEY}`,
|
|
||||||
CLICK_DISMISS : `click.dismiss${EVENT_KEY}`,
|
|
||||||
KEYDOWN_DISMISS : `keydown.dismiss${EVENT_KEY}`,
|
|
||||||
MOUSEUP_DISMISS : `mouseup.dismiss${EVENT_KEY}`,
|
|
||||||
MOUSEDOWN_DISMISS : `mousedown.dismiss${EVENT_KEY}`,
|
|
||||||
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const ClassName = {
|
|
||||||
SCROLLBAR_MEASURER : 'modal-scrollbar-measure',
|
|
||||||
BACKDROP : 'modal-backdrop',
|
|
||||||
OPEN : 'modal-open',
|
|
||||||
FADE : 'fade',
|
|
||||||
SHOW : 'show'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Selector = {
|
|
||||||
DIALOG : '.modal-dialog',
|
|
||||||
DATA_TOGGLE : '[data-toggle="modal"]',
|
|
||||||
DATA_DISMISS : '[data-dismiss="modal"]',
|
|
||||||
FIXED_CONTENT : '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top',
|
|
||||||
STICKY_CONTENT : '.sticky-top',
|
|
||||||
NAVBAR_TOGGLER : '.navbar-toggler'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Class Definition
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Modal {
|
|
||||||
constructor(element, config) {
|
|
||||||
this._config = this._getConfig(config)
|
|
||||||
this._element = element
|
|
||||||
this._dialog = $(element).find(Selector.DIALOG)[0]
|
|
||||||
this._backdrop = null
|
|
||||||
this._isShown = false
|
|
||||||
this._isBodyOverflowing = false
|
|
||||||
this._ignoreBackdropClick = false
|
|
||||||
this._originalBodyPadding = 0
|
|
||||||
this._scrollbarWidth = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getters
|
|
||||||
|
|
||||||
static get VERSION() {
|
|
||||||
return VERSION
|
|
||||||
}
|
|
||||||
|
|
||||||
static get Default() {
|
|
||||||
return Default
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public
|
|
||||||
|
|
||||||
toggle(relatedTarget) {
|
|
||||||
return this._isShown ? this.hide() : this.show(relatedTarget)
|
|
||||||
}
|
|
||||||
|
|
||||||
show(relatedTarget) {
|
|
||||||
if (this._isTransitioning || this._isShown) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)) {
|
|
||||||
this._isTransitioning = true
|
|
||||||
}
|
|
||||||
|
|
||||||
const showEvent = $.Event(Event.SHOW, {
|
|
||||||
relatedTarget
|
|
||||||
})
|
|
||||||
|
|
||||||
$(this._element).trigger(showEvent)
|
|
||||||
|
|
||||||
if (this._isShown || showEvent.isDefaultPrevented()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this._isShown = true
|
|
||||||
|
|
||||||
this._checkScrollbar()
|
|
||||||
this._setScrollbar()
|
|
||||||
|
|
||||||
this._adjustDialog()
|
|
||||||
|
|
||||||
$(document.body).addClass(ClassName.OPEN)
|
|
||||||
|
|
||||||
this._setEscapeEvent()
|
|
||||||
this._setResizeEvent()
|
|
||||||
|
|
||||||
$(this._element).on(
|
|
||||||
Event.CLICK_DISMISS,
|
|
||||||
Selector.DATA_DISMISS,
|
|
||||||
(event) => this.hide(event)
|
|
||||||
)
|
|
||||||
|
|
||||||
$(this._dialog).on(Event.MOUSEDOWN_DISMISS, () => {
|
|
||||||
$(this._element).one(Event.MOUSEUP_DISMISS, (event) => {
|
|
||||||
if ($(event.target).is(this._element)) {
|
|
||||||
this._ignoreBackdropClick = true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
this._showBackdrop(() => this._showElement(relatedTarget))
|
|
||||||
}
|
|
||||||
|
|
||||||
hide(event) {
|
|
||||||
if (event) {
|
|
||||||
event.preventDefault()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._isTransitioning || !this._isShown) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const hideEvent = $.Event(Event.HIDE)
|
|
||||||
|
|
||||||
$(this._element).trigger(hideEvent)
|
|
||||||
|
|
||||||
if (!this._isShown || hideEvent.isDefaultPrevented()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this._isShown = false
|
|
||||||
|
|
||||||
const transition = Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)
|
|
||||||
|
|
||||||
if (transition) {
|
|
||||||
this._isTransitioning = true
|
|
||||||
}
|
|
||||||
|
|
||||||
this._setEscapeEvent()
|
|
||||||
this._setResizeEvent()
|
|
||||||
|
|
||||||
$(document).off(Event.FOCUSIN)
|
|
||||||
|
|
||||||
$(this._element).removeClass(ClassName.SHOW)
|
|
||||||
|
|
||||||
$(this._element).off(Event.CLICK_DISMISS)
|
|
||||||
$(this._dialog).off(Event.MOUSEDOWN_DISMISS)
|
|
||||||
|
|
||||||
if (transition) {
|
|
||||||
$(this._element)
|
|
||||||
.one(Util.TRANSITION_END, (event) => this._hideModal(event))
|
|
||||||
.emulateTransitionEnd(TRANSITION_DURATION)
|
|
||||||
} else {
|
|
||||||
this._hideModal()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dispose() {
|
|
||||||
$.removeData(this._element, DATA_KEY)
|
|
||||||
|
|
||||||
$(window, document, this._element, this._backdrop).off(EVENT_KEY)
|
|
||||||
|
|
||||||
this._config = null
|
|
||||||
this._element = null
|
|
||||||
this._dialog = null
|
|
||||||
this._backdrop = null
|
|
||||||
this._isShown = null
|
|
||||||
this._isBodyOverflowing = null
|
|
||||||
this._ignoreBackdropClick = null
|
|
||||||
this._scrollbarWidth = null
|
|
||||||
}
|
|
||||||
|
|
||||||
handleUpdate() {
|
|
||||||
this._adjustDialog()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private
|
|
||||||
|
|
||||||
_getConfig(config) {
|
|
||||||
config = {
|
|
||||||
...Default,
|
|
||||||
...config
|
|
||||||
}
|
|
||||||
Util.typeCheckConfig(NAME, config, DefaultType)
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
|
|
||||||
_showElement(relatedTarget) {
|
|
||||||
const transition = Util.supportsTransitionEnd() &&
|
|
||||||
$(this._element).hasClass(ClassName.FADE)
|
|
||||||
|
|
||||||
if (!this._element.parentNode ||
|
|
||||||
this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
|
|
||||||
// Don't move modal's DOM position
|
|
||||||
document.body.appendChild(this._element)
|
|
||||||
}
|
|
||||||
|
|
||||||
this._element.style.display = 'block'
|
|
||||||
this._element.removeAttribute('aria-hidden')
|
|
||||||
this._element.scrollTop = 0
|
|
||||||
|
|
||||||
if (transition) {
|
|
||||||
Util.reflow(this._element)
|
|
||||||
}
|
|
||||||
|
|
||||||
$(this._element).addClass(ClassName.SHOW)
|
|
||||||
|
|
||||||
if (this._config.focus) {
|
|
||||||
this._enforceFocus()
|
|
||||||
}
|
|
||||||
|
|
||||||
const shownEvent = $.Event(Event.SHOWN, {
|
|
||||||
relatedTarget
|
|
||||||
})
|
|
||||||
|
|
||||||
const transitionComplete = () => {
|
|
||||||
if (this._config.focus) {
|
|
||||||
this._element.focus()
|
|
||||||
}
|
|
||||||
this._isTransitioning = false
|
|
||||||
$(this._element).trigger(shownEvent)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (transition) {
|
|
||||||
$(this._dialog)
|
|
||||||
.one(Util.TRANSITION_END, transitionComplete)
|
|
||||||
.emulateTransitionEnd(TRANSITION_DURATION)
|
|
||||||
} else {
|
|
||||||
transitionComplete()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_enforceFocus() {
|
|
||||||
$(document)
|
|
||||||
.off(Event.FOCUSIN) // Guard against infinite focus loop
|
|
||||||
.on(Event.FOCUSIN, (event) => {
|
|
||||||
if (document !== event.target &&
|
|
||||||
this._element !== event.target &&
|
|
||||||
$(this._element).has(event.target).length === 0) {
|
|
||||||
this._element.focus()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
_setEscapeEvent() {
|
|
||||||
if (this._isShown && this._config.keyboard) {
|
|
||||||
$(this._element).on(Event.KEYDOWN_DISMISS, (event) => {
|
|
||||||
if (event.which === ESCAPE_KEYCODE) {
|
|
||||||
event.preventDefault()
|
|
||||||
this.hide()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else if (!this._isShown) {
|
|
||||||
$(this._element).off(Event.KEYDOWN_DISMISS)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_setResizeEvent() {
|
|
||||||
if (this._isShown) {
|
|
||||||
$(window).on(Event.RESIZE, (event) => this.handleUpdate(event))
|
|
||||||
} else {
|
|
||||||
$(window).off(Event.RESIZE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_hideModal() {
|
|
||||||
this._element.style.display = 'none'
|
|
||||||
this._element.setAttribute('aria-hidden', true)
|
|
||||||
this._isTransitioning = false
|
|
||||||
this._showBackdrop(() => {
|
|
||||||
$(document.body).removeClass(ClassName.OPEN)
|
|
||||||
this._resetAdjustments()
|
|
||||||
this._resetScrollbar()
|
|
||||||
$(this._element).trigger(Event.HIDDEN)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
_removeBackdrop() {
|
|
||||||
if (this._backdrop) {
|
|
||||||
$(this._backdrop).remove()
|
|
||||||
this._backdrop = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_showBackdrop(callback) {
|
|
||||||
const animate = $(this._element).hasClass(ClassName.FADE)
|
|
||||||
? ClassName.FADE : ''
|
|
||||||
|
|
||||||
if (this._isShown && this._config.backdrop) {
|
|
||||||
const doAnimate = Util.supportsTransitionEnd() && animate
|
|
||||||
|
|
||||||
this._backdrop = document.createElement('div')
|
|
||||||
this._backdrop.className = ClassName.BACKDROP
|
|
||||||
|
|
||||||
if (animate) {
|
|
||||||
$(this._backdrop).addClass(animate)
|
|
||||||
}
|
|
||||||
|
|
||||||
$(this._backdrop).appendTo(document.body)
|
|
||||||
|
|
||||||
$(this._element).on(Event.CLICK_DISMISS, (event) => {
|
|
||||||
if (this._ignoreBackdropClick) {
|
|
||||||
this._ignoreBackdropClick = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (event.target !== event.currentTarget) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (this._config.backdrop === 'static') {
|
|
||||||
this._element.focus()
|
|
||||||
} else {
|
|
||||||
this.hide()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (doAnimate) {
|
|
||||||
Util.reflow(this._backdrop)
|
|
||||||
}
|
|
||||||
|
|
||||||
$(this._backdrop).addClass(ClassName.SHOW)
|
|
||||||
|
|
||||||
if (!callback) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!doAnimate) {
|
|
||||||
callback()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
$(this._backdrop)
|
|
||||||
.one(Util.TRANSITION_END, callback)
|
|
||||||
.emulateTransitionEnd(BACKDROP_TRANSITION_DURATION)
|
|
||||||
} else if (!this._isShown && this._backdrop) {
|
|
||||||
$(this._backdrop).removeClass(ClassName.SHOW)
|
|
||||||
|
|
||||||
const callbackRemove = () => {
|
|
||||||
this._removeBackdrop()
|
|
||||||
if (callback) {
|
|
||||||
callback()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Util.supportsTransitionEnd() &&
|
|
||||||
$(this._element).hasClass(ClassName.FADE)) {
|
|
||||||
$(this._backdrop)
|
|
||||||
.one(Util.TRANSITION_END, callbackRemove)
|
|
||||||
.emulateTransitionEnd(BACKDROP_TRANSITION_DURATION)
|
|
||||||
} else {
|
|
||||||
callbackRemove()
|
|
||||||
}
|
|
||||||
} else if (callback) {
|
|
||||||
callback()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// the following methods are used to handle overflowing modals
|
|
||||||
// todo (fat): these should probably be refactored out of modal.js
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
_adjustDialog() {
|
|
||||||
const isModalOverflowing =
|
|
||||||
this._element.scrollHeight > document.documentElement.clientHeight
|
|
||||||
|
|
||||||
if (!this._isBodyOverflowing && isModalOverflowing) {
|
|
||||||
this._element.style.paddingLeft = `${this._scrollbarWidth}px`
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._isBodyOverflowing && !isModalOverflowing) {
|
|
||||||
this._element.style.paddingRight = `${this._scrollbarWidth}px`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_resetAdjustments() {
|
|
||||||
this._element.style.paddingLeft = ''
|
|
||||||
this._element.style.paddingRight = ''
|
|
||||||
}
|
|
||||||
|
|
||||||
_checkScrollbar() {
|
|
||||||
const rect = document.body.getBoundingClientRect()
|
|
||||||
this._isBodyOverflowing = rect.left + rect.right < window.innerWidth
|
|
||||||
this._scrollbarWidth = this._getScrollbarWidth()
|
|
||||||
}
|
|
||||||
|
|
||||||
_setScrollbar() {
|
|
||||||
if (this._isBodyOverflowing) {
|
|
||||||
// Note: DOMNode.style.paddingRight returns the actual value or '' if not set
|
|
||||||
// while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set
|
|
||||||
|
|
||||||
// Adjust fixed content padding
|
|
||||||
$(Selector.FIXED_CONTENT).each((index, element) => {
|
|
||||||
const actualPadding = $(element)[0].style.paddingRight
|
|
||||||
const calculatedPadding = $(element).css('padding-right')
|
|
||||||
$(element).data('padding-right', actualPadding).css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Adjust sticky content margin
|
|
||||||
$(Selector.STICKY_CONTENT).each((index, element) => {
|
|
||||||
const actualMargin = $(element)[0].style.marginRight
|
|
||||||
const calculatedMargin = $(element).css('margin-right')
|
|
||||||
$(element).data('margin-right', actualMargin).css('margin-right', `${parseFloat(calculatedMargin) - this._scrollbarWidth}px`)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Adjust navbar-toggler margin
|
|
||||||
$(Selector.NAVBAR_TOGGLER).each((index, element) => {
|
|
||||||
const actualMargin = $(element)[0].style.marginRight
|
|
||||||
const calculatedMargin = $(element).css('margin-right')
|
|
||||||
$(element).data('margin-right', actualMargin).css('margin-right', `${parseFloat(calculatedMargin) + this._scrollbarWidth}px`)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Adjust body padding
|
|
||||||
const actualPadding = document.body.style.paddingRight
|
|
||||||
const calculatedPadding = $('body').css('padding-right')
|
|
||||||
$('body').data('padding-right', actualPadding).css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_resetScrollbar() {
|
|
||||||
// Restore fixed content padding
|
|
||||||
$(Selector.FIXED_CONTENT).each((index, element) => {
|
|
||||||
const padding = $(element).data('padding-right')
|
|
||||||
if (typeof padding !== 'undefined') {
|
|
||||||
$(element).css('padding-right', padding).removeData('padding-right')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Restore sticky content and navbar-toggler margin
|
|
||||||
$(`${Selector.STICKY_CONTENT}, ${Selector.NAVBAR_TOGGLER}`).each((index, element) => {
|
|
||||||
const margin = $(element).data('margin-right')
|
|
||||||
if (typeof margin !== 'undefined') {
|
|
||||||
$(element).css('margin-right', margin).removeData('margin-right')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Restore body padding
|
|
||||||
const padding = $('body').data('padding-right')
|
|
||||||
if (typeof padding !== 'undefined') {
|
|
||||||
$('body').css('padding-right', padding).removeData('padding-right')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_getScrollbarWidth() { // thx d.walsh
|
|
||||||
const scrollDiv = document.createElement('div')
|
|
||||||
scrollDiv.className = ClassName.SCROLLBAR_MEASURER
|
|
||||||
document.body.appendChild(scrollDiv)
|
|
||||||
const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth
|
|
||||||
document.body.removeChild(scrollDiv)
|
|
||||||
return scrollbarWidth
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static
|
|
||||||
|
|
||||||
static _jQueryInterface(config, relatedTarget) {
|
|
||||||
return this.each(function () {
|
|
||||||
let data = $(this).data(DATA_KEY)
|
|
||||||
const _config = {
|
|
||||||
...Modal.Default,
|
|
||||||
...$(this).data(),
|
|
||||||
...typeof config === 'object' && config
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!data) {
|
|
||||||
data = new Modal(this, _config)
|
|
||||||
$(this).data(DATA_KEY, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof config === 'string') {
|
|
||||||
if (typeof data[config] === 'undefined') {
|
|
||||||
throw new TypeError(`No method named "${config}"`)
|
|
||||||
}
|
|
||||||
data[config](relatedTarget)
|
|
||||||
} else if (_config.show) {
|
|
||||||
data.show(relatedTarget)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Data Api implementation
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
$(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
|
|
||||||
let target
|
|
||||||
const selector = Util.getSelectorFromElement(this)
|
|
||||||
|
|
||||||
if (selector) {
|
|
||||||
target = $(selector)[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
const config = $(target).data(DATA_KEY)
|
|
||||||
? 'toggle' : {
|
|
||||||
...$(target).data(),
|
|
||||||
...$(this).data()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.tagName === 'A' || this.tagName === 'AREA') {
|
|
||||||
event.preventDefault()
|
|
||||||
}
|
|
||||||
|
|
||||||
const $target = $(target).one(Event.SHOW, (showEvent) => {
|
|
||||||
if (showEvent.isDefaultPrevented()) {
|
|
||||||
// Only register focus restorer if modal will actually get shown
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
$target.one(Event.HIDDEN, () => {
|
|
||||||
if ($(this).is(':visible')) {
|
|
||||||
this.focus()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
Modal._jQueryInterface.call($(target), config, this)
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* jQuery
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
$.fn[NAME] = Modal._jQueryInterface
|
|
||||||
$.fn[NAME].Constructor = Modal
|
|
||||||
$.fn[NAME].noConflict = function () {
|
|
||||||
$.fn[NAME] = JQUERY_NO_CONFLICT
|
|
||||||
return Modal._jQueryInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
return Modal
|
|
||||||
})($)
|
|
||||||
|
|
||||||
export default Modal
|
|
|
@ -1,188 +0,0 @@
|
||||||
import $ from 'jquery'
|
|
||||||
import Tooltip from './tooltip'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Bootstrap (v4.0.0): popover.js
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const Popover = (($) => {
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Constants
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const NAME = 'popover'
|
|
||||||
const VERSION = '4.0.0'
|
|
||||||
const DATA_KEY = 'bs.popover'
|
|
||||||
const EVENT_KEY = `.${DATA_KEY}`
|
|
||||||
const JQUERY_NO_CONFLICT = $.fn[NAME]
|
|
||||||
const CLASS_PREFIX = 'bs-popover'
|
|
||||||
const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g')
|
|
||||||
|
|
||||||
const Default = {
|
|
||||||
...Tooltip.Default,
|
|
||||||
placement : 'right',
|
|
||||||
trigger : 'click',
|
|
||||||
content : '',
|
|
||||||
template : '<div class="popover" role="tooltip">' +
|
|
||||||
'<div class="arrow"></div>' +
|
|
||||||
'<h3 class="popover-header"></h3>' +
|
|
||||||
'<div class="popover-body"></div></div>'
|
|
||||||
}
|
|
||||||
|
|
||||||
const DefaultType = {
|
|
||||||
...Tooltip.DefaultType,
|
|
||||||
content : '(string|element|function)'
|
|
||||||
}
|
|
||||||
|
|
||||||
const ClassName = {
|
|
||||||
FADE : 'fade',
|
|
||||||
SHOW : 'show'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Selector = {
|
|
||||||
TITLE : '.popover-header',
|
|
||||||
CONTENT : '.popover-body'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Event = {
|
|
||||||
HIDE : `hide${EVENT_KEY}`,
|
|
||||||
HIDDEN : `hidden${EVENT_KEY}`,
|
|
||||||
SHOW : `show${EVENT_KEY}`,
|
|
||||||
SHOWN : `shown${EVENT_KEY}`,
|
|
||||||
INSERTED : `inserted${EVENT_KEY}`,
|
|
||||||
CLICK : `click${EVENT_KEY}`,
|
|
||||||
FOCUSIN : `focusin${EVENT_KEY}`,
|
|
||||||
FOCUSOUT : `focusout${EVENT_KEY}`,
|
|
||||||
MOUSEENTER : `mouseenter${EVENT_KEY}`,
|
|
||||||
MOUSELEAVE : `mouseleave${EVENT_KEY}`
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Class Definition
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Popover extends Tooltip {
|
|
||||||
// Getters
|
|
||||||
|
|
||||||
static get VERSION() {
|
|
||||||
return VERSION
|
|
||||||
}
|
|
||||||
|
|
||||||
static get Default() {
|
|
||||||
return Default
|
|
||||||
}
|
|
||||||
|
|
||||||
static get NAME() {
|
|
||||||
return NAME
|
|
||||||
}
|
|
||||||
|
|
||||||
static get DATA_KEY() {
|
|
||||||
return DATA_KEY
|
|
||||||
}
|
|
||||||
|
|
||||||
static get Event() {
|
|
||||||
return Event
|
|
||||||
}
|
|
||||||
|
|
||||||
static get EVENT_KEY() {
|
|
||||||
return EVENT_KEY
|
|
||||||
}
|
|
||||||
|
|
||||||
static get DefaultType() {
|
|
||||||
return DefaultType
|
|
||||||
}
|
|
||||||
|
|
||||||
// Overrides
|
|
||||||
|
|
||||||
isWithContent() {
|
|
||||||
return this.getTitle() || this._getContent()
|
|
||||||
}
|
|
||||||
|
|
||||||
addAttachmentClass(attachment) {
|
|
||||||
$(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
getTipElement() {
|
|
||||||
this.tip = this.tip || $(this.config.template)[0]
|
|
||||||
return this.tip
|
|
||||||
}
|
|
||||||
|
|
||||||
setContent() {
|
|
||||||
const $tip = $(this.getTipElement())
|
|
||||||
|
|
||||||
// We use append for html objects to maintain js events
|
|
||||||
this.setElementContent($tip.find(Selector.TITLE), this.getTitle())
|
|
||||||
let content = this._getContent()
|
|
||||||
if (typeof content === 'function') {
|
|
||||||
content = content.call(this.element)
|
|
||||||
}
|
|
||||||
this.setElementContent($tip.find(Selector.CONTENT), content)
|
|
||||||
|
|
||||||
$tip.removeClass(`${ClassName.FADE} ${ClassName.SHOW}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private
|
|
||||||
|
|
||||||
_getContent() {
|
|
||||||
return this.element.getAttribute('data-content') ||
|
|
||||||
this.config.content
|
|
||||||
}
|
|
||||||
|
|
||||||
_cleanTipClass() {
|
|
||||||
const $tip = $(this.getTipElement())
|
|
||||||
const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)
|
|
||||||
if (tabClass !== null && tabClass.length > 0) {
|
|
||||||
$tip.removeClass(tabClass.join(''))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static
|
|
||||||
|
|
||||||
static _jQueryInterface(config) {
|
|
||||||
return this.each(function () {
|
|
||||||
let data = $(this).data(DATA_KEY)
|
|
||||||
const _config = typeof config === 'object' ? config : null
|
|
||||||
|
|
||||||
if (!data && /destroy|hide/.test(config)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!data) {
|
|
||||||
data = new Popover(this, _config)
|
|
||||||
$(this).data(DATA_KEY, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof config === 'string') {
|
|
||||||
if (typeof data[config] === 'undefined') {
|
|
||||||
throw new TypeError(`No method named "${config}"`)
|
|
||||||
}
|
|
||||||
data[config]()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* jQuery
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
$.fn[NAME] = Popover._jQueryInterface
|
|
||||||
$.fn[NAME].Constructor = Popover
|
|
||||||
$.fn[NAME].noConflict = function () {
|
|
||||||
$.fn[NAME] = JQUERY_NO_CONFLICT
|
|
||||||
return Popover._jQueryInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
return Popover
|
|
||||||
})($)
|
|
||||||
|
|
||||||
export default Popover
|
|
|
@ -1,329 +0,0 @@
|
||||||
import $ from 'jquery'
|
|
||||||
import Util from './util'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Bootstrap (v4.0.0): scrollspy.js
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const ScrollSpy = (($) => {
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Constants
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const NAME = 'scrollspy'
|
|
||||||
const VERSION = '4.0.0'
|
|
||||||
const DATA_KEY = 'bs.scrollspy'
|
|
||||||
const EVENT_KEY = `.${DATA_KEY}`
|
|
||||||
const DATA_API_KEY = '.data-api'
|
|
||||||
const JQUERY_NO_CONFLICT = $.fn[NAME]
|
|
||||||
|
|
||||||
const Default = {
|
|
||||||
offset : 10,
|
|
||||||
method : 'auto',
|
|
||||||
target : ''
|
|
||||||
}
|
|
||||||
|
|
||||||
const DefaultType = {
|
|
||||||
offset : 'number',
|
|
||||||
method : 'string',
|
|
||||||
target : '(string|element)'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Event = {
|
|
||||||
ACTIVATE : `activate${EVENT_KEY}`,
|
|
||||||
SCROLL : `scroll${EVENT_KEY}`,
|
|
||||||
LOAD_DATA_API : `load${EVENT_KEY}${DATA_API_KEY}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const ClassName = {
|
|
||||||
DROPDOWN_ITEM : 'dropdown-item',
|
|
||||||
DROPDOWN_MENU : 'dropdown-menu',
|
|
||||||
ACTIVE : 'active'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Selector = {
|
|
||||||
DATA_SPY : '[data-spy="scroll"]',
|
|
||||||
ACTIVE : '.active',
|
|
||||||
NAV_LIST_GROUP : '.nav, .list-group',
|
|
||||||
NAV_LINKS : '.nav-link',
|
|
||||||
NAV_ITEMS : '.nav-item',
|
|
||||||
LIST_ITEMS : '.list-group-item',
|
|
||||||
DROPDOWN : '.dropdown',
|
|
||||||
DROPDOWN_ITEMS : '.dropdown-item',
|
|
||||||
DROPDOWN_TOGGLE : '.dropdown-toggle'
|
|
||||||
}
|
|
||||||
|
|
||||||
const OffsetMethod = {
|
|
||||||
OFFSET : 'offset',
|
|
||||||
POSITION : 'position'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Class Definition
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
class ScrollSpy {
|
|
||||||
constructor(element, config) {
|
|
||||||
this._element = element
|
|
||||||
this._scrollElement = element.tagName === 'BODY' ? window : element
|
|
||||||
this._config = this._getConfig(config)
|
|
||||||
this._selector = `${this._config.target} ${Selector.NAV_LINKS},` +
|
|
||||||
`${this._config.target} ${Selector.LIST_ITEMS},` +
|
|
||||||
`${this._config.target} ${Selector.DROPDOWN_ITEMS}`
|
|
||||||
this._offsets = []
|
|
||||||
this._targets = []
|
|
||||||
this._activeTarget = null
|
|
||||||
this._scrollHeight = 0
|
|
||||||
|
|
||||||
$(this._scrollElement).on(Event.SCROLL, (event) => this._process(event))
|
|
||||||
|
|
||||||
this.refresh()
|
|
||||||
this._process()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getters
|
|
||||||
|
|
||||||
static get VERSION() {
|
|
||||||
return VERSION
|
|
||||||
}
|
|
||||||
|
|
||||||
static get Default() {
|
|
||||||
return Default
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public
|
|
||||||
|
|
||||||
refresh() {
|
|
||||||
const autoMethod = this._scrollElement === this._scrollElement.window
|
|
||||||
? OffsetMethod.OFFSET : OffsetMethod.POSITION
|
|
||||||
|
|
||||||
const offsetMethod = this._config.method === 'auto'
|
|
||||||
? autoMethod : this._config.method
|
|
||||||
|
|
||||||
const offsetBase = offsetMethod === OffsetMethod.POSITION
|
|
||||||
? this._getScrollTop() : 0
|
|
||||||
|
|
||||||
this._offsets = []
|
|
||||||
this._targets = []
|
|
||||||
|
|
||||||
this._scrollHeight = this._getScrollHeight()
|
|
||||||
|
|
||||||
const targets = $.makeArray($(this._selector))
|
|
||||||
|
|
||||||
targets
|
|
||||||
.map((element) => {
|
|
||||||
let target
|
|
||||||
const targetSelector = Util.getSelectorFromElement(element)
|
|
||||||
|
|
||||||
if (targetSelector) {
|
|
||||||
target = $(targetSelector)[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target) {
|
|
||||||
const targetBCR = target.getBoundingClientRect()
|
|
||||||
if (targetBCR.width || targetBCR.height) {
|
|
||||||
// TODO (fat): remove sketch reliance on jQuery position/offset
|
|
||||||
return [
|
|
||||||
$(target)[offsetMethod]().top + offsetBase,
|
|
||||||
targetSelector
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
})
|
|
||||||
.filter((item) => item)
|
|
||||||
.sort((a, b) => a[0] - b[0])
|
|
||||||
.forEach((item) => {
|
|
||||||
this._offsets.push(item[0])
|
|
||||||
this._targets.push(item[1])
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
dispose() {
|
|
||||||
$.removeData(this._element, DATA_KEY)
|
|
||||||
$(this._scrollElement).off(EVENT_KEY)
|
|
||||||
|
|
||||||
this._element = null
|
|
||||||
this._scrollElement = null
|
|
||||||
this._config = null
|
|
||||||
this._selector = null
|
|
||||||
this._offsets = null
|
|
||||||
this._targets = null
|
|
||||||
this._activeTarget = null
|
|
||||||
this._scrollHeight = null
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private
|
|
||||||
|
|
||||||
_getConfig(config) {
|
|
||||||
config = {
|
|
||||||
...Default,
|
|
||||||
...config
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof config.target !== 'string') {
|
|
||||||
let id = $(config.target).attr('id')
|
|
||||||
if (!id) {
|
|
||||||
id = Util.getUID(NAME)
|
|
||||||
$(config.target).attr('id', id)
|
|
||||||
}
|
|
||||||
config.target = `#${id}`
|
|
||||||
}
|
|
||||||
|
|
||||||
Util.typeCheckConfig(NAME, config, DefaultType)
|
|
||||||
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
|
|
||||||
_getScrollTop() {
|
|
||||||
return this._scrollElement === window
|
|
||||||
? this._scrollElement.pageYOffset : this._scrollElement.scrollTop
|
|
||||||
}
|
|
||||||
|
|
||||||
_getScrollHeight() {
|
|
||||||
return this._scrollElement.scrollHeight || Math.max(
|
|
||||||
document.body.scrollHeight,
|
|
||||||
document.documentElement.scrollHeight
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
_getOffsetHeight() {
|
|
||||||
return this._scrollElement === window
|
|
||||||
? window.innerHeight : this._scrollElement.getBoundingClientRect().height
|
|
||||||
}
|
|
||||||
|
|
||||||
_process() {
|
|
||||||
const scrollTop = this._getScrollTop() + this._config.offset
|
|
||||||
const scrollHeight = this._getScrollHeight()
|
|
||||||
const maxScroll = this._config.offset +
|
|
||||||
scrollHeight -
|
|
||||||
this._getOffsetHeight()
|
|
||||||
|
|
||||||
if (this._scrollHeight !== scrollHeight) {
|
|
||||||
this.refresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scrollTop >= maxScroll) {
|
|
||||||
const target = this._targets[this._targets.length - 1]
|
|
||||||
|
|
||||||
if (this._activeTarget !== target) {
|
|
||||||
this._activate(target)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {
|
|
||||||
this._activeTarget = null
|
|
||||||
this._clear()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = this._offsets.length; i--;) {
|
|
||||||
const isActiveTarget = this._activeTarget !== this._targets[i] &&
|
|
||||||
scrollTop >= this._offsets[i] &&
|
|
||||||
(typeof this._offsets[i + 1] === 'undefined' ||
|
|
||||||
scrollTop < this._offsets[i + 1])
|
|
||||||
|
|
||||||
if (isActiveTarget) {
|
|
||||||
this._activate(this._targets[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_activate(target) {
|
|
||||||
this._activeTarget = target
|
|
||||||
|
|
||||||
this._clear()
|
|
||||||
|
|
||||||
let queries = this._selector.split(',')
|
|
||||||
// eslint-disable-next-line arrow-body-style
|
|
||||||
queries = queries.map((selector) => {
|
|
||||||
return `${selector}[data-target="${target}"],` +
|
|
||||||
`${selector}[href="${target}"]`
|
|
||||||
})
|
|
||||||
|
|
||||||
const $link = $(queries.join(','))
|
|
||||||
|
|
||||||
if ($link.hasClass(ClassName.DROPDOWN_ITEM)) {
|
|
||||||
$link.closest(Selector.DROPDOWN).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE)
|
|
||||||
$link.addClass(ClassName.ACTIVE)
|
|
||||||
} else {
|
|
||||||
// Set triggered link as active
|
|
||||||
$link.addClass(ClassName.ACTIVE)
|
|
||||||
// Set triggered links parents as active
|
|
||||||
// With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
|
|
||||||
$link.parents(Selector.NAV_LIST_GROUP).prev(`${Selector.NAV_LINKS}, ${Selector.LIST_ITEMS}`).addClass(ClassName.ACTIVE)
|
|
||||||
// Handle special case when .nav-link is inside .nav-item
|
|
||||||
$link.parents(Selector.NAV_LIST_GROUP).prev(Selector.NAV_ITEMS).children(Selector.NAV_LINKS).addClass(ClassName.ACTIVE)
|
|
||||||
}
|
|
||||||
|
|
||||||
$(this._scrollElement).trigger(Event.ACTIVATE, {
|
|
||||||
relatedTarget: target
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
_clear() {
|
|
||||||
$(this._selector).filter(Selector.ACTIVE).removeClass(ClassName.ACTIVE)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static
|
|
||||||
|
|
||||||
static _jQueryInterface(config) {
|
|
||||||
return this.each(function () {
|
|
||||||
let data = $(this).data(DATA_KEY)
|
|
||||||
const _config = typeof config === 'object' && config
|
|
||||||
|
|
||||||
if (!data) {
|
|
||||||
data = new ScrollSpy(this, _config)
|
|
||||||
$(this).data(DATA_KEY, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof config === 'string') {
|
|
||||||
if (typeof data[config] === 'undefined') {
|
|
||||||
throw new TypeError(`No method named "${config}"`)
|
|
||||||
}
|
|
||||||
data[config]()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Data Api implementation
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
$(window).on(Event.LOAD_DATA_API, () => {
|
|
||||||
const scrollSpys = $.makeArray($(Selector.DATA_SPY))
|
|
||||||
|
|
||||||
for (let i = scrollSpys.length; i--;) {
|
|
||||||
const $spy = $(scrollSpys[i])
|
|
||||||
ScrollSpy._jQueryInterface.call($spy, $spy.data())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* jQuery
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
$.fn[NAME] = ScrollSpy._jQueryInterface
|
|
||||||
$.fn[NAME].Constructor = ScrollSpy
|
|
||||||
$.fn[NAME].noConflict = function () {
|
|
||||||
$.fn[NAME] = JQUERY_NO_CONFLICT
|
|
||||||
return ScrollSpy._jQueryInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
return ScrollSpy
|
|
||||||
})($)
|
|
||||||
|
|
||||||
export default ScrollSpy
|
|
|
@ -1,263 +0,0 @@
|
||||||
import $ from 'jquery'
|
|
||||||
import Util from './util'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Bootstrap (v4.0.0): tab.js
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const Tab = (($) => {
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Constants
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const NAME = 'tab'
|
|
||||||
const VERSION = '4.0.0'
|
|
||||||
const DATA_KEY = 'bs.tab'
|
|
||||||
const EVENT_KEY = `.${DATA_KEY}`
|
|
||||||
const DATA_API_KEY = '.data-api'
|
|
||||||
const JQUERY_NO_CONFLICT = $.fn[NAME]
|
|
||||||
const TRANSITION_DURATION = 150
|
|
||||||
|
|
||||||
const Event = {
|
|
||||||
HIDE : `hide${EVENT_KEY}`,
|
|
||||||
HIDDEN : `hidden${EVENT_KEY}`,
|
|
||||||
SHOW : `show${EVENT_KEY}`,
|
|
||||||
SHOWN : `shown${EVENT_KEY}`,
|
|
||||||
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const ClassName = {
|
|
||||||
DROPDOWN_MENU : 'dropdown-menu',
|
|
||||||
ACTIVE : 'active',
|
|
||||||
DISABLED : 'disabled',
|
|
||||||
FADE : 'fade',
|
|
||||||
SHOW : 'show'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Selector = {
|
|
||||||
DROPDOWN : '.dropdown',
|
|
||||||
NAV_LIST_GROUP : '.nav, .list-group',
|
|
||||||
ACTIVE : '.active',
|
|
||||||
ACTIVE_UL : '> li > .active',
|
|
||||||
DATA_TOGGLE : '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',
|
|
||||||
DROPDOWN_TOGGLE : '.dropdown-toggle',
|
|
||||||
DROPDOWN_ACTIVE_CHILD : '> .dropdown-menu .active'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Class Definition
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Tab {
|
|
||||||
constructor(element) {
|
|
||||||
this._element = element
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getters
|
|
||||||
|
|
||||||
static get VERSION() {
|
|
||||||
return VERSION
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public
|
|
||||||
|
|
||||||
show() {
|
|
||||||
if (this._element.parentNode &&
|
|
||||||
this._element.parentNode.nodeType === Node.ELEMENT_NODE &&
|
|
||||||
$(this._element).hasClass(ClassName.ACTIVE) ||
|
|
||||||
$(this._element).hasClass(ClassName.DISABLED)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let target
|
|
||||||
let previous
|
|
||||||
const listElement = $(this._element).closest(Selector.NAV_LIST_GROUP)[0]
|
|
||||||
const selector = Util.getSelectorFromElement(this._element)
|
|
||||||
|
|
||||||
if (listElement) {
|
|
||||||
const itemSelector = listElement.nodeName === 'UL' ? Selector.ACTIVE_UL : Selector.ACTIVE
|
|
||||||
previous = $.makeArray($(listElement).find(itemSelector))
|
|
||||||
previous = previous[previous.length - 1]
|
|
||||||
}
|
|
||||||
|
|
||||||
const hideEvent = $.Event(Event.HIDE, {
|
|
||||||
relatedTarget: this._element
|
|
||||||
})
|
|
||||||
|
|
||||||
const showEvent = $.Event(Event.SHOW, {
|
|
||||||
relatedTarget: previous
|
|
||||||
})
|
|
||||||
|
|
||||||
if (previous) {
|
|
||||||
$(previous).trigger(hideEvent)
|
|
||||||
}
|
|
||||||
|
|
||||||
$(this._element).trigger(showEvent)
|
|
||||||
|
|
||||||
if (showEvent.isDefaultPrevented() ||
|
|
||||||
hideEvent.isDefaultPrevented()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selector) {
|
|
||||||
target = $(selector)[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
this._activate(
|
|
||||||
this._element,
|
|
||||||
listElement
|
|
||||||
)
|
|
||||||
|
|
||||||
const complete = () => {
|
|
||||||
const hiddenEvent = $.Event(Event.HIDDEN, {
|
|
||||||
relatedTarget: this._element
|
|
||||||
})
|
|
||||||
|
|
||||||
const shownEvent = $.Event(Event.SHOWN, {
|
|
||||||
relatedTarget: previous
|
|
||||||
})
|
|
||||||
|
|
||||||
$(previous).trigger(hiddenEvent)
|
|
||||||
$(this._element).trigger(shownEvent)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target) {
|
|
||||||
this._activate(target, target.parentNode, complete)
|
|
||||||
} else {
|
|
||||||
complete()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dispose() {
|
|
||||||
$.removeData(this._element, DATA_KEY)
|
|
||||||
this._element = null
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private
|
|
||||||
|
|
||||||
_activate(element, container, callback) {
|
|
||||||
let activeElements
|
|
||||||
if (container.nodeName === 'UL') {
|
|
||||||
activeElements = $(container).find(Selector.ACTIVE_UL)
|
|
||||||
} else {
|
|
||||||
activeElements = $(container).children(Selector.ACTIVE)
|
|
||||||
}
|
|
||||||
|
|
||||||
const active = activeElements[0]
|
|
||||||
const isTransitioning = callback &&
|
|
||||||
Util.supportsTransitionEnd() &&
|
|
||||||
(active && $(active).hasClass(ClassName.FADE))
|
|
||||||
|
|
||||||
const complete = () => this._transitionComplete(
|
|
||||||
element,
|
|
||||||
active,
|
|
||||||
callback
|
|
||||||
)
|
|
||||||
|
|
||||||
if (active && isTransitioning) {
|
|
||||||
$(active)
|
|
||||||
.one(Util.TRANSITION_END, complete)
|
|
||||||
.emulateTransitionEnd(TRANSITION_DURATION)
|
|
||||||
} else {
|
|
||||||
complete()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_transitionComplete(element, active, callback) {
|
|
||||||
if (active) {
|
|
||||||
$(active).removeClass(`${ClassName.SHOW} ${ClassName.ACTIVE}`)
|
|
||||||
|
|
||||||
const dropdownChild = $(active.parentNode).find(
|
|
||||||
Selector.DROPDOWN_ACTIVE_CHILD
|
|
||||||
)[0]
|
|
||||||
|
|
||||||
if (dropdownChild) {
|
|
||||||
$(dropdownChild).removeClass(ClassName.ACTIVE)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (active.getAttribute('role') === 'tab') {
|
|
||||||
active.setAttribute('aria-selected', false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$(element).addClass(ClassName.ACTIVE)
|
|
||||||
if (element.getAttribute('role') === 'tab') {
|
|
||||||
element.setAttribute('aria-selected', true)
|
|
||||||
}
|
|
||||||
|
|
||||||
Util.reflow(element)
|
|
||||||
$(element).addClass(ClassName.SHOW)
|
|
||||||
|
|
||||||
if (element.parentNode &&
|
|
||||||
$(element.parentNode).hasClass(ClassName.DROPDOWN_MENU)) {
|
|
||||||
const dropdownElement = $(element).closest(Selector.DROPDOWN)[0]
|
|
||||||
if (dropdownElement) {
|
|
||||||
$(dropdownElement).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE)
|
|
||||||
}
|
|
||||||
|
|
||||||
element.setAttribute('aria-expanded', true)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (callback) {
|
|
||||||
callback()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static
|
|
||||||
|
|
||||||
static _jQueryInterface(config) {
|
|
||||||
return this.each(function () {
|
|
||||||
const $this = $(this)
|
|
||||||
let data = $this.data(DATA_KEY)
|
|
||||||
|
|
||||||
if (!data) {
|
|
||||||
data = new Tab(this)
|
|
||||||
$this.data(DATA_KEY, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof config === 'string') {
|
|
||||||
if (typeof data[config] === 'undefined') {
|
|
||||||
throw new TypeError(`No method named "${config}"`)
|
|
||||||
}
|
|
||||||
data[config]()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Data Api implementation
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
$(document)
|
|
||||||
.on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
|
|
||||||
event.preventDefault()
|
|
||||||
Tab._jQueryInterface.call($(this), 'show')
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* jQuery
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
$.fn[NAME] = Tab._jQueryInterface
|
|
||||||
$.fn[NAME].Constructor = Tab
|
|
||||||
$.fn[NAME].noConflict = function () {
|
|
||||||
$.fn[NAME] = JQUERY_NO_CONFLICT
|
|
||||||
return Tab._jQueryInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
return Tab
|
|
||||||
})($)
|
|
||||||
|
|
||||||
export default Tab
|
|
|
@ -1,721 +0,0 @@
|
||||||
import $ from 'jquery'
|
|
||||||
import Popper from 'popper.js'
|
|
||||||
import Util from './util'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Bootstrap (v4.0.0): tooltip.js
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const Tooltip = (($) => {
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Constants
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const NAME = 'tooltip'
|
|
||||||
const VERSION = '4.0.0'
|
|
||||||
const DATA_KEY = 'bs.tooltip'
|
|
||||||
const EVENT_KEY = `.${DATA_KEY}`
|
|
||||||
const JQUERY_NO_CONFLICT = $.fn[NAME]
|
|
||||||
const TRANSITION_DURATION = 150
|
|
||||||
const CLASS_PREFIX = 'bs-tooltip'
|
|
||||||
const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g')
|
|
||||||
|
|
||||||
const DefaultType = {
|
|
||||||
animation : 'boolean',
|
|
||||||
template : 'string',
|
|
||||||
title : '(string|element|function)',
|
|
||||||
trigger : 'string',
|
|
||||||
delay : '(number|object)',
|
|
||||||
html : 'boolean',
|
|
||||||
selector : '(string|boolean)',
|
|
||||||
placement : '(string|function)',
|
|
||||||
offset : '(number|string)',
|
|
||||||
container : '(string|element|boolean)',
|
|
||||||
fallbackPlacement : '(string|array)',
|
|
||||||
boundary : '(string|element)'
|
|
||||||
}
|
|
||||||
|
|
||||||
const AttachmentMap = {
|
|
||||||
AUTO : 'auto',
|
|
||||||
TOP : 'top',
|
|
||||||
RIGHT : 'right',
|
|
||||||
BOTTOM : 'bottom',
|
|
||||||
LEFT : 'left'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Default = {
|
|
||||||
animation : true,
|
|
||||||
template : '<div class="tooltip" role="tooltip">' +
|
|
||||||
'<div class="arrow"></div>' +
|
|
||||||
'<div class="tooltip-inner"></div></div>',
|
|
||||||
trigger : 'hover focus',
|
|
||||||
title : '',
|
|
||||||
delay : 0,
|
|
||||||
html : false,
|
|
||||||
selector : false,
|
|
||||||
placement : 'top',
|
|
||||||
offset : 0,
|
|
||||||
container : false,
|
|
||||||
fallbackPlacement : 'flip',
|
|
||||||
boundary : 'scrollParent'
|
|
||||||
}
|
|
||||||
|
|
||||||
const HoverState = {
|
|
||||||
SHOW : 'show',
|
|
||||||
OUT : 'out'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Event = {
|
|
||||||
HIDE : `hide${EVENT_KEY}`,
|
|
||||||
HIDDEN : `hidden${EVENT_KEY}`,
|
|
||||||
SHOW : `show${EVENT_KEY}`,
|
|
||||||
SHOWN : `shown${EVENT_KEY}`,
|
|
||||||
INSERTED : `inserted${EVENT_KEY}`,
|
|
||||||
CLICK : `click${EVENT_KEY}`,
|
|
||||||
FOCUSIN : `focusin${EVENT_KEY}`,
|
|
||||||
FOCUSOUT : `focusout${EVENT_KEY}`,
|
|
||||||
MOUSEENTER : `mouseenter${EVENT_KEY}`,
|
|
||||||
MOUSELEAVE : `mouseleave${EVENT_KEY}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const ClassName = {
|
|
||||||
FADE : 'fade',
|
|
||||||
SHOW : 'show'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Selector = {
|
|
||||||
TOOLTIP : '.tooltip',
|
|
||||||
TOOLTIP_INNER : '.tooltip-inner',
|
|
||||||
ARROW : '.arrow'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Trigger = {
|
|
||||||
HOVER : 'hover',
|
|
||||||
FOCUS : 'focus',
|
|
||||||
CLICK : 'click',
|
|
||||||
MANUAL : 'manual'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Class Definition
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Tooltip {
|
|
||||||
constructor(element, config) {
|
|
||||||
/**
|
|
||||||
* Check for Popper dependency
|
|
||||||
* Popper - https://popper.js.org
|
|
||||||
*/
|
|
||||||
if (typeof Popper === 'undefined') {
|
|
||||||
throw new TypeError('Bootstrap tooltips require Popper.js (https://popper.js.org)')
|
|
||||||
}
|
|
||||||
|
|
||||||
// private
|
|
||||||
this._isEnabled = true
|
|
||||||
this._timeout = 0
|
|
||||||
this._hoverState = ''
|
|
||||||
this._activeTrigger = {}
|
|
||||||
this._popper = null
|
|
||||||
|
|
||||||
// Protected
|
|
||||||
this.element = element
|
|
||||||
this.config = this._getConfig(config)
|
|
||||||
this.tip = null
|
|
||||||
|
|
||||||
this._setListeners()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getters
|
|
||||||
|
|
||||||
static get VERSION() {
|
|
||||||
return VERSION
|
|
||||||
}
|
|
||||||
|
|
||||||
static get Default() {
|
|
||||||
return Default
|
|
||||||
}
|
|
||||||
|
|
||||||
static get NAME() {
|
|
||||||
return NAME
|
|
||||||
}
|
|
||||||
|
|
||||||
static get DATA_KEY() {
|
|
||||||
return DATA_KEY
|
|
||||||
}
|
|
||||||
|
|
||||||
static get Event() {
|
|
||||||
return Event
|
|
||||||
}
|
|
||||||
|
|
||||||
static get EVENT_KEY() {
|
|
||||||
return EVENT_KEY
|
|
||||||
}
|
|
||||||
|
|
||||||
static get DefaultType() {
|
|
||||||
return DefaultType
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public
|
|
||||||
|
|
||||||
enable() {
|
|
||||||
this._isEnabled = true
|
|
||||||
}
|
|
||||||
|
|
||||||
disable() {
|
|
||||||
this._isEnabled = false
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleEnabled() {
|
|
||||||
this._isEnabled = !this._isEnabled
|
|
||||||
}
|
|
||||||
|
|
||||||
toggle(event) {
|
|
||||||
if (!this._isEnabled) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event) {
|
|
||||||
const dataKey = this.constructor.DATA_KEY
|
|
||||||
let context = $(event.currentTarget).data(dataKey)
|
|
||||||
|
|
||||||
if (!context) {
|
|
||||||
context = new this.constructor(
|
|
||||||
event.currentTarget,
|
|
||||||
this._getDelegateConfig()
|
|
||||||
)
|
|
||||||
$(event.currentTarget).data(dataKey, context)
|
|
||||||
}
|
|
||||||
|
|
||||||
context._activeTrigger.click = !context._activeTrigger.click
|
|
||||||
|
|
||||||
if (context._isWithActiveTrigger()) {
|
|
||||||
context._enter(null, context)
|
|
||||||
} else {
|
|
||||||
context._leave(null, context)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ($(this.getTipElement()).hasClass(ClassName.SHOW)) {
|
|
||||||
this._leave(null, this)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this._enter(null, this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dispose() {
|
|
||||||
clearTimeout(this._timeout)
|
|
||||||
|
|
||||||
$.removeData(this.element, this.constructor.DATA_KEY)
|
|
||||||
|
|
||||||
$(this.element).off(this.constructor.EVENT_KEY)
|
|
||||||
$(this.element).closest('.modal').off('hide.bs.modal')
|
|
||||||
|
|
||||||
if (this.tip) {
|
|
||||||
$(this.tip).remove()
|
|
||||||
}
|
|
||||||
|
|
||||||
this._isEnabled = null
|
|
||||||
this._timeout = null
|
|
||||||
this._hoverState = null
|
|
||||||
this._activeTrigger = null
|
|
||||||
if (this._popper !== null) {
|
|
||||||
this._popper.destroy()
|
|
||||||
}
|
|
||||||
|
|
||||||
this._popper = null
|
|
||||||
this.element = null
|
|
||||||
this.config = null
|
|
||||||
this.tip = null
|
|
||||||
}
|
|
||||||
|
|
||||||
show() {
|
|
||||||
if ($(this.element).css('display') === 'none') {
|
|
||||||
throw new Error('Please use show on visible elements')
|
|
||||||
}
|
|
||||||
|
|
||||||
const showEvent = $.Event(this.constructor.Event.SHOW)
|
|
||||||
if (this.isWithContent() && this._isEnabled) {
|
|
||||||
$(this.element).trigger(showEvent)
|
|
||||||
|
|
||||||
const isInTheDom = $.contains(
|
|
||||||
this.element.ownerDocument.documentElement,
|
|
||||||
this.element
|
|
||||||
)
|
|
||||||
|
|
||||||
if (showEvent.isDefaultPrevented() || !isInTheDom) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const tip = this.getTipElement()
|
|
||||||
const tipId = Util.getUID(this.constructor.NAME)
|
|
||||||
|
|
||||||
tip.setAttribute('id', tipId)
|
|
||||||
this.element.setAttribute('aria-describedby', tipId)
|
|
||||||
|
|
||||||
this.setContent()
|
|
||||||
|
|
||||||
if (this.config.animation) {
|
|
||||||
$(tip).addClass(ClassName.FADE)
|
|
||||||
}
|
|
||||||
|
|
||||||
const placement = typeof this.config.placement === 'function'
|
|
||||||
? this.config.placement.call(this, tip, this.element)
|
|
||||||
: this.config.placement
|
|
||||||
|
|
||||||
const attachment = this._getAttachment(placement)
|
|
||||||
this.addAttachmentClass(attachment)
|
|
||||||
|
|
||||||
const container = this.config.container === false ? document.body : $(this.config.container)
|
|
||||||
|
|
||||||
$(tip).data(this.constructor.DATA_KEY, this)
|
|
||||||
|
|
||||||
if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {
|
|
||||||
$(tip).appendTo(container)
|
|
||||||
}
|
|
||||||
|
|
||||||
$(this.element).trigger(this.constructor.Event.INSERTED)
|
|
||||||
|
|
||||||
this._popper = new Popper(this.element, tip, {
|
|
||||||
placement: attachment,
|
|
||||||
modifiers: {
|
|
||||||
offset: {
|
|
||||||
offset: this.config.offset
|
|
||||||
},
|
|
||||||
flip: {
|
|
||||||
behavior: this.config.fallbackPlacement
|
|
||||||
},
|
|
||||||
arrow: {
|
|
||||||
element: Selector.ARROW
|
|
||||||
},
|
|
||||||
preventOverflow: {
|
|
||||||
boundariesElement: this.config.boundary
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onCreate: (data) => {
|
|
||||||
if (data.originalPlacement !== data.placement) {
|
|
||||||
this._handlePopperPlacementChange(data)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onUpdate: (data) => {
|
|
||||||
this._handlePopperPlacementChange(data)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
$(tip).addClass(ClassName.SHOW)
|
|
||||||
|
|
||||||
// If this is a touch-enabled device we add extra
|
|
||||||
// empty mouseover listeners to the body's immediate children;
|
|
||||||
// only needed because of broken event delegation on iOS
|
|
||||||
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
|
|
||||||
if ('ontouchstart' in document.documentElement) {
|
|
||||||
$('body').children().on('mouseover', null, $.noop)
|
|
||||||
}
|
|
||||||
|
|
||||||
const complete = () => {
|
|
||||||
if (this.config.animation) {
|
|
||||||
this._fixTransition()
|
|
||||||
}
|
|
||||||
const prevHoverState = this._hoverState
|
|
||||||
this._hoverState = null
|
|
||||||
|
|
||||||
$(this.element).trigger(this.constructor.Event.SHOWN)
|
|
||||||
|
|
||||||
if (prevHoverState === HoverState.OUT) {
|
|
||||||
this._leave(null, this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE)) {
|
|
||||||
$(this.tip)
|
|
||||||
.one(Util.TRANSITION_END, complete)
|
|
||||||
.emulateTransitionEnd(Tooltip._TRANSITION_DURATION)
|
|
||||||
} else {
|
|
||||||
complete()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hide(callback) {
|
|
||||||
const tip = this.getTipElement()
|
|
||||||
const hideEvent = $.Event(this.constructor.Event.HIDE)
|
|
||||||
const complete = () => {
|
|
||||||
if (this._hoverState !== HoverState.SHOW && tip.parentNode) {
|
|
||||||
tip.parentNode.removeChild(tip)
|
|
||||||
}
|
|
||||||
|
|
||||||
this._cleanTipClass()
|
|
||||||
this.element.removeAttribute('aria-describedby')
|
|
||||||
$(this.element).trigger(this.constructor.Event.HIDDEN)
|
|
||||||
if (this._popper !== null) {
|
|
||||||
this._popper.destroy()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (callback) {
|
|
||||||
callback()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$(this.element).trigger(hideEvent)
|
|
||||||
|
|
||||||
if (hideEvent.isDefaultPrevented()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
$(tip).removeClass(ClassName.SHOW)
|
|
||||||
|
|
||||||
// If this is a touch-enabled device we remove the extra
|
|
||||||
// empty mouseover listeners we added for iOS support
|
|
||||||
if ('ontouchstart' in document.documentElement) {
|
|
||||||
$('body').children().off('mouseover', null, $.noop)
|
|
||||||
}
|
|
||||||
|
|
||||||
this._activeTrigger[Trigger.CLICK] = false
|
|
||||||
this._activeTrigger[Trigger.FOCUS] = false
|
|
||||||
this._activeTrigger[Trigger.HOVER] = false
|
|
||||||
|
|
||||||
if (Util.supportsTransitionEnd() &&
|
|
||||||
$(this.tip).hasClass(ClassName.FADE)) {
|
|
||||||
$(tip)
|
|
||||||
.one(Util.TRANSITION_END, complete)
|
|
||||||
.emulateTransitionEnd(TRANSITION_DURATION)
|
|
||||||
} else {
|
|
||||||
complete()
|
|
||||||
}
|
|
||||||
|
|
||||||
this._hoverState = ''
|
|
||||||
}
|
|
||||||
|
|
||||||
update() {
|
|
||||||
if (this._popper !== null) {
|
|
||||||
this._popper.scheduleUpdate()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Protected
|
|
||||||
|
|
||||||
isWithContent() {
|
|
||||||
return Boolean(this.getTitle())
|
|
||||||
}
|
|
||||||
|
|
||||||
addAttachmentClass(attachment) {
|
|
||||||
$(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
getTipElement() {
|
|
||||||
this.tip = this.tip || $(this.config.template)[0]
|
|
||||||
return this.tip
|
|
||||||
}
|
|
||||||
|
|
||||||
setContent() {
|
|
||||||
const $tip = $(this.getTipElement())
|
|
||||||
this.setElementContent($tip.find(Selector.TOOLTIP_INNER), this.getTitle())
|
|
||||||
$tip.removeClass(`${ClassName.FADE} ${ClassName.SHOW}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
setElementContent($element, content) {
|
|
||||||
const html = this.config.html
|
|
||||||
if (typeof content === 'object' && (content.nodeType || content.jquery)) {
|
|
||||||
// Content is a DOM node or a jQuery
|
|
||||||
if (html) {
|
|
||||||
if (!$(content).parent().is($element)) {
|
|
||||||
$element.empty().append(content)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$element.text($(content).text())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$element[html ? 'html' : 'text'](content)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getTitle() {
|
|
||||||
let title = this.element.getAttribute('data-original-title')
|
|
||||||
|
|
||||||
if (!title) {
|
|
||||||
title = typeof this.config.title === 'function'
|
|
||||||
? this.config.title.call(this.element)
|
|
||||||
: this.config.title
|
|
||||||
}
|
|
||||||
|
|
||||||
return title
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private
|
|
||||||
|
|
||||||
_getAttachment(placement) {
|
|
||||||
return AttachmentMap[placement.toUpperCase()]
|
|
||||||
}
|
|
||||||
|
|
||||||
_setListeners() {
|
|
||||||
const triggers = this.config.trigger.split(' ')
|
|
||||||
|
|
||||||
triggers.forEach((trigger) => {
|
|
||||||
if (trigger === 'click') {
|
|
||||||
$(this.element).on(
|
|
||||||
this.constructor.Event.CLICK,
|
|
||||||
this.config.selector,
|
|
||||||
(event) => this.toggle(event)
|
|
||||||
)
|
|
||||||
} else if (trigger !== Trigger.MANUAL) {
|
|
||||||
const eventIn = trigger === Trigger.HOVER
|
|
||||||
? this.constructor.Event.MOUSEENTER
|
|
||||||
: this.constructor.Event.FOCUSIN
|
|
||||||
const eventOut = trigger === Trigger.HOVER
|
|
||||||
? this.constructor.Event.MOUSELEAVE
|
|
||||||
: this.constructor.Event.FOCUSOUT
|
|
||||||
|
|
||||||
$(this.element)
|
|
||||||
.on(
|
|
||||||
eventIn,
|
|
||||||
this.config.selector,
|
|
||||||
(event) => this._enter(event)
|
|
||||||
)
|
|
||||||
.on(
|
|
||||||
eventOut,
|
|
||||||
this.config.selector,
|
|
||||||
(event) => this._leave(event)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
$(this.element).closest('.modal').on(
|
|
||||||
'hide.bs.modal',
|
|
||||||
() => this.hide()
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
if (this.config.selector) {
|
|
||||||
this.config = {
|
|
||||||
...this.config,
|
|
||||||
trigger: 'manual',
|
|
||||||
selector: ''
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this._fixTitle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_fixTitle() {
|
|
||||||
const titleType = typeof this.element.getAttribute('data-original-title')
|
|
||||||
if (this.element.getAttribute('title') ||
|
|
||||||
titleType !== 'string') {
|
|
||||||
this.element.setAttribute(
|
|
||||||
'data-original-title',
|
|
||||||
this.element.getAttribute('title') || ''
|
|
||||||
)
|
|
||||||
this.element.setAttribute('title', '')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_enter(event, context) {
|
|
||||||
const dataKey = this.constructor.DATA_KEY
|
|
||||||
|
|
||||||
context = context || $(event.currentTarget).data(dataKey)
|
|
||||||
|
|
||||||
if (!context) {
|
|
||||||
context = new this.constructor(
|
|
||||||
event.currentTarget,
|
|
||||||
this._getDelegateConfig()
|
|
||||||
)
|
|
||||||
$(event.currentTarget).data(dataKey, context)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event) {
|
|
||||||
context._activeTrigger[
|
|
||||||
event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER
|
|
||||||
] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($(context.getTipElement()).hasClass(ClassName.SHOW) ||
|
|
||||||
context._hoverState === HoverState.SHOW) {
|
|
||||||
context._hoverState = HoverState.SHOW
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
clearTimeout(context._timeout)
|
|
||||||
|
|
||||||
context._hoverState = HoverState.SHOW
|
|
||||||
|
|
||||||
if (!context.config.delay || !context.config.delay.show) {
|
|
||||||
context.show()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
context._timeout = setTimeout(() => {
|
|
||||||
if (context._hoverState === HoverState.SHOW) {
|
|
||||||
context.show()
|
|
||||||
}
|
|
||||||
}, context.config.delay.show)
|
|
||||||
}
|
|
||||||
|
|
||||||
_leave(event, context) {
|
|
||||||
const dataKey = this.constructor.DATA_KEY
|
|
||||||
|
|
||||||
context = context || $(event.currentTarget).data(dataKey)
|
|
||||||
|
|
||||||
if (!context) {
|
|
||||||
context = new this.constructor(
|
|
||||||
event.currentTarget,
|
|
||||||
this._getDelegateConfig()
|
|
||||||
)
|
|
||||||
$(event.currentTarget).data(dataKey, context)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event) {
|
|
||||||
context._activeTrigger[
|
|
||||||
event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER
|
|
||||||
] = false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context._isWithActiveTrigger()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
clearTimeout(context._timeout)
|
|
||||||
|
|
||||||
context._hoverState = HoverState.OUT
|
|
||||||
|
|
||||||
if (!context.config.delay || !context.config.delay.hide) {
|
|
||||||
context.hide()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
context._timeout = setTimeout(() => {
|
|
||||||
if (context._hoverState === HoverState.OUT) {
|
|
||||||
context.hide()
|
|
||||||
}
|
|
||||||
}, context.config.delay.hide)
|
|
||||||
}
|
|
||||||
|
|
||||||
_isWithActiveTrigger() {
|
|
||||||
for (const trigger in this._activeTrigger) {
|
|
||||||
if (this._activeTrigger[trigger]) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
_getConfig(config) {
|
|
||||||
config = {
|
|
||||||
...this.constructor.Default,
|
|
||||||
...$(this.element).data(),
|
|
||||||
...config
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof config.delay === 'number') {
|
|
||||||
config.delay = {
|
|
||||||
show: config.delay,
|
|
||||||
hide: config.delay
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof config.title === 'number') {
|
|
||||||
config.title = config.title.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof config.content === 'number') {
|
|
||||||
config.content = config.content.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
Util.typeCheckConfig(
|
|
||||||
NAME,
|
|
||||||
config,
|
|
||||||
this.constructor.DefaultType
|
|
||||||
)
|
|
||||||
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
|
|
||||||
_getDelegateConfig() {
|
|
||||||
const config = {}
|
|
||||||
|
|
||||||
if (this.config) {
|
|
||||||
for (const key in this.config) {
|
|
||||||
if (this.constructor.Default[key] !== this.config[key]) {
|
|
||||||
config[key] = this.config[key]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
|
|
||||||
_cleanTipClass() {
|
|
||||||
const $tip = $(this.getTipElement())
|
|
||||||
const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)
|
|
||||||
if (tabClass !== null && tabClass.length > 0) {
|
|
||||||
$tip.removeClass(tabClass.join(''))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_handlePopperPlacementChange(data) {
|
|
||||||
this._cleanTipClass()
|
|
||||||
this.addAttachmentClass(this._getAttachment(data.placement))
|
|
||||||
}
|
|
||||||
|
|
||||||
_fixTransition() {
|
|
||||||
const tip = this.getTipElement()
|
|
||||||
const initConfigAnimation = this.config.animation
|
|
||||||
if (tip.getAttribute('x-placement') !== null) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
$(tip).removeClass(ClassName.FADE)
|
|
||||||
this.config.animation = false
|
|
||||||
this.hide()
|
|
||||||
this.show()
|
|
||||||
this.config.animation = initConfigAnimation
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static
|
|
||||||
|
|
||||||
static _jQueryInterface(config) {
|
|
||||||
return this.each(function () {
|
|
||||||
let data = $(this).data(DATA_KEY)
|
|
||||||
const _config = typeof config === 'object' && config
|
|
||||||
|
|
||||||
if (!data && /dispose|hide/.test(config)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!data) {
|
|
||||||
data = new Tooltip(this, _config)
|
|
||||||
$(this).data(DATA_KEY, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof config === 'string') {
|
|
||||||
if (typeof data[config] === 'undefined') {
|
|
||||||
throw new TypeError(`No method named "${config}"`)
|
|
||||||
}
|
|
||||||
data[config]()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* jQuery
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
$.fn[NAME] = Tooltip._jQueryInterface
|
|
||||||
$.fn[NAME].Constructor = Tooltip
|
|
||||||
$.fn[NAME].noConflict = function () {
|
|
||||||
$.fn[NAME] = JQUERY_NO_CONFLICT
|
|
||||||
return Tooltip._jQueryInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
return Tooltip
|
|
||||||
})($, Popper)
|
|
||||||
|
|
||||||
export default Tooltip
|
|
|
@ -1,161 +0,0 @@
|
||||||
import $ from 'jquery'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Bootstrap (v4.0.0): util.js
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const Util = (($) => {
|
|
||||||
/**
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
* Private TransitionEnd Helpers
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
let transition = false
|
|
||||||
|
|
||||||
const MAX_UID = 1000000
|
|
||||||
|
|
||||||
// Shoutout AngusCroll (https://goo.gl/pxwQGp)
|
|
||||||
function toType(obj) {
|
|
||||||
return {}.toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSpecialTransitionEndEvent() {
|
|
||||||
return {
|
|
||||||
bindType: transition.end,
|
|
||||||
delegateType: transition.end,
|
|
||||||
handle(event) {
|
|
||||||
if ($(event.target).is(this)) {
|
|
||||||
return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params
|
|
||||||
}
|
|
||||||
return undefined // eslint-disable-line no-undefined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function transitionEndTest() {
|
|
||||||
if (typeof window !== 'undefined' && window.QUnit) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
end: 'transitionend'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function transitionEndEmulator(duration) {
|
|
||||||
let called = false
|
|
||||||
|
|
||||||
$(this).one(Util.TRANSITION_END, () => {
|
|
||||||
called = true
|
|
||||||
})
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
if (!called) {
|
|
||||||
Util.triggerTransitionEnd(this)
|
|
||||||
}
|
|
||||||
}, duration)
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
function setTransitionEndSupport() {
|
|
||||||
transition = transitionEndTest()
|
|
||||||
|
|
||||||
$.fn.emulateTransitionEnd = transitionEndEmulator
|
|
||||||
|
|
||||||
if (Util.supportsTransitionEnd()) {
|
|
||||||
$.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function escapeId(selector) {
|
|
||||||
// We escape IDs in case of special selectors (selector = '#myId:something')
|
|
||||||
// $.escapeSelector does not exist in jQuery < 3
|
|
||||||
selector = typeof $.escapeSelector === 'function' ? $.escapeSelector(selector).substr(1)
|
|
||||||
: selector.replace(/(:|\.|\[|\]|,|=|@)/g, '\\$1')
|
|
||||||
|
|
||||||
return selector
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Public Util Api
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const Util = {
|
|
||||||
|
|
||||||
TRANSITION_END: 'bsTransitionEnd',
|
|
||||||
|
|
||||||
getUID(prefix) {
|
|
||||||
do {
|
|
||||||
// eslint-disable-next-line no-bitwise
|
|
||||||
prefix += ~~(Math.random() * MAX_UID) // "~~" acts like a faster Math.floor() here
|
|
||||||
} while (document.getElementById(prefix))
|
|
||||||
return prefix
|
|
||||||
},
|
|
||||||
|
|
||||||
getSelectorFromElement(element) {
|
|
||||||
let selector = element.getAttribute('data-target')
|
|
||||||
if (!selector || selector === '#') {
|
|
||||||
selector = element.getAttribute('href') || ''
|
|
||||||
}
|
|
||||||
|
|
||||||
// If it's an ID
|
|
||||||
if (selector.charAt(0) === '#') {
|
|
||||||
selector = escapeId(selector)
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const $selector = $(document).find(selector)
|
|
||||||
return $selector.length > 0 ? selector : null
|
|
||||||
} catch (err) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
reflow(element) {
|
|
||||||
return element.offsetHeight
|
|
||||||
},
|
|
||||||
|
|
||||||
triggerTransitionEnd(element) {
|
|
||||||
$(element).trigger(transition.end)
|
|
||||||
},
|
|
||||||
|
|
||||||
supportsTransitionEnd() {
|
|
||||||
return Boolean(transition)
|
|
||||||
},
|
|
||||||
|
|
||||||
isElement(obj) {
|
|
||||||
return (obj[0] || obj).nodeType
|
|
||||||
},
|
|
||||||
|
|
||||||
typeCheckConfig(componentName, config, configTypes) {
|
|
||||||
for (const property in configTypes) {
|
|
||||||
if (Object.prototype.hasOwnProperty.call(configTypes, property)) {
|
|
||||||
const expectedTypes = configTypes[property]
|
|
||||||
const value = config[property]
|
|
||||||
const valueType = value && Util.isElement(value)
|
|
||||||
? 'element' : toType(value)
|
|
||||||
|
|
||||||
if (!new RegExp(expectedTypes).test(valueType)) {
|
|
||||||
throw new Error(
|
|
||||||
`${componentName.toUpperCase()}: ` +
|
|
||||||
`Option "${property}" provided type "${valueType}" ` +
|
|
||||||
`but expected type "${expectedTypes}".`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setTransitionEndSupport()
|
|
||||||
|
|
||||||
return Util
|
|
||||||
})($)
|
|
||||||
|
|
||||||
export default Util
|
|
Before Width: | Height: | Size: 732 KiB After Width: | Height: | Size: 676 KiB |
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 141 KiB |
Before Width: | Height: | Size: 775 KiB After Width: | Height: | Size: 798 KiB |
|
@ -1,98 +0,0 @@
|
||||||
## -*- coding: utf-8 -*-
|
|
||||||
<%namespace name="base" file="base_helper.tmpl" import="*" />
|
|
||||||
<%namespace name="notes" file="annotation_helper.tmpl" import="*" />
|
|
||||||
${set_locale(lang)}
|
|
||||||
${base.html_headstart()}
|
|
||||||
<%block name="extra_head">
|
|
||||||
### Leave this block alone.
|
|
||||||
</%block>
|
|
||||||
${template_hooks['extra_head']()}
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<a href="#content" class="sr-only sr-only-focusable">${messages("Skip to main content")}</a>
|
|
||||||
|
|
||||||
<header id="banner"><br/><h1>The LIS Scholarship Archive</h1><h2>A free, open scholarly platform for library and information science</h2>
|
|
||||||
|
|
||||||
<!-- Menubar -->
|
|
||||||
|
|
||||||
<nav class="navbar navbar-expand-md static-top mb-4
|
|
||||||
% if theme_config.get('navbar_light'):
|
|
||||||
navbar-light bg-light
|
|
||||||
% else:
|
|
||||||
navbar-dark bg-dark
|
|
||||||
% endif
|
|
||||||
">
|
|
||||||
<div class="container"><!-- This keeps the margins nice -->
|
|
||||||
<a class="navbar-brand" href="${abs_link(_link("root", None, lang))}">
|
|
||||||
%if logo_url:
|
|
||||||
<img src="${logo_url}" alt="${blog_title|h}" id="logo" class="d-inline-block align-top">
|
|
||||||
%endif
|
|
||||||
|
|
||||||
% if show_blog_title:
|
|
||||||
<span id="blog-title">${blog_title|h}</span>
|
|
||||||
% endif
|
|
||||||
</a>
|
|
||||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#bs-navbar" aria-controls="bs-navbar" aria-expanded="false" aria-label="Toggle navigation">
|
|
||||||
<span class="navbar-toggler-icon"></span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<div class="collapse navbar-collapse" id="bs-navbar">
|
|
||||||
<ul class="navbar-nav mr-auto">
|
|
||||||
${base.html_navigation_links_entries(navigation_links)}
|
|
||||||
${template_hooks['menu']()}
|
|
||||||
</ul>
|
|
||||||
%if search_form:
|
|
||||||
${search_form}
|
|
||||||
%endif
|
|
||||||
|
|
||||||
<ul class="navbar-nav navbar-right">
|
|
||||||
${base.html_navigation_links_entries(navigation_alt_links)}
|
|
||||||
<%block name="belowtitle">
|
|
||||||
%if len(translations) > 1:
|
|
||||||
<li>${base.html_translations()}</li>
|
|
||||||
%endif
|
|
||||||
</%block>
|
|
||||||
% if show_sourcelink:
|
|
||||||
<%block name="sourcelink"></%block>
|
|
||||||
%endif
|
|
||||||
${template_hooks['menu_alt']()}
|
|
||||||
</ul>
|
|
||||||
</div><!-- /.navbar-collapse -->
|
|
||||||
</div><!-- /.container -->
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<!-- End of Menubar -->
|
|
||||||
|
|
||||||
<div class="container" id="content" role="main">
|
|
||||||
<div class="body-content">
|
|
||||||
<!--Body content-->
|
|
||||||
${template_hooks['page_header']()}
|
|
||||||
<%block name="content"></%block>
|
|
||||||
<!--End of body content-->
|
|
||||||
|
|
||||||
<footer id="footer">
|
|
||||||
${content_footer}
|
|
||||||
${template_hooks['page_footer']()}
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
${base.late_load_js()}
|
|
||||||
<!-- fancy dates -->
|
|
||||||
<script>
|
|
||||||
moment.locale("${momentjs_locales[lang]}");
|
|
||||||
fancydates(${date_fanciness}, ${js_date_format});
|
|
||||||
</script>
|
|
||||||
<!-- end fancy dates -->
|
|
||||||
<%block name="extra_js"></%block>
|
|
||||||
<script>
|
|
||||||
baguetteBox.run('div#content', {
|
|
||||||
ignoreClass: 'islink',
|
|
||||||
captions: function(element) {
|
|
||||||
return element.getElementsByTagName('img')[0].alt;
|
|
||||||
}});
|
|
||||||
</script>
|
|
||||||
${body_end}
|
|
||||||
${template_hooks['body_end']()}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,63 +0,0 @@
|
||||||
## -*- coding: utf-8 -*-
|
|
||||||
<%namespace name="helper" file="index_helper.tmpl"/>
|
|
||||||
<%namespace name="math" file="math_helper.tmpl"/>
|
|
||||||
<%namespace name="comments" file="comments_helper.tmpl"/>
|
|
||||||
<%namespace name="pagination" file="pagination_helper.tmpl"/>
|
|
||||||
<%namespace name="feeds_translations" file="feeds_translations_helper.tmpl" import="*"/>
|
|
||||||
<%inherit file="base.tmpl"/>
|
|
||||||
|
|
||||||
<%block name="extra_head">
|
|
||||||
${parent.extra_head()}
|
|
||||||
% if posts and (permalink == '/' or permalink == '/' + index_file):
|
|
||||||
<link rel="prefetch" href="${posts[0].permalink()}" type="text/html">
|
|
||||||
% endif
|
|
||||||
${math.math_styles_ifposts(posts)}
|
|
||||||
</%block>
|
|
||||||
|
|
||||||
<%block name="content">
|
|
||||||
<%block name="content_header">
|
|
||||||
${feeds_translations.translation_link(kind)}
|
|
||||||
</%block>
|
|
||||||
% if 'main_index' in pagekind:
|
|
||||||
${front_index_header}
|
|
||||||
% endif
|
|
||||||
% if page_links:
|
|
||||||
${pagination.page_navigation(current_page, page_links, prevlink, nextlink, prev_next_links_reversed)}
|
|
||||||
% endif
|
|
||||||
<div class="postindex">
|
|
||||||
% for post in posts:
|
|
||||||
<article class="h-entry post-${post.meta('type')}" itemscope="itemscope" itemtype="http://schema.org/Article">
|
|
||||||
<header>
|
|
||||||
<h1 class="p-name entry-title"><a href="${post.permalink()}" class="u-url">${post.title()|h}</a></h1>
|
|
||||||
<div class="metadata">
|
|
||||||
<p class="byline author vcard"><span class="byline-name fn" itemprop="author">
|
|
||||||
% if author_pages_generated:
|
|
||||||
<a href="${_link('author', post.author())}">${post.author()|h}</a>
|
|
||||||
% else:
|
|
||||||
${post.author()|h}
|
|
||||||
% endif
|
|
||||||
</span></p>
|
|
||||||
<p class="dateline">
|
|
||||||
<time class="published dt-published" datetime="${post.formatted_date('webiso')}" itemprop="datePublished" title="${post.formatted_date(date_format)|h}">${post.formatted_date(date_format)|h}</time>
|
|
||||||
% if post.updated and post.updated != post.date:
|
|
||||||
<span class="updated"> (${messages("updated")}
|
|
||||||
<time class="dt-updated" datetime="${post.formatted_updated('webiso')}" itemprop="dateUpdated" title="${post.formatted_updated(date_format)|h}">${post.formatted_updated(date_format)|h}</time>)</span>
|
|
||||||
% endif
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
%if index_teasers:
|
|
||||||
<div class="p-summary entry-summary">
|
|
||||||
${post.text(teaser_only=True)}
|
|
||||||
%else:
|
|
||||||
<div class="e-content entry-content">
|
|
||||||
${post.text(teaser_only=False)}
|
|
||||||
%endif
|
|
||||||
</div>
|
|
||||||
</article>
|
|
||||||
% endfor
|
|
||||||
</div>
|
|
||||||
${helper.html_pager()}
|
|
||||||
${comments.comment_link_script()}
|
|
||||||
${math.math_scripts_ifposts(posts)}
|
|
||||||
</%block>
|
|
|
@ -1,50 +0,0 @@
|
||||||
## -*- coding: utf-8 -*-
|
|
||||||
<%namespace name="helper" file="post_helper.tmpl"/>
|
|
||||||
<%namespace name="pheader" file="post_header.tmpl"/>
|
|
||||||
<%namespace name="comments" file="comments_helper.tmpl"/>
|
|
||||||
<%namespace name="math" file="math_helper.tmpl"/>
|
|
||||||
<%namespace name="ui" file="ui_helper.tmpl"/>
|
|
||||||
<%inherit file="base.tmpl"/>
|
|
||||||
|
|
||||||
<%block name="extra_head">
|
|
||||||
${parent.extra_head()}
|
|
||||||
% if post.meta('keywords'):
|
|
||||||
<meta name="keywords" content="${smartjoin(', ', post.meta('keywords'))|h}">
|
|
||||||
% endif
|
|
||||||
<meta name="author" content="${post.author()|h}">
|
|
||||||
%if post.prev_post:
|
|
||||||
<link rel="prev" href="${post.prev_post.permalink()}" title="${post.prev_post.title()|h}" type="text/html">
|
|
||||||
%endif
|
|
||||||
%if post.next_post:
|
|
||||||
<link rel="next" href="${post.next_post.permalink()}" title="${post.next_post.title()|h}" type="text/html">
|
|
||||||
%endif
|
|
||||||
% if post.is_draft:
|
|
||||||
<meta name="robots" content="noindex">
|
|
||||||
% endif
|
|
||||||
${helper.open_graph_metadata(post)}
|
|
||||||
${helper.twitter_card_information(post)}
|
|
||||||
${helper.meta_translations(post)}
|
|
||||||
${math.math_styles_ifpost(post)}
|
|
||||||
</%block>
|
|
||||||
|
|
||||||
<%block name="content">
|
|
||||||
<article class="post-${post.meta('type')} h-entry hentry postpage" itemscope="itemscope" itemtype="http://schema.org/Article">
|
|
||||||
${pheader.html_post_header()}
|
|
||||||
<div class="e-content entry-content" itemprop="articleBody text">
|
|
||||||
${post.text()}
|
|
||||||
</div>
|
|
||||||
<aside class="postpromonav">
|
|
||||||
<nav>
|
|
||||||
${helper.html_tags(post)}
|
|
||||||
${helper.html_pager(post)}
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
${math.math_scripts_ifpost(post)}
|
|
||||||
</article>
|
|
||||||
</%block>
|
|
||||||
|
|
||||||
<%block name="sourcelink">
|
|
||||||
% if show_sourcelink:
|
|
||||||
${ui.show_sourcelink(post.source_link())}
|
|
||||||
% endif
|
|
||||||
</%block>
|
|
|
@ -1,52 +0,0 @@
|
||||||
## -*- coding: utf-8 -*-
|
|
||||||
<%namespace name="helper" file="post_helper.tmpl"/>
|
|
||||||
<%namespace name="comments" file="comments_helper.tmpl"/>
|
|
||||||
|
|
||||||
<%def name="html_title()">
|
|
||||||
%if title and not post.meta('hidetitle'):
|
|
||||||
<h1 class="p-name entry-title" itemprop="headline name"><a href="${post.permalink()}" class="u-url">${post.title()|h}</a></h1>
|
|
||||||
%endif
|
|
||||||
</%def>
|
|
||||||
|
|
||||||
<%def name="html_translations(post)">
|
|
||||||
% if len(post.translated_to) > 1:
|
|
||||||
<div class="metadata posttranslations translations">
|
|
||||||
<h3 class="posttranslations-intro">${messages("Also available in:")}</h3>
|
|
||||||
% for langname in sorted(translations):
|
|
||||||
% if langname != lang and post.is_translation_available(langname):
|
|
||||||
<p><a href="${post.permalink(langname)}" rel="alternate" hreflang="${langname}">${messages("LANGUAGE", langname)}</a></p>
|
|
||||||
% endif
|
|
||||||
% endfor
|
|
||||||
</div>
|
|
||||||
% endif
|
|
||||||
</%def>
|
|
||||||
|
|
||||||
<%def name="html_sourcelink()">
|
|
||||||
% if show_sourcelink:
|
|
||||||
<p class="sourceline"><a href="${post.source_link()}" class="sourcelink">${messages("Source")}</a></p>
|
|
||||||
% endif
|
|
||||||
</%def>
|
|
||||||
|
|
||||||
<%def name="html_post_header()">
|
|
||||||
<header>
|
|
||||||
${html_title()}
|
|
||||||
<div class="metadata">
|
|
||||||
<p class="byline author vcard"><span class="byline-name fn" itemprop="author">
|
|
||||||
% if author_pages_generated:
|
|
||||||
<a href="${_link('author', post.author())}">${post.author()|h}</a>
|
|
||||||
% else:
|
|
||||||
${post.author()|h}
|
|
||||||
% endif
|
|
||||||
</span></p>
|
|
||||||
<p class="dateline">
|
|
||||||
<time class="published dt-published" datetime="${post.formatted_date('webiso')}" itemprop="datePublished" title="${post.formatted_date(date_format)|h}">${post.formatted_date(date_format)|h}</time></p>
|
|
||||||
% if post.updated and post.updated != post.date:
|
|
||||||
<span class="updated"> (${messages("updated")}
|
|
||||||
<time class="updated dt-updated" datetime="${post.formatted_updated('webiso')}" itemprop="dateUpdated" title="${post.formatted_updated(date_format)|h}">${post.formatted_updated(date_format)|h}</time>)</span>
|
|
||||||
% endif
|
|
||||||
<p><a href="mailto:?subject=I saw this and thought of you!&body=${post.title()} ${post.meta('link')}" onclick="ga('send', 'social', 'email', 'share', ${post.meta('link')}); return true;"><i class="far fa-envelope"></i></a></p>
|
|
||||||
<p><a href="https://twitter.com/share?url=${post.permalink()});text=${post.title()} ${post.meta('link')}" onclick="ga('send', 'social', 'Twitter', 'tweet', ${post.permalink()}); return true;" target="_blank"><i class="fab fa-twitter"></i></a></p>
|
|
||||||
</div>
|
|
||||||
${html_translations(post)}
|
|
||||||
</header>
|
|
||||||
</%def>
|
|
|
@ -3,25 +3,13 @@
|
||||||
<!-- Begin post-list ${post_list_id} -->
|
<!-- Begin post-list ${post_list_id} -->
|
||||||
<div id="${post_list_id}" class="post-list">
|
<div id="${post_list_id}" class="post-list">
|
||||||
%if posts:
|
%if posts:
|
||||||
<ul class="post-list list-unstyled">
|
<ul class="post-list">
|
||||||
% for post in posts:
|
% for post in posts:
|
||||||
<li class="post-list-item">
|
<li class="post-list-item">
|
||||||
<h1><a href="${post.permalink(lang)}">${post.title(lang)|h}</a></h1><p class="dateline">
|
<a href="${post.permalink(lang)}">${post.title(lang)|h}</a>
|
||||||
<div class="metadata">
|
|
||||||
<p class="dateline"><time class="published dt-published" datetime="${post.formatted_date('webiso')}" title="${post.formatted_date(date_format)|h}">${post.formatted_date(date_format)|h}</time></p>
|
|
||||||
<p><a href="mailto:?subject=I saw this and thought of you!&body=${post.title()} ${post.meta('link')}" onclick="ga('send', 'social', 'email', 'share', ${post.meta('link')}); return true;"><i class="far fa-envelope"></i></a></p>
|
|
||||||
<p><a href="https://twitter.com/share?url=${post.permalink()});text=${post.title()} ${post.meta('link')}" onclick="ga('send', 'social', 'Twitter', 'tweet', ${post.permalink()}); return true;" target="_blank"><i class="fab fa-twitter"></i></a></p>
|
|
||||||
</div>
|
|
||||||
%if index_teasers:
|
|
||||||
<div class="p-summary entry-summary">
|
|
||||||
${post.text(teaser_only=True)}
|
|
||||||
%else:
|
|
||||||
<div class="e-content entry-content">
|
|
||||||
${post.text(teaser_only=False)}
|
|
||||||
%endif
|
|
||||||
</li>
|
</li>
|
||||||
% endfor
|
% endfor
|
||||||
</ul>
|
</ul>
|
||||||
%endif
|
%endif
|
||||||
</div>
|
</div>
|
||||||
<!-- End post-list ${post_list_id} -->
|
<!-- End post-list ${post_list_id} -->
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
.. title: Announcing the LIS Scholarship Archive!
|
.. title: Announcing the LIS Scholarship Archive!
|
||||||
.. slug: lissa-announce
|
.. slug: lissa-announce
|
||||||
.. date: 2017-05-05 14:08:25 UTC-04:00
|
.. date: 2017-05-05 14:08:25 UTC-04:00
|
||||||
.. tags:
|
|
||||||
.. link: https://lissarchive.org/updates/lissa-announce/
|
.. link: https://lissarchive.org/updates/lissa-announce/
|
||||||
.. description:
|
.. description:
|
||||||
.. type: text
|
.. type: text
|
|
@ -2,7 +2,6 @@
|
||||||
.. title: LIS Scholarship Archive is open!
|
.. title: LIS Scholarship Archive is open!
|
||||||
.. slug: soft-launch
|
.. slug: soft-launch
|
||||||
.. date: 2017-07-19 14:08:25 UTC-04:00
|
.. date: 2017-07-19 14:08:25 UTC-04:00
|
||||||
.. tags:
|
|
||||||
.. link: https://lissarchive.org/updates/soft-launch/
|
.. link: https://lissarchive.org/updates/soft-launch/
|
||||||
.. description:
|
.. description:
|
||||||
.. type: text
|
.. type: text
|
|
@ -2,7 +2,6 @@
|
||||||
.. title: Open LIS work for #OAWeek!
|
.. title: Open LIS work for #OAWeek!
|
||||||
.. slug: launch
|
.. slug: launch
|
||||||
.. date: 2017-10-26 14:08:25 UTC-04:00
|
.. date: 2017-10-26 14:08:25 UTC-04:00
|
||||||
.. tags: home
|
|
||||||
.. link: https://lissarchive.org/updates/launch/
|
.. link: https://lissarchive.org/updates/launch/
|
||||||
.. description:
|
.. description:
|
||||||
.. type: text
|
.. type: text
|