Upgrade Slate sample to Slate 2.7.1

Closes gh-693
This commit is contained in:
Andy Wilkinson
2020-09-02 10:56:05 +01:00
parent 536e87acc9
commit 9fa94022d2
40 changed files with 13461 additions and 11622 deletions

View File

@@ -22,3 +22,6 @@ build/
_yardoc
doc/
.idea/
# Vagrant artifacts
ubuntu-*-console.log

View File

@@ -1,6 +1,151 @@
# Changelog
## Version 1.5.0
## Version 2.7.1
*August 13, 2020*
* __[security]__ Bumped middleman from 4.3.7 to 4.3.8
_Note_: Slate uses redcarpet, not kramdown, for rendering markdown to HTML, and so was unaffected by the security vulnerability in middleman.
If you have changed slate to use kramdown, and with GFM, you may need to install the `kramdown-parser-gfm` gem.
## Version 2.7.0
*June 21, 2020*
* __[security]__ Bumped rack in Gemfile.lock from 2.2.2 to 2.2.3
* Bumped bundled jQuery from 3.2.1 to 3.5.1
* Bumped bundled lunr from 0.5.7 to 2.3.8
* Bumped imagesloaded from 3.1.8 to 4.1.4
* Bumped rouge from 3.17.0 to 3.20.0
* Bumped redcarpet from 3.4.0 to 3.5.0
* Fix color of highlighted code being unreadable when printing page
* Add clipboard icon for "Copy to Clipboard" functionality to code boxes (see note below)
* Fix handling of ToC selectors that contain punctutation (thanks @gruis)
* Fix language bar truncating languages that overflow screen width
* Strip HTML tags from ToC title before displaying it in title bar in JS (backup to stripping done in Ruby code) (thanks @atic)
To enable the new clipboard icon, you need to add `code_clipboard: true` to the frontmatter of source/index.html.md.
See [this line](https://github.com/slatedocs/slate/blame/main/source/index.html.md#L19) for an example of usage.
## Version 2.6.1
*May 30, 2020*
* __[security]__ update child dependency activesupport in Gemfile.lock to 5.4.2.3
* Update Middleman in Gemfile.lock to 4.3.7
* Replace Travis-CI with GitHub actions for continuous integration
* Replace Spectrum with GitHub discussions
## Version 2.6.0
*May 18, 2020*
__Note__: 2.5.0 was "pulled" due to a breaking bug discovered after release. It is recommended to skip it, and move straight to 2.6.0.
* Fix large whitespace gap in middle column for sections with codeblocks
* Fix highlighted code elements having a different background than rest of code block
* Change JSON keys to have a different font color than their values
* Disable asset hashing for woff and woff2 elements due to middleman bug breaking woff2 asset hashing in general
* Move Dockerfile to Debian from Alpine
* Converted repo to a [GitHub template](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-template-repository)
* Update sassc to 2.3.0 in Gemfile.lock
## Version 2.5.0
*May 8, 2020*
* __[security]__ update nokogiri to ~> 1.10.8
* Update links in example docs to https://github.com/slatedocs/slate from https://github.com/lord/slate
* Update LICENSE to include full Apache 2.0 text
* Test slate against Ruby 2.5 and 2.6 on Travis-CI
* Update Vagrantfile to use Ubuntu 18.04 (thanks @bradthurber)
* Parse arguments and flags for deploy.sh on script start, instead of potentially after building source files
* Install nodejs inside Vagrantfile (thanks @fernandoaguilar)
* Add Dockerfile for running slate (thanks @redhatxl)
* update middleman-syntax and rouge to ~>3.2
* update middleman to 4.3.6
## Version 2.4.0
*October 19, 2019*
- Move repository from lord/slate to slatedocs/slate
- Fix documentation to point at new repo link, thanks to [Arun](https://github.com/slash-arun), [Gustavo Gawryszewski](https://github.com/gawry), and [Daniel Korbit](https://github.com/danielkorbit)
- Update `nokogiri` to 1.10.4
- Update `ffi` in `Gemfile.lock` to fix security warnings, thanks to [Grey Baker](https://github.com/greysteil) and [jakemack](https://github.com/jakemack)
- Update `rack` to 2.0.7 in `Gemfile.lock` to fix security warnings, thanks to [Grey Baker](https://github.com/greysteil) and [jakemack](https://github.com/jakemack)
- Update middleman to `4.3` and relax constraints on middleman related gems, thanks to [jakemack](https://github.com/jakemack)
- Add sass gem, thanks to [jakemack](https://github.com/jakemack)
- Activate `asset_cache` in middleman to improve cacheability of static files, thanks to [Sam Gilman](https://github.com/thenengah)
- Update to using bundler 2 for `Gemfile.lock`, thanks to [jakemack](https://github.com/jakemack)
## Version 2.3.1
*July 5, 2018*
- Update `sprockets` in `Gemfile.lock` to fix security warnings
## Version 2.3
*July 5, 2018*
- Allows strikethrough in markdown by default.
- Upgrades jQuery to 3.2.1, thanks to [Tomi Takussaari](https://github.com/TomiTakussaari)
- Fixes invalid HTML in `layout.erb`, thanks to [Eric Scouten](https://github.com/scouten) for pointing out
- Hopefully fixes Vagrant memory issues, thanks to [Petter Blomberg](https://github.com/p-blomberg) for the suggestion
- Cleans HTML in headers before setting `document.title`, thanks to [Dan Levy](https://github.com/justsml)
- Allows trailing whitespace in markdown files, thanks to [Samuel Cousin](https://github.com/kuzyn)
- Fixes pushState/replaceState problems with scrolling not changing the document hash, thanks to [Andrey Fedorov](https://github.com/anfedorov)
- Removes some outdated examples, thanks [@al-tr](https://github.com/al-tr), [Jerome Dahdah](https://github.com/jdahdah), and [Ricardo Castro](https://github.com/mccricardo)
- Fixes `nav-padding` bug, thanks [Jerome Dahdah](https://github.com/jdahdah)
- Code style fixes thanks to [Sebastian Zaremba](https://github.com/vassyz)
- Nokogiri version bump thanks to [Grey Baker](https://github.com/greysteil)
- Fix to default `index.md` text thanks to [Nick Busey](https://github.com/NickBusey)
Thanks to everyone who contributed to this release!
## Version 2.2
*January 19, 2018*
- Fixes bugs with some non-roman languages not generating unique headers
- Adds editorconfig, thanks to [Jay Thomas](https://github.com/jaythomas)
- Adds optional `NestingUniqueHeadCounter`, thanks to [Vladimir Morozov](https://github.com/greenhost87)
- Small fixes to typos and language, thx [Emir Ribić](https://github.com/ribice), [Gregor Martynus](https://github.com/gr2m), and [Martius](https://github.com/martiuslim)!
- Adds links to Spectrum chat for questions in README and ISSUE_TEMPLATE
## Version 2.1
*October 30, 2017*
- Right-to-left text stylesheet option, thanks to [Mohammad Hossein Rabiee](https://github.com/mhrabiee)
- Fix for HTML5 history state bug, thanks to [Zach Toolson](https://github.com/ztoolson)
- Small styling changes, typo fixes, small bug fixes from [Marian Friedmann](https://github.com/rnarian), [Ben Wilhelm](https://github.com/benwilhelm), [Fouad Matin](https://github.com/fouad), [Nicolas Bonduel](https://github.com/NicolasBonduel), [Christian Oliff](https://github.com/coliff)
Thanks to everyone who submitted PRs for this version!
## Version 2.0
*July 17, 2017*
- All-new statically generated table of contents
- Should be much faster loading and scrolling for large pages
- Smaller Javascript file sizes
- Avoids the problem with the last link in the ToC not ever highlighting if the section was shorter than the page
- Fixes control-click not opening in a new page
- Automatically updates the HTML title as you scroll
- Updated design
- New default colors!
- New spacings and sizes!
- System-default typefaces, just like GitHub
- Added search input delay on large corpuses to reduce lag
- We even bumped the major version cause hey, why not?
- Various small bug fixes
Thanks to everyone who helped debug or wrote code for this version! It was a serious community effort, and I couldn't have done it alone.
## Version 1.5
*February 23, 2017*
@@ -9,7 +154,7 @@
- Switch default code highlighting color scheme to better highlight JSON
- Various small typo and bug fixes
## Version 1.4.0
## Version 1.4
*November 24, 2016*

View File

@@ -0,0 +1,20 @@
FROM ruby:2.6-slim
WORKDIR /srv/slate
VOLUME /srv/slate/source
EXPOSE 4567
COPY . /srv/slate
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential \
nodejs \
&& gem install bundler \
&& bundle install \
&& apt-get remove -y build-essential \
&& apt-get autoremove -y \
&& rm -rf /var/lib/apt/lists/*
CMD ["bundle", "exec", "middleman", "server", "--watcher-force-polling"]

View File

@@ -1,9 +1,12 @@
ruby '>=2.3.1'
source 'https://rubygems.org'
# Middleman
gem 'middleman', '~>4.2.1'
gem 'middleman-syntax', '~> 3.0.0'
gem 'middleman-autoprefixer', '~> 2.7.0'
gem "middleman-sprockets", "~> 4.1.0"
gem 'rouge', '~> 2.0.5'
gem 'redcarpet', '~> 3.4.0'
gem 'middleman', '~>4.3'
gem 'middleman-syntax', '~> 3.2'
gem 'middleman-autoprefixer', '~> 2.7'
gem 'middleman-sprockets', '~> 4.1'
gem 'rouge', '~> 3.20'
gem 'redcarpet', '~> 3.5.0'
gem 'nokogiri', '~> 1.10.8'
gem 'sass'

View File

@@ -1,60 +1,58 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (5.0.7)
activesupport (5.2.4.3)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
addressable (2.5.2)
public_suffix (>= 2.0.2, < 4.0)
autoprefixer-rails (6.7.7.2)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
autoprefixer-rails (9.5.1.1)
execjs
backports (3.11.4)
backports (3.18.1)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.12.2)
compass-import-once (1.0.5)
sass (>= 3.2, < 3.5)
concurrent-ruby (1.1.3)
concurrent-ruby (1.1.7)
contracts (0.13.0)
dotenv (2.5.0)
dotenv (2.7.6)
erubis (2.7.0)
execjs (2.7.0)
fast_blank (1.0.0)
fastimage (2.1.4)
ffi (1.9.25)
haml (5.0.4)
fastimage (2.2.0)
ffi (1.13.1)
haml (5.1.2)
temple (>= 0.8.0)
tilt
hamster (3.0.0)
concurrent-ruby (~> 1.0)
hashie (3.6.0)
i18n (0.7.0)
kramdown (1.17.0)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
kramdown (2.3.0)
rexml
listen (3.0.8)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
memoist (0.16.0)
middleman (4.2.1)
memoist (0.16.2)
middleman (4.3.8)
coffee-script (~> 2.2)
compass-import-once (= 1.0.5)
haml (>= 4.0.5)
kramdown (~> 1.2)
middleman-cli (= 4.2.1)
middleman-core (= 4.2.1)
sass (>= 3.4.0, < 4.0)
middleman-autoprefixer (2.7.1)
autoprefixer-rails (>= 6.5.2, < 7.0.0)
kramdown (>= 2.3.0)
middleman-cli (= 4.3.8)
middleman-core (= 4.3.8)
middleman-autoprefixer (2.10.1)
autoprefixer-rails (~> 9.1)
middleman-core (>= 3.3.3)
middleman-cli (4.2.1)
middleman-cli (4.3.8)
thor (>= 0.17.0, < 2.0)
middleman-core (4.2.1)
activesupport (>= 4.2, < 5.1)
middleman-core (4.3.8)
activesupport (>= 4.2, < 6.0)
addressable (~> 2.3)
backports (~> 3.6)
bundler (~> 1.1)
bundler
contracts (~> 0.13.0)
dotenv
erubis
@@ -63,47 +61,57 @@ GEM
fastimage (~> 2.0)
hamster (~> 3.0)
hashie (~> 3.4)
i18n (~> 0.7.0)
i18n (~> 0.9.0)
listen (~> 3.0.0)
memoist (~> 0.14)
padrino-helpers (~> 0.13.0)
parallel
rack (>= 1.4.5, < 3)
sass (>= 3.4)
sassc (~> 2.0)
servolux
tilt (~> 2.0)
tilt (~> 2.0.9)
uglifier (~> 3.0)
middleman-sprockets (4.1.1)
middleman-core (~> 4.0)
sprockets (>= 3.0)
middleman-syntax (3.0.0)
middleman-syntax (3.2.0)
middleman-core (>= 3.2)
rouge (~> 2.0)
minitest (5.11.3)
rouge (~> 3.2)
mini_portile2 (2.4.0)
minitest (5.14.1)
nokogiri (1.10.9)
mini_portile2 (~> 2.4.0)
padrino-helpers (0.13.3.4)
i18n (~> 0.6, >= 0.6.7)
padrino-support (= 0.13.3.4)
tilt (>= 1.4.1, < 3)
padrino-support (0.13.3.4)
activesupport (>= 3.1)
parallel (1.12.1)
public_suffix (3.0.3)
rack (2.0.6)
rb-fsevent (0.10.3)
rb-inotify (0.9.10)
ffi (>= 0.5.0, < 2)
redcarpet (3.4.0)
rouge (2.0.7)
sass (3.4.25)
parallel (1.19.2)
public_suffix (4.0.5)
rack (2.2.3)
rb-fsevent (0.10.4)
rb-inotify (0.10.1)
ffi (~> 1.0)
redcarpet (3.5.0)
rexml (3.2.4)
rouge (3.20.0)
sass (3.7.4)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
sassc (2.4.0)
ffi (~> 1.9)
servolux (0.13.0)
sprockets (3.7.2)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
temple (0.8.0)
thor (0.20.3)
temple (0.8.2)
thor (1.0.1)
thread_safe (0.3.6)
tilt (2.0.8)
tzinfo (1.2.5)
tilt (2.0.10)
tzinfo (1.2.7)
thread_safe (~> 0.1)
uglifier (3.2.0)
execjs (>= 0.3.0, < 3)
@@ -112,12 +120,17 @@ PLATFORMS
ruby
DEPENDENCIES
middleman (~> 4.2.1)
middleman-autoprefixer (~> 2.7.0)
middleman-sprockets (~> 4.1.0)
middleman-syntax (~> 3.0.0)
redcarpet (~> 3.4.0)
rouge (~> 2.0.5)
middleman (~> 4.3)
middleman-autoprefixer (~> 2.7)
middleman-sprockets (~> 4.1)
middleman-syntax (~> 3.2)
nokogiri (~> 1.10.8)
redcarpet (~> 3.5.0)
rouge (~> 3.20)
sass
RUBY VERSION
ruby 2.3.3p222
BUNDLED WITH
1.17.1
2.1.4

View File

@@ -1,13 +1,201 @@
Copyright 2008-2013 Concur Technologies, Inc.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
https://www.apache.org/licenses/LICENSE-2.0
1. Definitions.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,111 +0,0 @@
<p align="center">
<img src="https://raw.githubusercontent.com/lord/img/master/logo-slate.png" alt="Slate: API Documentation Generator" width="226">
<br>
<a href="https://travis-ci.org/lord/slate"><img src="https://travis-ci.org/lord/slate.svg?branch=master" alt="Build Status"></a>
</p>
<p align="center">Slate helps you create beautiful, intelligent, responsive API documentation.</p>
<p align="center"><img src="https://dl.dropboxusercontent.com/u/95847291/github%20images/slate/slate_screenshot_new.png" width=700 alt="Screenshot of Example Documentation created with Slate"></p>
<p align="center"><em>The example above was created with Slate. Check it out at <a href="https://lord.github.io/slate">lord.github.io/slate</a>.</em></p>
Features
------------
* **Clean, intuitive design** — With Slate, the description of your API is on the left side of your documentation, and all the code examples are on the right side. Inspired by [Stripe's](https://stripe.com/docs/api) and [Paypal's](https://developer.paypal.com/webapps/developer/docs/api/) API docs. Slate is responsive, so it looks great on tablets, phones, and even in print.
* **Everything on a single page** — Gone are the days when your users had to search through a million pages to find what they wanted. Slate puts the entire documentation on a single page. We haven't sacrificed linkability, though. As you scroll, your browser's hash will update to the nearest header, so linking to a particular point in the documentation is still natural and easy.
* **Slate is just Markdown** — When you write docs with Slate, you're just writing Markdown, which makes it simple to edit and understand. Everything is written in Markdown — even the code samples are just Markdown code blocks.
* **Write code samples in multiple languages** — If your API has bindings in multiple programming languages, you can easily put in tabs to switch between them. In your document, you'll distinguish different languages by specifying the language name at the top of each code block, just like with Github Flavored Markdown.
* **Out-of-the-box syntax highlighting** for [over 100 languages](https://github.com/jneen/rouge/wiki/List-of-supported-languages-and-lexers), no configuration required.
* **Automatic, smoothly scrolling table of contents** on the far left of the page. As you scroll, it displays your current position in the document. It's fast, too. We're using Slate at TripIt to build documentation for our new API, where our table of contents has over 180 entries. We've made sure that the performance remains excellent, even for larger documents.
* **Let your users update your documentation for you** — By default, your Slate-generated documentation is hosted in a public Github repository. Not only does this mean you get free hosting for your docs with Github Pages, but it also makes it simple for other developers to make pull requests to your docs if they find typos or other problems. Of course, if you don't want to use GitHub, you're also welcome to host your docs elsewhere.
Getting started with Slate is super easy! Simply fork this repository and follow the instructions below. Or, if you'd like to check out what Slate is capable of, take a look at the [sample docs](https://lord.github.io/slate).
Getting Started with Slate
------------------------------
### Prerequisites
You're going to need:
- **Linux or OS X** — Windows may work, but is unsupported.
- **Ruby, version 2.2.5 or newer**
- **Bundler** — If Ruby is already installed, but the `bundle` command doesn't work, just run `gem install bundler` in a terminal.
### Getting Set Up
1. Fork this repository on Github.
2. Clone *your forked repository* (not our original one) to your hard drive with `git clone https://github.com/YOURUSERNAME/slate.git`
3. `cd slate`
4. Initialize and start Slate. You can either do this locally, or with Vagrant:
```shell
# either run this to run locally
bundle install
bundle exec middleman server
# OR run this to run with vagrant
vagrant up
```
You can now see the docs at http://localhost:4567. Whoa! That was fast!
Now that Slate is all set up on your machine, you'll probably want to learn more about [editing Slate markdown](https://github.com/lord/slate/wiki/Markdown-Syntax), or [how to publish your docs](https://github.com/lord/slate/wiki/Deploying-Slate).
If you'd prefer to use Docker, instructions are available [in the wiki](https://github.com/lord/slate/wiki/Docker).
Companies Using Slate
---------------------------------
* [NASA](https://api.nasa.gov)
* [IBM](https://docs.cloudant.com/api.html)
* [Sony](https://developers.cimediacloud.com)
* [Mozilla](https://localforage.github.io/localForage/)
* [Best Buy](https://bestbuyapis.github.io/api-documentation/)
* [Travis-CI](https://docs.travis-ci.com/api/)
* [Greenhouse](https://developers.greenhouse.io/harvest.html)
* [Woocommerce](https://woocommerce.github.io/woocommerce-rest-api-docs/)
* [Appium](https://appium.io/slate/en/master)
* [Dwolla](https://docs.dwolla.com/)
* [Clearbit](https://clearbit.com/docs)
* [Coinbase](https://developers.coinbase.com/api)
* [Parrot Drones](https://developer.parrot.com/docs/bebop/)
* [Fidor Bank](https://api-docs.fidor.de)
* [Scale](https://docs.scaleapi.com/)
You can view more in [the list on the wiki](https://github.com/lord/slate/wiki/Slate-in-the-Wild).
Need Help? Found a bug?
--------------------
[Submit an issue](https://github.com/lord/slate/issues) to the Slate Github if you need any help. And, of course, feel free to submit pull requests with bug fixes or changes.
Contributors
--------------------
Slate was built by [Robert Lord](https://lord.io) while interning at [TripIt](https://www.tripit.com/).
Thanks to the following people who have submitted major pull requests:
- [@chrissrogers](https://github.com/chrissrogers)
- [@bootstraponline](https://github.com/bootstraponline)
- [@realityking](https://github.com/realityking)
- [@cvkef](https://github.com/cvkef)
Also, thanks to [Sauce Labs](https://saucelabs.com) for helping sponsor the project.
Special Thanks
--------------------
- [Middleman](https://github.com/middleman/middleman)
- [jquery.tocify.js](https://github.com/gfranko/jquery.tocify.js)
- [middleman-syntax](https://github.com/middleman/middleman-syntax)
- [middleman-gh-pages](https://github.com/edgecase/middleman-gh-pages)
- [Font Awesome](https://fortawesome.github.io/Font-Awesome/)

View File

@@ -1,14 +1,21 @@
Vagrant.configure(2) do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.box = "ubuntu/bionic64"
config.vm.network :forwarded_port, guest: 4567, host: 4567
config.vm.provider "virtualbox" do |vb|
vb.memory = "2048"
end
config.vm.provision "bootstrap",
type: "shell",
inline: <<-SHELL
# add nodejs v12 repository
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
sudo apt-get update
sudo apt-get install -yq ruby2.0 ruby2.0-dev pkg-config build-essential nodejs git libxml2-dev libxslt-dev
sudo apt-get install -yq ruby ruby-dev
sudo apt-get install -yq pkg-config build-essential nodejs git libxml2-dev libxslt-dev
sudo apt-get autoremove -yq
gem2.0 install --no-ri --no-rdoc bundler
gem install --no-ri --no-rdoc bundler
SHELL
# add the local user git config to the vm
@@ -34,6 +41,6 @@ Vagrant.configure(2) do |config|
echo "Starting up middleman at http://localhost:4567"
echo "If it does not come up, check the ~/middleman.log file for any error messages"
cd /vagrant
bundle exec middleman server --force-polling --latency=1 &> ~/middleman.log &
bundle exec middleman server --watcher-force-polling --watcher-latency=1 &> ~/middleman.log &
SHELL
end

View File

@@ -1,3 +1,6 @@
# Unique header generation
require './lib/unique_head.rb'
# Markdown
set :markdown_engine, :redcarpet
set :markdown,
@@ -5,9 +8,11 @@ set :markdown,
smartypants: true,
disable_indented_code_blocks: true,
prettify: true,
strikethrough: true,
tables: true,
with_toc_data: true,
no_intra_emphasis: true
no_intra_emphasis: true,
renderer: UniqueHeadCounter
# Assets
set :css_dir, 'stylesheets'
@@ -18,6 +23,7 @@ set :fonts_dir, 'fonts'
# Activate the syntax highlighter
activate :syntax
ready do
require './lib/monokai_sublime_slate.rb'
require './lib/multilang.rb'
end
@@ -34,19 +40,24 @@ activate :relative_assets
set :relative_links, true
# Build Configuration
set :build_dir, '../build/docs'
configure :build do
# We do want to hash woff and woff2 as there's a bug where woff2 will use
# woff asset hash which breaks things. Trying to use a combination of ignore and
# rewrite_ignore does not work as it conflicts weirdly with relative_assets. Disabling
# the .woff2 extension only does not work as .woff will still activate it so have to
# have both. See https://github.com/slatedocs/slate/issues/1171 for more details.
activate :asset_hash, :exts => app.config[:asset_extensions] - %w[.woff .woff2]
# If you're having trouble with Middleman hanging, commenting
# out the following two lines has been known to help
activate :minify_css
activate :minify_javascript
# activate :relative_assets
# activate :asset_hash
# activate :gzip
end
# Deploy Configuration
# If you want Middleman to listen on a different port, you can set that below
set :port, 4567
helpers do
require './lib/toc_data.rb'
end

View File

@@ -15,9 +15,14 @@ Options:
deploy branch.
-n, --no-hash Don't append the source commit's hash to the deploy
commit's message.
--source-only Only build but not push
--push-only Only push but not build
"
bundle exec middleman build --clean
run_build() {
bundle exec middleman build --clean
}
parse_args() {
# Set args from a local environment file.
@@ -31,7 +36,7 @@ parse_args() {
while : ; do
if [[ $1 = "-h" || $1 = "--help" ]]; then
echo "$help_message"
return 0
exit 0
elif [[ $1 = "-v" || $1 = "--verbose" ]]; then
verbose=true
shift
@@ -44,11 +49,22 @@ parse_args() {
elif [[ $1 = "-n" || $1 = "--no-hash" ]]; then
GIT_DEPLOY_APPEND_HASH=false
shift
elif [[ $1 = "--source-only" ]]; then
source_only=true
shift
elif [[ $1 = "--push-only" ]]; then
push_only=true
shift
else
break
fi
done
if [ ${source_only} ] && [ ${push_only} ]; then
>&2 echo "You can only specify one of --source-only or --push-only"
exit 1
fi
# Set internal option vars from the environment and arg flags. All internal
# vars should be declared here, with sane defaults if applicable.
@@ -68,8 +84,6 @@ parse_args() {
}
main() {
parse_args "$@"
enable_expanded_output
if ! git diff --exit-code --quiet --cached; then
@@ -97,7 +111,7 @@ main() {
return 1
fi
# must use short form of flag in ls for compatibility with OS X and BSD
# must use short form of flag in ls for compatibility with macOS and BSD
if [[ -z `ls -A "$deploy_directory" 2> /dev/null` && -z $allow_empty ]]; then
echo "Deploy directory '$deploy_directory' is empty. Aborting. If you're sure you want to deploy an empty tree, use the --allow-empty / -e flag." >&2
return 1
@@ -140,7 +154,7 @@ incremental_deploy() {
0) echo No changes to files in $deploy_directory. Skipping commit.;;
1) commit+push;;
*)
echo git diff exited with code $diff. Aborting. Staying on branch $deploy_branch so you can debug. To switch back to master, use: git symbolic-ref HEAD refs/heads/master && git reset --mixed >&2
echo git diff exited with code $diff. Aborting. Staying on branch $deploy_branch so you can debug. To switch back to main, use: git symbolic-ref HEAD refs/heads/main && git reset --mixed >&2
return $diff
;;
esac
@@ -200,4 +214,13 @@ sanitize() {
"$@" 2> >(filter 1>&2) | filter
}
[[ $1 = --source-only ]] || main "$@"
parse_args "$@"
if [[ ${source_only} ]]; then
run_build
elif [[ ${push_only} ]]; then
main "$@"
else
run_build
main "$@"
fi

View File

@@ -0,0 +1,95 @@
# -*- coding: utf-8 -*- #
# frozen_string_literal: true
# this is based on https://github.com/rouge-ruby/rouge/blob/master/lib/rouge/themes/monokai_sublime.rb
# but without the added background, and changed styling for JSON keys to be soft_yellow instead of white
module Rouge
module Themes
class MonokaiSublimeSlate < CSSTheme
name 'monokai.sublime.slate'
palette :black => '#000000'
palette :bright_green => '#a6e22e'
palette :bright_pink => '#f92672'
palette :carmine => '#960050'
palette :dark => '#49483e'
palette :dark_grey => '#888888'
palette :dark_red => '#aa0000'
palette :dimgrey => '#75715e'
palette :emperor => '#555555'
palette :grey => '#999999'
palette :light_grey => '#aaaaaa'
palette :light_violet => '#ae81ff'
palette :soft_cyan => '#66d9ef'
palette :soft_yellow => '#e6db74'
palette :very_dark => '#1e0010'
palette :whitish => '#f8f8f2'
palette :orange => '#f6aa11'
palette :white => '#ffffff'
style Generic::Heading, :fg => :grey
style Literal::String::Regex, :fg => :orange
style Generic::Output, :fg => :dark_grey
style Generic::Prompt, :fg => :emperor
style Generic::Strong, :bold => false
style Generic::Subheading, :fg => :light_grey
style Name::Builtin, :fg => :orange
style Comment::Multiline,
Comment::Preproc,
Comment::Single,
Comment::Special,
Comment, :fg => :dimgrey
style Error,
Generic::Error,
Generic::Traceback, :fg => :carmine
style Generic::Deleted,
Generic::Inserted,
Generic::Emph, :fg => :dark
style Keyword::Constant,
Keyword::Declaration,
Keyword::Reserved,
Name::Constant,
Keyword::Type, :fg => :soft_cyan
style Literal::Number::Float,
Literal::Number::Hex,
Literal::Number::Integer::Long,
Literal::Number::Integer,
Literal::Number::Oct,
Literal::Number,
Literal::String::Char,
Literal::String::Escape,
Literal::String::Symbol, :fg => :light_violet
style Literal::String::Doc,
Literal::String::Double,
Literal::String::Backtick,
Literal::String::Heredoc,
Literal::String::Interpol,
Literal::String::Other,
Literal::String::Single,
Literal::String, :fg => :soft_yellow
style Name::Attribute,
Name::Class,
Name::Decorator,
Name::Exception,
Name::Function, :fg => :bright_green
style Name::Variable::Class,
Name::Namespace,
Name::Entity,
Name::Builtin::Pseudo,
Name::Variable::Global,
Name::Variable::Instance,
Name::Variable,
Text::Whitespace,
Text,
Name, :fg => :white
style Name::Label, :fg => :bright_pink
style Operator::Word,
Name::Tag,
Keyword,
Keyword::Namespace,
Keyword::Pseudo,
Operator, :fg => :bright_pink
end
end
end

View File

@@ -1,9 +1,13 @@
module Multilang
def block_code(code, full_lang_name)
parts = full_lang_name.split('--')
rouge_lang_name = parts[0] || ""
super(code, rouge_lang_name).sub("highlight #{rouge_lang_name}") do |match|
match + " tab-" + full_lang_name
if full_lang_name
parts = full_lang_name.split('--')
rouge_lang_name = (parts) ? parts[0] : "" # just parts[0] here causes null ref exception when no language specified
super(code, rouge_lang_name).sub("highlight #{rouge_lang_name}") do |match|
match + " tab-" + full_lang_name
end
else
super(code, full_lang_name)
end
end
end

View File

@@ -0,0 +1,22 @@
# Nested unique header generation
require 'middleman-core/renderers/redcarpet'
class NestingUniqueHeadCounter < Middleman::Renderers::MiddlemanRedcarpetHTML
def initialize
super
@@headers_history = {} if !defined?(@@headers_history)
end
def header(text, header_level)
friendly_text = text.gsub(/<[^>]*>/,"").parameterize
@@headers_history[header_level] = text.parameterize
if header_level > 1
for i in (header_level - 1).downto(1)
friendly_text.prepend("#{@@headers_history[i]}-") if @@headers_history.key?(i)
end
end
return "<h#{header_level} id='#{friendly_text}'>#{text}</h#{header_level}>"
end
end

View File

@@ -0,0 +1,31 @@
require 'nokogiri'
def toc_data(page_content)
html_doc = Nokogiri::HTML::DocumentFragment.parse(page_content)
# get a flat list of headers
headers = []
html_doc.css('h1, h2, h3').each do |header|
headers.push({
id: header.attribute('id').to_s,
content: header.children,
title: header.children.to_s.gsub(/<[^>]*>/, ''),
level: header.name[1].to_i,
children: []
})
end
[3,2].each do |header_level|
header_to_nest = nil
headers = headers.reject do |header|
if header[:level] == header_level
header_to_nest[:children].push header if header_to_nest
true
else
header_to_nest = header if header[:level] < header_level
false
end
end
end
headers
end

View File

@@ -0,0 +1,24 @@
# Unique header generation
require 'middleman-core/renderers/redcarpet'
require 'digest'
class UniqueHeadCounter < Middleman::Renderers::MiddlemanRedcarpetHTML
def initialize
super
@head_count = {}
end
def header(text, header_level)
friendly_text = text.gsub(/<[^>]*>/,"").parameterize
if friendly_text.strip.length == 0
# Looks like parameterize removed the whole thing! It removes many unicode
# characters like Chinese and Russian. To get a unique URL, let's just
# URI escape the whole header
friendly_text = Digest::SHA1.hexdigest(text)[0,10]
end
@head_count[friendly_text] ||= 0
@head_count[friendly_text] += 1
if @head_count[friendly_text] > 1
friendly_text += "-#{@head_count[friendly_text]}"
end
return "<h#{header_level} id='#{friendly_text}'>#{text}</h#{header_level}>"
end
end

0
samples/rest-notes-slate/slate/source/fonts/slate.eot Executable file → Normal file
View File

2
samples/rest-notes-slate/slate/source/fonts/slate.svg Executable file → Normal file
View File

@@ -1,5 +1,5 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "https://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by IcoMoon</metadata>
<defs>

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
samples/rest-notes-slate/slate/source/fonts/slate.ttf Executable file → Normal file
View File

0
samples/rest-notes-slate/slate/source/fonts/slate.woff Executable file → Normal file
View File

View File

View File

@@ -1,20 +1,22 @@
# Errors
<aside class="notice">This error section is stored in a separate file in `includes/_errors.md`. Slate allows you to optionally separate out your docs into many files...just save them to the `includes` folder and add them to the top of your `index.md`'s frontmatter. Files are included in the order listed.</aside>
<aside class="notice">
This error section is stored in a separate file in <code>includes/_errors.md</code>. Slate allows you to optionally separate out your docs into many files...just save them to the <code>includes</code> folder and add them to the top of your <code>index.md</code>'s frontmatter. Files are included in the order listed.
</aside>
The Kittn API uses the following error codes:
Error Code | Meaning
---------- | -------
400 | Bad Request -- Your request sucks
401 | Unauthorized -- Your API key is wrong
403 | Forbidden -- The kitten requested is hidden for administrators only
404 | Not Found -- The specified kitten could not be found
405 | Method Not Allowed -- You tried to access a kitten with an invalid method
406 | Not Acceptable -- You requested a format that isn't json
410 | Gone -- The kitten requested has been removed from our servers
418 | I'm a teapot
400 | Bad Request -- Your request is invalid.
401 | Unauthorized -- Your API key is wrong.
403 | Forbidden -- The kitten requested is hidden for administrators only.
404 | Not Found -- The specified kitten could not be found.
405 | Method Not Allowed -- You tried to access a kitten with an invalid method.
406 | Not Acceptable -- You requested a format that isn't json.
410 | Gone -- The kitten requested has been removed from our servers.
418 | I'm a teapot.
429 | Too Many Requests -- You're requesting too many kittens! Slow down!
500 | Internal Server Error -- We had a problem with our server. Try again later.
503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later.

View File

@@ -1,7 +1,7 @@
---
title: API Reference
language_tabs:
language_tabs: # must be one of https://git.io/vQNgJ
- shell
- ruby
- python
@@ -9,21 +9,23 @@ language_tabs:
toc_footers:
- <a href='#'>Sign Up for a Developer Key</a>
- <a href='https://github.com/tripit/slate'>Documentation Powered by Slate</a>
- <a href='https://github.com/slatedocs/slate'>Documentation Powered by Slate</a>
includes:
- errors
search: true
code_clipboard: true
---
# Introduction
Welcome to the Kittn API! You can use our API to access Kittn API endpoints, which can get information on various cats, kittens, and breeds in our database.
We have language bindings in Shell, Ruby, and Python! You can view code examples in the dark area to the right, and you can switch the programming language of the examples with the tabs in the top right.
We have language bindings in Shell, Ruby, Python, and JavaScript! You can view code examples in the dark area to the right, and you can switch the programming language of the examples with the tabs in the top right.
This example API documentation page was created with [Slate](https://github.com/tripit/slate). Feel free to edit it and use it as a base for your own API's documentation.
This example API documentation page was created with [Slate](https://github.com/slatedocs/slate). Feel free to edit it and use it as a base for your own API's documentation.
# Authentication
@@ -55,7 +57,7 @@ let api = kittn.authorize('meowmeowmeow');
> Make sure to replace `meowmeowmeow` with your API key.
Kittn uses API keys to allow access to the API. You can register a new Kittn API key at our [developer portal](https://example.com/developers).
Kittn uses API keys to allow access to the API. You can register a new Kittn API key at our [developer portal](http://example.com/developers).
Kittn expects for the API key to be included in all API requests to the server in a header that looks like the following:
@@ -84,7 +86,7 @@ api.kittens.get()
```
```shell
curl "https://example.com/api/kittens"
curl "http://example.com/api/kittens"
-H "Authorization: meowmeowmeow"
```
@@ -120,7 +122,7 @@ This endpoint retrieves all kittens.
### HTTP Request
`GET https://example.com/api/kittens`
`GET http://example.com/api/kittens`
### Query Parameters
@@ -150,7 +152,7 @@ api.kittens.get(2)
```
```shell
curl "https://example.com/api/kittens/2"
curl "http://example.com/api/kittens/2"
-H "Authorization: meowmeowmeow"
```
@@ -179,7 +181,7 @@ This endpoint retrieves a specific kitten.
### HTTP Request
`GET https://example.com/kittens/<ID>`
`GET http://example.com/kittens/<ID>`
### URL Parameters
@@ -187,3 +189,53 @@ Parameter | Description
--------- | -----------
ID | The ID of the kitten to retrieve
## Delete a Specific Kitten
```ruby
require 'kittn'
api = Kittn::APIClient.authorize!('meowmeowmeow')
api.kittens.delete(2)
```
```python
import kittn
api = kittn.authorize('meowmeowmeow')
api.kittens.delete(2)
```
```shell
curl "http://example.com/api/kittens/2"
-X DELETE
-H "Authorization: meowmeowmeow"
```
```javascript
const kittn = require('kittn');
let api = kittn.authorize('meowmeowmeow');
let max = api.kittens.delete(2);
```
> The above command returns JSON structured like this:
```json
{
"id": 2,
"deleted" : ":("
}
```
This endpoint deletes a specific kitten.
### HTTP Request
`DELETE http://example.com/kittens/<ID>`
### URL Parameters
Parameter | Description
--------- | -----------
ID | The ID of the kitten to delete

View File

@@ -1,4 +1,2 @@
//= require ./lib/_energize
//= require ./app/_lang
//= require ./all_nosearch
//= require ./app/_search
//= require ./app/_toc

View File

@@ -1,3 +1,27 @@
//= require ./lib/_energize
//= require ./app/_lang
//= require ./app/_copy
//= require ./app/_toc
//= require ./app/_lang
function adjustLanguageSelectorWidth() {
const elem = $('.dark-box > .lang-selector');
elem.width(elem.parent().width());
}
$(function() {
loadToc($('#toc'), '.toc-link', '.toc-list-h2', 10);
setupLanguages($('body').data('languages'));
$('.content').imagesLoaded( function() {
window.recacheHeights();
window.refreshToc();
});
$(window).resize(function() {
adjustLanguageSelectorWidth();
});
adjustLanguageSelectorWidth();
});
window.onpopstate = function() {
activateLanguage(getLanguageFromQueryString());
};

View File

@@ -0,0 +1,15 @@
function copyToClipboard(container) {
const el = document.createElement('textarea');
el.value = container.textContent;
document.body.appendChild(el);
el.select();
document.execCommand('copy');
document.body.removeChild(el);
}
function setupCodeCopy() {
$('pre.highlight').prepend('<div class="copy-clipboard"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>Copy to Clipboard</title><path d="M18 6v-6h-18v18h6v6h18v-18h-6zm-12 10h-4v-14h14v4h-10v10zm16 6h-14v-14h14v14z"></path></svg></div>');
$('.copy-clipboard').on('click', function() {
copyToClipboard(this.parentNode.children[1]);
});
}

View File

@@ -7,7 +7,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
@@ -15,13 +15,14 @@ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
*/
(function (global) {
;(function () {
'use strict';
var languages = [];
global.setupLanguages = setupLanguages;
global.activateLanguage = activateLanguage;
window.setupLanguages = setupLanguages;
window.activateLanguage = activateLanguage;
window.getLanguageFromQueryString = getLanguageFromQueryString;
function activateLanguage(language) {
if (!language) return;
@@ -36,7 +37,7 @@ under the License.
$(".highlight.tab-" + language).show();
$(".lang-specific." + language).show();
global.toc.calculateHeights();
window.recacheHeights();
// scroll to the new location of the position
if ($(window.location.hash).get(0)) {
@@ -65,7 +66,7 @@ under the License.
key = decodeURIComponent(key);
// missing `=` should be `null`:
// https://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
// http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
val = val === undefined ? null : decodeURIComponent(val);
if (!ret.hasOwnProperty(key)) {
@@ -97,7 +98,7 @@ under the License.
// gets the language set in the query string
function getLanguageFromQueryString() {
if (location.search.length >= 1) {
var language = parseURL(location.search).language
var language = parseURL(location.search).language;
if (language) {
return language;
} else if (jQuery.inArray(location.search.substr(1), languages) != -1) {
@@ -159,8 +160,5 @@ under the License.
activateLanguage(language);
return false;
});
window.onpopstate = function() {
activateLanguage(getLanguageFromQueryString());
};
});
})(window);
})();

View File

@@ -1,50 +1,76 @@
//= require ../lib/_lunr
//= require ../lib/_jquery
//= require ../lib/_jquery.highlight
(function () {
;(function () {
'use strict';
var content, searchResults;
var highlightOpts = { element: 'span', className: 'search-highlight' };
var searchDelay = 0;
var timeoutHandle = 0;
var index;
var index = new lunr.Index();
function populate() {
index = lunr(function(){
index.ref('id');
index.field('title', { boost: 10 });
index.field('body');
index.pipeline.add(lunr.trimmer, lunr.stopWordFilter);
this.ref('id');
this.field('title', { boost: 10 });
this.field('body');
this.pipeline.add(lunr.trimmer, lunr.stopWordFilter);
var lunrConfig = this;
$('h1, h2').each(function() {
var title = $(this);
var body = title.nextUntil('h1, h2');
lunrConfig.add({
id: title.prop('id'),
title: title.text(),
body: body.text()
});
});
});
determineSearchDelay();
}
$(populate);
$(bind);
function populate() {
$('h1, h2').each(function() {
var title = $(this);
var body = title.nextUntil('h1, h2');
index.add({
id: title.prop('id'),
title: title.text(),
body: body.text()
});
});
function determineSearchDelay() {
if (index.tokenSet.toArray().length>5000) {
searchDelay = 300;
}
}
function bind() {
content = $('.content');
searchResults = $('.search-results');
$('#input-search').on('keyup', search);
$('#input-search').on('keyup',function(e) {
var wait = function() {
return function(executingFunction, waitTime){
clearTimeout(timeoutHandle);
timeoutHandle = setTimeout(executingFunction, waitTime);
};
}();
wait(function(){
search(e);
}, searchDelay);
});
}
function search(event) {
var searchInput = $('#input-search')[0];
unhighlight();
searchResults.addClass('visible');
// ESC clears the field
if (event.keyCode === 27) this.value = '';
if (event.keyCode === 27) searchInput.value = '';
if (this.value) {
var results = index.search(this.value).filter(function(r) {
if (searchInput.value) {
var results = index.search(searchInput.value).filter(function(r) {
return r.score > 0.0001;
});
@@ -54,10 +80,10 @@
var elem = document.getElementById(result.ref);
searchResults.append("<li><a href='#" + result.ref + "'>" + $(elem).text() + "</a></li>");
});
highlight.call(this);
highlight.call(searchInput);
} else {
searchResults.html('<li></li>');
$('.search-results li').text('No Results Found for "' + this.value + '"');
$('.search-results li').text('No Results Found for "' + searchInput.value + '"');
}
} else {
unhighlight();
@@ -73,3 +99,4 @@
content.unhighlight(highlightOpts);
}
})();

View File

@@ -1,57 +1,122 @@
//= require ../lib/_jquery
//= require ../lib/_jquery_ui
//= require ../lib/_jquery.tocify
//= require ../lib/_imagesloaded.min
(function (global) {
;(function () {
'use strict';
var htmlPattern = /<[^>]*>/g;
var loaded = false;
var debounce = function(func, waitTime) {
var timeout = false;
return function() {
if (timeout === false) {
setTimeout(function() {
func();
timeout = false;
}, waitTime);
timeout = true;
}
};
};
var closeToc = function() {
$(".tocify-wrapper").removeClass('open');
$(".toc-wrapper").removeClass('open');
$("#nav-button").removeClass('open');
};
var makeToc = function() {
global.toc = $("#toc").tocify({
selectors: 'h1, h2',
extendPage: false,
theme: 'none',
smoothScroll: false,
showEffectSpeed: 0,
hideEffectSpeed: 180,
ignoreSelector: '.toc-ignore',
highlightOffset: 60,
scrollTo: -1,
scrollHistory: true,
hashGenerator: function (text, element) {
return element.prop('id');
function loadToc($toc, tocLinkSelector, tocListSelector, scrollOffset) {
var headerHeights = {};
var pageHeight = 0;
var windowHeight = 0;
var originalTitle = document.title;
var recacheHeights = function() {
headerHeights = {};
pageHeight = $(document).height();
windowHeight = $(window).height();
$toc.find(tocLinkSelector).each(function() {
var targetId = $(this).attr('href');
if (targetId[0] === "#") {
headerHeights[targetId] = $("#" + $.escapeSelector(targetId.substring(1))).offset().top;
}
});
};
var refreshToc = function() {
var currentTop = $(document).scrollTop() + scrollOffset;
if (currentTop + windowHeight >= pageHeight) {
// at bottom of page, so just select last header by making currentTop very large
// this fixes the problem where the last header won't ever show as active if its content
// is shorter than the window height
currentTop = pageHeight + 1000;
}
}).data('toc-tocify');
$("#nav-button").click(function() {
$(".tocify-wrapper").toggleClass('open');
$("#nav-button").toggleClass('open');
return false;
});
var best = null;
for (var name in headerHeights) {
if ((headerHeights[name] < currentTop && headerHeights[name] > headerHeights[best]) || best === null) {
best = name;
}
}
$(".page-wrapper").click(closeToc);
$(".tocify-item").click(closeToc);
};
// Catch the initial load case
if (currentTop == scrollOffset && !loaded) {
best = window.location.hash;
loaded = true;
}
// Hack to make already open sections to start opened,
// instead of displaying an ugly animation
function animate() {
setTimeout(function() {
toc.setOption('showEffectSpeed', 180);
}, 50);
var $best = $toc.find("[href='" + best + "']").first();
if (!$best.hasClass("active")) {
// .active is applied to the ToC link we're currently on, and its parent <ul>s selected by tocListSelector
// .active-expanded is applied to the ToC links that are parents of this one
$toc.find(".active").removeClass("active");
$toc.find(".active-parent").removeClass("active-parent");
$best.addClass("active");
$best.parents(tocListSelector).addClass("active").siblings(tocLinkSelector).addClass('active-parent');
$best.siblings(tocListSelector).addClass("active");
$toc.find(tocListSelector).filter(":not(.active)").slideUp(150);
$toc.find(tocListSelector).filter(".active").slideDown(150);
if (window.history.replaceState) {
window.history.replaceState(null, "", best);
}
var thisTitle = $best.data("title");
if (thisTitle !== undefined && thisTitle.length > 0) {
document.title = thisTitle.replace(htmlPattern, "") + " " + originalTitle;
} else {
document.title = originalTitle;
}
}
};
var makeToc = function() {
recacheHeights();
refreshToc();
$("#nav-button").click(function() {
$(".toc-wrapper").toggleClass('open');
$("#nav-button").toggleClass('open');
return false;
});
$(".page-wrapper").click(closeToc);
$(".toc-link").click(closeToc);
// reload immediately after scrolling on toc click
$toc.find(tocLinkSelector).click(function() {
setTimeout(function() {
refreshToc();
}, 0);
});
$(window).scroll(debounce(refreshToc, 200));
$(window).resize(debounce(recacheHeights, 200));
};
makeToc();
window.recacheHeights = recacheHeights;
window.refreshToc = refreshToc;
}
$(function() {
makeToc();
animate();
setupLanguages($('body').data('languages'));
$('.content').imagesLoaded( function() {
global.toc.calculateHeights();
});
});
})(window);
window.loadToc = loadToc;
})();

View File

@@ -115,7 +115,7 @@
/**
* Special logic for standalone web apps
* See https://stackoverflow.com/questions/2898740/iphone-safari-web-app-opens-links-in-new-window
* See http://stackoverflow.com/questions/2898740/iphone-safari-web-app-opens-links-in-new-window
*/
if(standAlone) {
window.location = target.getAttribute("href");

File diff suppressed because one or more lines are too long

View File

@@ -2,7 +2,7 @@
* jQuery Highlight plugin
*
* Based on highlight v3 by Johann Burkard
* https://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
* http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
*
* Code a little bit refactored and cleaned (in my humble opinion).
* Most important changes:

File diff suppressed because it is too large Load Diff

View File

@@ -1,566 +0,0 @@
/*! jQuery UI - v1.11.3 - 2015-02-12
* https://jqueryui.com
* Includes: widget.js
* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
// AMD. Register as an anonymous module.
define([ "jquery" ], factory );
} else {
// Browser globals
factory( jQuery );
}
}(function( $ ) {
/*!
* jQuery UI Widget 1.11.3
* https://jqueryui.com
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license.
* https://jquery.org/license
*
* https://api.jqueryui.com/jQuery.widget/
*/
var widget_uuid = 0,
widget_slice = Array.prototype.slice;
$.cleanData = (function( orig ) {
return function( elems ) {
var events, elem, i;
for ( i = 0; (elem = elems[i]) != null; i++ ) {
try {
// Only trigger remove when necessary to save time
events = $._data( elem, "events" );
if ( events && events.remove ) {
$( elem ).triggerHandler( "remove" );
}
// https://bugs.jquery.com/ticket/8235
} catch ( e ) {}
}
orig( elems );
};
})( $.cleanData );
$.widget = function( name, base, prototype ) {
var fullName, existingConstructor, constructor, basePrototype,
// proxiedPrototype allows the provided prototype to remain unmodified
// so that it can be used as a mixin for multiple widgets (#8876)
proxiedPrototype = {},
namespace = name.split( "." )[ 0 ];
name = name.split( "." )[ 1 ];
fullName = namespace + "-" + name;
if ( !prototype ) {
prototype = base;
base = $.Widget;
}
// create selector for plugin
$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
return !!$.data( elem, fullName );
};
$[ namespace ] = $[ namespace ] || {};
existingConstructor = $[ namespace ][ name ];
constructor = $[ namespace ][ name ] = function( options, element ) {
// allow instantiation without "new" keyword
if ( !this._createWidget ) {
return new constructor( options, element );
}
// allow instantiation without initializing for simple inheritance
// must use "new" keyword (the code above always passes args)
if ( arguments.length ) {
this._createWidget( options, element );
}
};
// extend with the existing constructor to carry over any static properties
$.extend( constructor, existingConstructor, {
version: prototype.version,
// copy the object used to create the prototype in case we need to
// redefine the widget later
_proto: $.extend( {}, prototype ),
// track widgets that inherit from this widget in case this widget is
// redefined after a widget inherits from it
_childConstructors: []
});
basePrototype = new base();
// we need to make the options hash a property directly on the new instance
// otherwise we'll modify the options hash on the prototype that we're
// inheriting from
basePrototype.options = $.widget.extend( {}, basePrototype.options );
$.each( prototype, function( prop, value ) {
if ( !$.isFunction( value ) ) {
proxiedPrototype[ prop ] = value;
return;
}
proxiedPrototype[ prop ] = (function() {
var _super = function() {
return base.prototype[ prop ].apply( this, arguments );
},
_superApply = function( args ) {
return base.prototype[ prop ].apply( this, args );
};
return function() {
var __super = this._super,
__superApply = this._superApply,
returnValue;
this._super = _super;
this._superApply = _superApply;
returnValue = value.apply( this, arguments );
this._super = __super;
this._superApply = __superApply;
return returnValue;
};
})();
});
constructor.prototype = $.widget.extend( basePrototype, {
// TODO: remove support for widgetEventPrefix
// always use the name + a colon as the prefix, e.g., draggable:start
// don't prefix for widgets that aren't DOM-based
widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
}, proxiedPrototype, {
constructor: constructor,
namespace: namespace,
widgetName: name,
widgetFullName: fullName
});
// If this widget is being redefined then we need to find all widgets that
// are inheriting from it and redefine all of them so that they inherit from
// the new version of this widget. We're essentially trying to replace one
// level in the prototype chain.
if ( existingConstructor ) {
$.each( existingConstructor._childConstructors, function( i, child ) {
var childPrototype = child.prototype;
// redefine the child widget using the same prototype that was
// originally used, but inherit from the new version of the base
$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
});
// remove the list of existing child constructors from the old constructor
// so the old child constructors can be garbage collected
delete existingConstructor._childConstructors;
} else {
base._childConstructors.push( constructor );
}
$.widget.bridge( name, constructor );
return constructor;
};
$.widget.extend = function( target ) {
var input = widget_slice.call( arguments, 1 ),
inputIndex = 0,
inputLength = input.length,
key,
value;
for ( ; inputIndex < inputLength; inputIndex++ ) {
for ( key in input[ inputIndex ] ) {
value = input[ inputIndex ][ key ];
if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
// Clone objects
if ( $.isPlainObject( value ) ) {
target[ key ] = $.isPlainObject( target[ key ] ) ?
$.widget.extend( {}, target[ key ], value ) :
// Don't extend strings, arrays, etc. with objects
$.widget.extend( {}, value );
// Copy everything else by reference
} else {
target[ key ] = value;
}
}
}
}
return target;
};
$.widget.bridge = function( name, object ) {
var fullName = object.prototype.widgetFullName || name;
$.fn[ name ] = function( options ) {
var isMethodCall = typeof options === "string",
args = widget_slice.call( arguments, 1 ),
returnValue = this;
if ( isMethodCall ) {
this.each(function() {
var methodValue,
instance = $.data( this, fullName );
if ( options === "instance" ) {
returnValue = instance;
return false;
}
if ( !instance ) {
return $.error( "cannot call methods on " + name + " prior to initialization; " +
"attempted to call method '" + options + "'" );
}
if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
return $.error( "no such method '" + options + "' for " + name + " widget instance" );
}
methodValue = instance[ options ].apply( instance, args );
if ( methodValue !== instance && methodValue !== undefined ) {
returnValue = methodValue && methodValue.jquery ?
returnValue.pushStack( methodValue.get() ) :
methodValue;
return false;
}
});
} else {
// Allow multiple hashes to be passed on init
if ( args.length ) {
options = $.widget.extend.apply( null, [ options ].concat(args) );
}
this.each(function() {
var instance = $.data( this, fullName );
if ( instance ) {
instance.option( options || {} );
if ( instance._init ) {
instance._init();
}
} else {
$.data( this, fullName, new object( options, this ) );
}
});
}
return returnValue;
};
};
$.Widget = function( /* options, element */ ) {};
$.Widget._childConstructors = [];
$.Widget.prototype = {
widgetName: "widget",
widgetEventPrefix: "",
defaultElement: "<div>",
options: {
disabled: false,
// callbacks
create: null
},
_createWidget: function( options, element ) {
element = $( element || this.defaultElement || this )[ 0 ];
this.element = $( element );
this.uuid = widget_uuid++;
this.eventNamespace = "." + this.widgetName + this.uuid;
this.bindings = $();
this.hoverable = $();
this.focusable = $();
if ( element !== this ) {
$.data( element, this.widgetFullName, this );
this._on( true, this.element, {
remove: function( event ) {
if ( event.target === element ) {
this.destroy();
}
}
});
this.document = $( element.style ?
// element within the document
element.ownerDocument :
// element is window or document
element.document || element );
this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
}
this.options = $.widget.extend( {},
this.options,
this._getCreateOptions(),
options );
this._create();
this._trigger( "create", null, this._getCreateEventData() );
this._init();
},
_getCreateOptions: $.noop,
_getCreateEventData: $.noop,
_create: $.noop,
_init: $.noop,
destroy: function() {
this._destroy();
// we can probably remove the unbind calls in 2.0
// all event bindings should go through this._on()
this.element
.unbind( this.eventNamespace )
.removeData( this.widgetFullName )
// support: jquery <1.6.3
// https://bugs.jquery.com/ticket/9413
.removeData( $.camelCase( this.widgetFullName ) );
this.widget()
.unbind( this.eventNamespace )
.removeAttr( "aria-disabled" )
.removeClass(
this.widgetFullName + "-disabled " +
"ui-state-disabled" );
// clean up events and states
this.bindings.unbind( this.eventNamespace );
this.hoverable.removeClass( "ui-state-hover" );
this.focusable.removeClass( "ui-state-focus" );
},
_destroy: $.noop,
widget: function() {
return this.element;
},
option: function( key, value ) {
var options = key,
parts,
curOption,
i;
if ( arguments.length === 0 ) {
// don't return a reference to the internal hash
return $.widget.extend( {}, this.options );
}
if ( typeof key === "string" ) {
// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
options = {};
parts = key.split( "." );
key = parts.shift();
if ( parts.length ) {
curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
for ( i = 0; i < parts.length - 1; i++ ) {
curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
curOption = curOption[ parts[ i ] ];
}
key = parts.pop();
if ( arguments.length === 1 ) {
return curOption[ key ] === undefined ? null : curOption[ key ];
}
curOption[ key ] = value;
} else {
if ( arguments.length === 1 ) {
return this.options[ key ] === undefined ? null : this.options[ key ];
}
options[ key ] = value;
}
}
this._setOptions( options );
return this;
},
_setOptions: function( options ) {
var key;
for ( key in options ) {
this._setOption( key, options[ key ] );
}
return this;
},
_setOption: function( key, value ) {
this.options[ key ] = value;
if ( key === "disabled" ) {
this.widget()
.toggleClass( this.widgetFullName + "-disabled", !!value );
// If the widget is becoming disabled, then nothing is interactive
if ( value ) {
this.hoverable.removeClass( "ui-state-hover" );
this.focusable.removeClass( "ui-state-focus" );
}
}
return this;
},
enable: function() {
return this._setOptions({ disabled: false });
},
disable: function() {
return this._setOptions({ disabled: true });
},
_on: function( suppressDisabledCheck, element, handlers ) {
var delegateElement,
instance = this;
// no suppressDisabledCheck flag, shuffle arguments
if ( typeof suppressDisabledCheck !== "boolean" ) {
handlers = element;
element = suppressDisabledCheck;
suppressDisabledCheck = false;
}
// no element argument, shuffle and use this.element
if ( !handlers ) {
handlers = element;
element = this.element;
delegateElement = this.widget();
} else {
element = delegateElement = $( element );
this.bindings = this.bindings.add( element );
}
$.each( handlers, function( event, handler ) {
function handlerProxy() {
// allow widgets to customize the disabled handling
// - disabled as an array instead of boolean
// - disabled class as method for disabling individual parts
if ( !suppressDisabledCheck &&
( instance.options.disabled === true ||
$( this ).hasClass( "ui-state-disabled" ) ) ) {
return;
}
return ( typeof handler === "string" ? instance[ handler ] : handler )
.apply( instance, arguments );
}
// copy the guid so direct unbinding works
if ( typeof handler !== "string" ) {
handlerProxy.guid = handler.guid =
handler.guid || handlerProxy.guid || $.guid++;
}
var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
eventName = match[1] + instance.eventNamespace,
selector = match[2];
if ( selector ) {
delegateElement.delegate( selector, eventName, handlerProxy );
} else {
element.bind( eventName, handlerProxy );
}
});
},
_off: function( element, eventName ) {
eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
this.eventNamespace;
element.unbind( eventName ).undelegate( eventName );
// Clear the stack to avoid memory leaks (#10056)
this.bindings = $( this.bindings.not( element ).get() );
this.focusable = $( this.focusable.not( element ).get() );
this.hoverable = $( this.hoverable.not( element ).get() );
},
_delay: function( handler, delay ) {
function handlerProxy() {
return ( typeof handler === "string" ? instance[ handler ] : handler )
.apply( instance, arguments );
}
var instance = this;
return setTimeout( handlerProxy, delay || 0 );
},
_hoverable: function( element ) {
this.hoverable = this.hoverable.add( element );
this._on( element, {
mouseenter: function( event ) {
$( event.currentTarget ).addClass( "ui-state-hover" );
},
mouseleave: function( event ) {
$( event.currentTarget ).removeClass( "ui-state-hover" );
}
});
},
_focusable: function( element ) {
this.focusable = this.focusable.add( element );
this._on( element, {
focusin: function( event ) {
$( event.currentTarget ).addClass( "ui-state-focus" );
},
focusout: function( event ) {
$( event.currentTarget ).removeClass( "ui-state-focus" );
}
});
},
_trigger: function( type, event, data ) {
var prop, orig,
callback = this.options[ type ];
data = data || {};
event = $.Event( event );
event.type = ( type === this.widgetEventPrefix ?
type :
this.widgetEventPrefix + type ).toLowerCase();
// the original event may come from any element
// so we need to reset the target on the new event
event.target = this.element[ 0 ];
// copy original event properties over to the new event
orig = event.originalEvent;
if ( orig ) {
for ( prop in orig ) {
if ( !( prop in event ) ) {
event[ prop ] = orig[ prop ];
}
}
}
this.element.trigger( event, data );
return !( $.isFunction( callback ) &&
callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
event.isDefaultPrevented() );
}
};
$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
if ( typeof options === "string" ) {
options = { effect: options };
}
var hasOptions,
effectName = !options ?
method :
options === true || typeof options === "number" ?
defaultEffect :
options.effect || defaultEffect;
options = options || {};
if ( typeof options === "number" ) {
options = { duration: options };
}
hasOptions = !$.isEmptyObject( options );
options.complete = callback;
if ( options.delay ) {
element.delay( options.delay );
}
if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
element[ method ]( options );
} else if ( effectName !== method && element[ effectName ] ) {
element[ effectName ]( options.duration, options.easing, callback );
} else {
element.queue(function( next ) {
$( this )[ method ]();
if ( callback ) {
callback.call( element[ 0 ] );
}
next();
});
}
};
});
var widget = $.widget;
}));

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
@@ -14,6 +14,15 @@ License for the specific language governing permissions and limitations
under the License.
%>
<% language_tabs = current_page.data.language_tabs || [] %>
<% page_content = yield %>
<%
if current_page.data.includes
current_page.data.includes.each do |include|
page_content += partial("includes/#{include}")
end
end
%>
<!doctype html>
<html>
<head>
@@ -22,8 +31,14 @@ under the License.
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title><%= current_page.data.title || "API Documentation" %></title>
<style>
<%= Rouge::Themes::MonokaiSublime.render(:scope => '.highlight') %>
<style media="screen">
<%= Rouge::Themes::MonokaiSublimeSlate.render(:scope => '.highlight') %>
</style>
<style media="print">
* {
transition:none!important;
}
<%= Rouge::Themes::Base16::Solarized.render(:scope => '.highlight') %>
</style>
<%= stylesheet_link_tag :screen, media: :screen %>
<%= stylesheet_link_tag :print, media: :print %>
@@ -32,6 +47,12 @@ under the License.
<% else %>
<%= javascript_include_tag "all_nosearch" %>
<% end %>
<% if current_page.data.code_clipboard %>
<script>
$(function() { setupCodeCopy(); });
</script>
<% end %>
</head>
<body class="<%= page_classes %>" data-languages="<%=h language_tabs.map{ |lang| lang.is_a?(Hash) ? lang.keys.first : lang }.to_json %>">
@@ -41,8 +62,8 @@ under the License.
<%= image_tag('navbar.png') %>
</span>
</a>
<div class="tocify-wrapper">
<%= image_tag "logo.png" %>
<div class="toc-wrapper">
<%= image_tag "logo.png", class: 'logo' %>
<% if language_tabs.any? %>
<div class="lang-selector">
<% language_tabs.each do |lang| %>
@@ -60,8 +81,22 @@ under the License.
</div>
<ul class="search-results"></ul>
<% end %>
<div id="toc">
</div>
<ul id="toc" class="toc-list-h1">
<% toc_data(page_content).each do |h1| %>
<li>
<a href="#<%= h1[:id] %>" class="toc-h1 toc-link" data-title="<%= h1[:title] %>"><%= h1[:content] %></a>
<% if h1[:children].length > 0 %>
<ul class="toc-list-h2">
<% h1[:children].each do |h2| %>
<li>
<a href="#<%= h2[:id] %>" class="toc-h2 toc-link" data-title="<%= h2[:title] %>"><%= h2[:content] %></a>
</li>
<% end %>
</ul>
<% end %>
</li>
<% end %>
</ul>
<% if current_page.data.toc_footers %>
<ul class="toc-footer">
<% current_page.data.toc_footers.each do |footer| %>
@@ -73,10 +108,7 @@ under the License.
<div class="page-wrapper">
<div class="dark-box"></div>
<div class="content">
<%= yield %>
<% current_page.data.includes && current_page.data.includes.each do |include| %>
<%= partial "includes/#{include}" %>
<% end %>
<%= page_content %>
</div>
<div class="dark-box">
<% if language_tabs.any? %>

View File

@@ -0,0 +1,140 @@
////////////////////////////////////////////////////////////////////////////////
// RTL Styles Variables
////////////////////////////////////////////////////////////////////////////////
$default: auto;
////////////////////////////////////////////////////////////////////////////////
// TABLE OF CONTENTS
////////////////////////////////////////////////////////////////////////////////
#toc>ul>li>a>span {
float: left;
}
.toc-wrapper {
transition: right 0.3s ease-in-out !important;
left: $default !important;
#{right}: 0;
}
.toc-h2 {
padding-#{right}: $nav-padding + $nav-indent;
}
#nav-button {
#{right}: 0;
transition: right 0.3s ease-in-out;
&.open {
right: $nav-width
}
}
////////////////////////////////////////////////////////////////////////////////
// PAGE LAYOUT AND CODE SAMPLE BACKGROUND
////////////////////////////////////////////////////////////////////////////////
.page-wrapper {
margin-#{left}: $default !important;
margin-#{right}: $nav-width;
.dark-box {
#{right}: $default;
#{left}: 0;
}
}
.lang-selector {
width: $default !important;
a {
float: right;
}
}
////////////////////////////////////////////////////////////////////////////////
// CODE SAMPLE STYLES
////////////////////////////////////////////////////////////////////////////////
.content {
&>h1,
&>h2,
&>h3,
&>h4,
&>h5,
&>h6,
&>p,
&>table,
&>ul,
&>ol,
&>aside,
&>dl {
margin-#{left}: $examples-width;
margin-#{right}: $default !important;
}
&>ul,
&>ol {
padding-#{right}: $main-padding + 15px;
}
table {
th,
td {
text-align: right;
}
}
dd {
margin-#{right}: 15px;
}
aside {
aside:before {
padding-#{left}: 0.5em;
}
.search-highlight {
background: linear-gradient(to top right, #F7E633 0%, #F1D32F 100%);
}
}
pre,
blockquote {
float: left !important;
clear: left !important;
}
}
////////////////////////////////////////////////////////////////////////////////
// TYPOGRAPHY
////////////////////////////////////////////////////////////////////////////////
h1,
h2,
h3,
h4,
h5,
h6,
p,
aside {
text-align: right;
direction: rtl;
}
.toc-wrapper {
text-align: right;
direction: rtl;
font-weight: 100 !important;
}
////////////////////////////////////////////////////////////////////////////////
// RESPONSIVE DESIGN
////////////////////////////////////////////////////////////////////////////////
@media (max-width: $tablet-width) {
.toc-wrapper {
#{right}: -$nav-width;
&.open {
#{right}: 0;
}
}
.page-wrapper {
margin-#{right}: 0;
}
}
@media (max-width: $phone-width) {
%left-col {
margin-#{left}: 0;
}
}

View File

@@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
@@ -23,17 +23,18 @@ under the License.
// BACKGROUND COLORS
////////////////////
$nav-bg: #393939 !default;
$examples-bg: #393939 !default;
$code-bg: #292929 !default;
$code-annotation-bg: #1c1c1c !default;
$nav-subitem-bg: #262626 !default;
$nav-active-bg: #2467af !default;
$nav-bg: #2E3336 !default;
$examples-bg: #2E3336 !default;
$code-bg: #1E2224 !default;
$code-annotation-bg: #191D1F !default;
$nav-subitem-bg: #1E2224 !default;
$nav-active-bg: #0F75D4 !default;
$nav-active-parent-bg: #1E2224 !default; // parent links of the current section
$lang-select-border: #000 !default;
$lang-select-bg: #222 !default;
$lang-select-bg: #1E2224 !default;
$lang-select-active-bg: $examples-bg !default; // feel free to change this to blue or something
$lang-select-pressed-bg: #111 !default; // color of language tab bg when mouse is pressed
$main-bg: #eaf2f6 !default;
$main-bg: #F3F7F9 !default;
$aside-notice-bg: #8fbcd4 !default;
$aside-warning-bg: #c97a7e !default;
$aside-success-bg: #6ac174 !default;
@@ -45,6 +46,7 @@ $search-notice-bg: #c97a7e !default;
$main-text: #333 !default; // main content text color
$nav-text: #fff !default;
$nav-active-text: #fff !default;
$nav-active-parent-text: #fff !default; // parent links of the current section
$lang-select-text: #fff !default; // color of unselected language tab text
$lang-select-active-text: #fff !default; // color of selected language tab text
$lang-select-pressed-text: #fff !default; // color of language tab text when mouse is pressed
@@ -54,7 +56,7 @@ $lang-select-pressed-text: #fff !default; // color of language tab text when mou
////////////////////
$nav-width: 230px !default; // width of the navbar
$examples-width: 50% !default; // portion of the screen taken up by code examples
$logo-margin: 20px !default; // margin between nav items and logo, ignored if search is active
$logo-margin: 0px !default; // margin below logo
$main-padding: 28px !default; // padding to left and right of content & examples
$nav-padding: 15px !default; // padding to left and right of navbar
$nav-v-padding: 10px !default; // padding used vertically around search boxes and results
@@ -68,8 +70,8 @@ $phone-width: $tablet-width - $nav-width !default; // min width before reverting
// FONTS
////////////////////
%default-font {
font-family: "Helvetica Neue", Helvetica, Arial, "Microsoft Yahei","微软雅黑", STXihei, "华文细黑", sans-serif;
font-size: 13px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-size: 14px;
}
%header-font {
@@ -86,11 +88,7 @@ $phone-width: $tablet-width - $nav-width !default; // min width before reverting
// OTHER
////////////////////
$nav-active-shadow: #000 !default;
$nav-footer-border-color: #666 !default;
$nav-embossed-border-top: #000 !default;
$nav-embossed-border-bottom: #939393 !default;
$main-embossed-text-shadow: 0px 1px 0px #fff !default;
$search-box-border-color: #666 !default;

View File

@@ -10,7 +10,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
@@ -144,4 +144,10 @@ body {
aside.success:before {
@extend %icon-ok-sign;
}
}
}
.copy-clipboard {
@media print {
display: none
}
}

View File

@@ -2,6 +2,7 @@
@import 'normalize';
@import 'variables';
@import 'icon-font';
// @import 'rtl'; // uncomment to switch to RTL format
/*
Copyright 2008-2013 Concur Technologies, Inc.
@@ -10,7 +11,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
@@ -46,16 +47,7 @@ html, body {
width: 20px;
}
@mixin embossed-bg {
background:
linear-gradient(to bottom, rgba(#000, 0.2), rgba(#000, 0) 8px),
linear-gradient(to top, rgba(#000, 0.2), rgba(#000, 0) 8px),
linear-gradient(to bottom, rgba($nav-embossed-border-top, 1), rgba($nav-embossed-border-top, 0) 1.5px),
linear-gradient(to top, rgba($nav-embossed-border-bottom, 1), rgba($nav-embossed-border-bottom, 0) 1.5px),
$nav-subitem-bg;
}
.tocify-wrapper {
.toc-wrapper {
transition: left 0.3s ease-in-out;
overflow-y: auto;
@@ -80,9 +72,10 @@ html, body {
}
// This is the logo at the top of the ToC
&>img {
.logo {
display: block;
max-width: 100%;
margin-bottom: $logo-margin;
}
&>.search {
@@ -95,7 +88,7 @@ html, body {
padding: 6px 0 6px 20px;
box-sizing: border-box;
margin: $nav-v-padding $nav-padding;
width: $nav-width - 30;
width: $nav-width - ($nav-padding*2);
outline: none;
color: $nav-text;
border-radius: 0; /* ios has a default border radius */
@@ -110,10 +103,6 @@ html, body {
}
}
img+.tocify, .lang-selector+.tocify {
margin-top: $logo-margin;
}
.search-results {
margin-top: 0;
box-sizing: border-box;
@@ -123,13 +112,12 @@ html, body {
transition-property: height, margin;
transition-duration: 180ms;
transition-timing-function: ease-in-out;
background: $nav-subitem-bg;
&.visible {
height: 30%;
margin-bottom: 1em;
}
@include embossed-bg;
li {
margin: 1em $nav-padding;
line-height: 1;
@@ -146,14 +134,6 @@ html, body {
}
.tocify-item>a, .toc-footer li {
padding: 0 $nav-padding 0 $nav-padding;
display: block;
overflow-x: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
// The Table of Contents is composed of multiple nested
// unordered lists. These styles remove the default
// styling of an unordered list because it is ugly.
@@ -168,32 +148,30 @@ html, body {
color: $nav-text;
transition-property: background;
transition-timing-function: linear;
transition-duration: 230ms;
transition-duration: 200ms;
}
// This is the currently selected ToC entry
.tocify-focus {
box-shadow: 0px 1px 0px $nav-active-shadow;
.toc-link.active {
background-color: $nav-active-bg;
color: $nav-active-text;
}
// Subheaders are the submenus that slide open
// in the table of contents.
.tocify-subheader {
display: none; // tocify will override this when needed
// this is parent links of the currently selected ToC entry
.toc-link.active-parent {
background-color: $nav-active-parent-bg;
color: $nav-active-parent-text;
}
.toc-list-h2 {
display: none;
background-color: $nav-subitem-bg;
font-weight: 500;
.tocify-item>a {
padding-left: $nav-padding + $nav-indent;
font-size: 12px;
}
}
// for embossed look:
@include embossed-bg;
&>li:last-child {
box-shadow: none; // otherwise it'll overflow out of the subheader
}
.toc-h2 {
padding-left: $nav-padding + $nav-indent;
font-size: 12px;
}
.toc-footer {
@@ -216,7 +194,19 @@ html, body {
text-decoration: none;
}
}
}
.toc-link, .toc-footer li {
padding: 0 $nav-padding 0 $nav-padding;
display: block;
overflow-x: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-decoration: none;
color: $nav-text;
transition-property: background;
transition-timing-function: linear;
transition-duration: 130ms;
}
// button to show navigation on mobile devices
@@ -288,12 +278,13 @@ html, body {
}
.lang-selector {
display: flex;
background-color: $lang-select-bg;
width: 100%;
font-weight: bold;
overflow-x: auto;
a {
display: block;
float:left;
display: inline;
color: $lang-select-text;
text-decoration: none;
padding: 0 10px;
@@ -324,6 +315,8 @@ html, body {
// This is all the stuff with the light background in the left half of the page
.content {
// fixes webkit rendering bug for some: see #538
-webkit-transform: translateZ(0);
// to place content above the dark box
position: relative;
z-index: 30;
@@ -339,7 +332,6 @@ html, body {
padding: 0 $main-padding;
box-sizing: border-box;
display: block;
text-shadow: $main-embossed-text-shadow;
@extend %left-col;
}
@@ -355,14 +347,14 @@ html, body {
h1 {
@extend %header-font;
font-size: 30px;
font-size: 25px;
padding-top: 0.5em;
padding-bottom: 0.5em;
border-bottom: 1px solid #ccc;
margin-bottom: $h1-margin-bottom;
margin-top: 2em;
border-top: 1px solid #ddd;
background-image: linear-gradient(to bottom, #fff, #f9f9f9);
border-top: 1px solid #ccc;
border-bottom: 1px solid #ccc;
background-color: #fdfdfd;
}
h1:first-child, div:first-child + h1 {
@@ -372,13 +364,13 @@ html, body {
h2 {
@extend %header-font;
font-size: 20px;
font-size: 19px;
margin-top: 4em;
margin-bottom: 0;
border-top: 1px solid #ccc;
padding-top: 1.2em;
padding-bottom: 1.2em;
background-image: linear-gradient(to bottom, rgba(#fff, 0.4), rgba(#fff, 0));
background-image: linear-gradient(to bottom, rgba(#fff, 0.2), rgba(#fff, 0));
}
// h2s right after h1s should bump right up
@@ -412,6 +404,9 @@ html, body {
text-align: left;
vertical-align: top;
line-height: 1.6;
code {
white-space: nowrap;
}
}
th {
@@ -470,7 +465,6 @@ html, body {
aside {
padding-top: 1em;
padding-bottom: 1em;
text-shadow: 0 1px 0 lighten($aside-notice-bg, 15%);
margin-top: 1.5em;
margin-bottom: 1.5em;
background: $aside-notice-bg;
@@ -478,12 +472,10 @@ html, body {
&.warning {
background-color: $aside-warning-bg;
text-shadow: 0 1px 0 lighten($aside-warning-bg, 15%);
}
&.success {
background-color: $aside-success-bg;
text-shadow: 0 1px 0 lighten($aside-success-bg, 15%);
}
}
@@ -507,10 +499,9 @@ html, body {
.search-highlight {
padding: 2px;
margin: -2px;
margin: -3px;
border-radius: 4px;
border: 1px solid #F7E633;
text-shadow: 1px 1px 0 #666;
background: linear-gradient(to top left, #F7E633 0%, #F1D32F 100%);
}
}
@@ -521,11 +512,14 @@ html, body {
// This is all the stuff that appears in the right half of the page
.content {
&>div.highlight {
clear:none;
}
pre, blockquote {
background-color: $code-bg;
color: #fff;
padding: 2em $main-padding;
margin: 0;
width: $examples-width;
@@ -533,7 +527,6 @@ html, body {
clear:right;
box-sizing: border-box;
text-shadow: 0px 1px 2px rgba(0,0,0,0.4);
@extend %right-col;
@@ -548,16 +541,16 @@ html, body {
pre {
@extend %code-font;
padding-top: 2em;
padding-bottom: 2em;
padding: 2em $main-padding;
}
blockquote {
&>p {
background-color: $code-annotation-bg;
border-radius: 5px;
padding: $code-annotation-padding;
color: #ccc;
border-top: 1px solid #000;
border-bottom: 1px solid #404040;
padding: $code-annotation-padding 2em;
color: #eee;
}
}
}
@@ -569,7 +562,7 @@ html, body {
// There are also a couple styles disperesed
@media (max-width: $tablet-width) {
.tocify-wrapper {
.toc-wrapper {
left: -$nav-width;
&.open {
@@ -585,7 +578,7 @@ html, body {
display: block;
}
.tocify-wrapper .tocify-item > a {
.toc-link {
padding-top: 0.3em;
padding-bottom: 0.3em;
}
@@ -600,7 +593,7 @@ html, body {
margin-right: 0;
}
.tocify-wrapper .lang-selector {
.toc-wrapper .lang-selector {
display: block;
}
@@ -625,3 +618,16 @@ html, body {
.highlight, .highlight .w {
background-color: $code-bg;
}
.copy-clipboard {
float: right;
fill: #9DAAB6;
cursor: pointer;
opacity: 0.4;
height: 18px;
width: 18px;
}
.copy-clipboard:hover {
opacity: 0.8;
}