overhauled completely

This commit is contained in:
Vicky Steeves 2020-05-04 17:58:03 -04:00
parent 21da112607
commit 0e11ed82d9
77 changed files with 9199 additions and 30271 deletions

114
README.md Normal file
View File

@ -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!

193
conf.py
View File

@ -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.
# #
@ -136,7 +46,6 @@ TRANSLATIONS_PATTERN = '{path}.{lang}.{ext}'
NAVIGATION_LINKS = { NAVIGATION_LINKS = {
DEFAULT_LANG: ( DEFAULT_LANG: (
("/", "Home"),
( (
( (
('/about/', 'Mission'), ('/about/', 'Mission'),
@ -149,8 +58,8 @@ NAVIGATION_LINKS = {
), ),
('/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,
@ -158,9 +67,8 @@ NAVIGATION_LINKS = {
# (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 pages title. # and displayed underneath the author list or index pages 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
@ -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&amp;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.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 422 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

BIN
images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
images/people/dina.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
images/people/jim.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

BIN
images/people/shanna.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -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">

50
pages/index.html Normal file
View File

@ -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&#39;t tried it myself, and then I thought, wait why not? So now I&#39;ve tried it. <a href="https://t.co/2fzTMKo5Fv">https://t.co/2fzTMKo5Fv</a></p>&mdash; 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>

View File

@ -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

View File

@ -17,32 +17,38 @@
<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 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>
<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 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> </div>

View File

@ -1 +0,0 @@
The source code behind lissarchive.org!

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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 */

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,229 +1,115 @@
/* -------------------- FONTS -------------------- */ body {
color:#323232;
font-size:1.1rem;
}
@import url('../webfronts/Arvo'); .jumbotron {
padding: 1rem 2rem 1rem 2rem ;
}
@import url('../webfronts/Quicksand'); .center {
display: block;
margin-left: auto;
margin-right: auto;
width: 50%;
}
/* -------------------- BODY -------------------- */ /* --------------------NAVBAR--------------------------*/
a:hover, a:focus { .navbar {
color: #dc7e4a; font-size: 1.1rem;
}
.bg-dark {
background-color: #492B5D !important;
}
.dropdown-item:focus, .dropdown-item:hover {
background-color: #492B5D;
color: white;
}
#blog-title {
vertical-align: -moz-middle-with-baseline;
}
/* --------------------TABLES--------------------------*/
.table .thead-dark th {
font-size: 1.1rem;
}
.table th, .table td {
font-size: 1.1rem;
color:black;
}
/* --------------------UNDERLINING LINKS--------------------------*/
.body-content p a {
text-decoration:underline; text-decoration:underline;
} }
a { .body-content li a {
color: #8966a0; text-decoration:underline;
}
.pager li a {
text-decoration:none; text-decoration:none;
} }
.u-url { footer a {
text-decoration:underline;
}
.card-deck li a {
text-decoration:none; text-decoration:none;
} }
body p{ .card-deck p a {
font-size: 1.06em;
}
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 {
background-color: #8966a0 !important;
}
.nav-item {
padding-right: 0.7em;
padding-left: 0.7em;
}
.navbar-dark .navbar-nav > li > a {
text-decoration:none; text-decoration:none;
font-size: 1.08em;
} }
.navbar-dark .nav-item .dropdown:focus, .navbar-dark .nav-item .dropdown:hover, .navbar-dark .nav-item .dropdown:active { /* --------------------CARDS--------------------------*/
color: #dc7e4a !important;
.card-body {
padding-left:1.25rem;
padding-right:1.25rem;
padding-top:1rem;
padding-bottom:0.5rem;
} }
.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 { /* --------------------RESPONSIVE DISPLAY HEADINGS--------------------------*/
color: #dc7e4a !important; @media (max-width: 575.98px) {
.display-1 {
font-size: 3rem;
font-weight: 300;
line-height: 1.0;
} }
.dropdown-item.active, .dropdown-item:active { .display-2 {
background-color: #dc7e4a !important; font-size: 2.75rem;
font-weight: 300;
line-height: 1.0;
} }
.nav-item .dropdown { .display-3 {
color: #dc7e4a !important; font-size: 2.25rem;
font-weight: 300;
line-height: 1.0;
} }
.dropdown-item:hover, .dropdown-item:focus { .display-4 {
background-color: #7da066; font-size: 1.75rem;
color: #ffffff; font-weight: 300;
line-height: 1.0;
} }
/* ------MOBILE NAV------ */
.navbar-dark .navbar-toggle:hover, .navbar-dark .navbar-toggle:focus {
background-color: #dc7e4a;
} }
.navbar-dark .navbar-toggle { /*!
border-color: #dc7e4a; * 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)
*/
@media (max-width: 767px) {
.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 {
color: #ffffff;
background-color: #dc7e4a;
}
}
/* -------------------- BUTTONS -------------------- */
.btn-primary {
color: #ffffff;
background-color: #6a4e7d;
border-color: #6a4e7d;
}
.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 {
color: #ffffff;
background-color: #b8a3c6;
border-color: #b8a3c6;
}
.btn-secondary:focus,
.btn-secondary.focus {
color: #ffffff;
background-color: #9c7eaf;
border-color: #9c7eaf;
}
.btn-secondary:hover {
color: #ffffff;
background-color: #9c7eaf;
border-color: #8966a0;
}
.btn-secondary:active,
.btn-secondary.active,
.open > .dropdown-toggle.btn-secondary {
color: #ffffff;
background-color: #9c7eaf;
border-color: #9c7eaf;
}
.btn-secondary:active:hover,
.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 -------------------- */
.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"); }

View File

@ -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;
}

View File

@ -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

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}

File diff suppressed because one or more lines are too long

View File

@ -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

View File

@ -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

File diff suppressed because one or more lines are too long

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 732 KiB

After

Width:  |  Height:  |  Size: 676 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 141 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 775 KiB

After

Width:  |  Height:  |  Size: 798 KiB

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -3,22 +3,10 @@
<!-- 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>

View File

@ -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

View File

@ -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

View File

@ -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