mirror of
https://github.com/idanoo/GoScrobble.git
synced 2024-11-21 16:11:56 +00:00
0.1.0 Split repos, Add API docs, new env vars
This commit is contained in:
parent
cf4498e8bc
commit
306bab997b
@ -25,3 +25,4 @@ GOSCROBBLE_DOMAIN=""
|
|||||||
|
|
||||||
DATA_DIRECTORY="/var/www/goscrobble-data"
|
DATA_DIRECTORY="/var/www/goscrobble-data"
|
||||||
FRONTEND_DIRECTORY="/var/www/goscrobble-web"
|
FRONTEND_DIRECTORY="/var/www/goscrobble-web"
|
||||||
|
API_DOCS_DIRECTORY="/var/www/goscrobble-api/docs/api/build"
|
||||||
|
@ -2,7 +2,7 @@ stages:
|
|||||||
- build
|
- build
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
VERSION: 0.1.001
|
VERSION: 0.1.0
|
||||||
|
|
||||||
build-go:
|
build-go:
|
||||||
image: golang:1.16
|
image: golang:1.16
|
||||||
|
@ -61,6 +61,11 @@ func main() {
|
|||||||
panic("FRONTEND_DIRECTORY required in .env")
|
panic("FRONTEND_DIRECTORY required in .env")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
goscrobble.ApiDocsDirectory = os.Getenv("API_DOCS_DIRECTORY")
|
||||||
|
if goscrobble.ApiDocsDirectory == "" {
|
||||||
|
panic("API_DOCS_DIRECTORY required in .env")
|
||||||
|
}
|
||||||
|
|
||||||
// Ignore reverse proxies
|
// Ignore reverse proxies
|
||||||
goscrobble.ReverseProxies = strings.Split(os.Getenv("REVERSE_PROXIES"), ",")
|
goscrobble.ReverseProxies = strings.Split(os.Getenv("REVERSE_PROXIES"), ",")
|
||||||
|
|
||||||
|
307
docs/api/CHANGELOG.md
Normal file
307
docs/api/CHANGELOG.md
Normal file
@ -0,0 +1,307 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
## Version 2.12.0
|
||||||
|
|
||||||
|
*November 04, 2021*
|
||||||
|
|
||||||
|
* Bump nokogiri from 1.12.3 to 1.12.5
|
||||||
|
* Bump ffi from 1.15.0 to 1.15.4
|
||||||
|
* Bump rouge from 3.26.0 to 3.26.1
|
||||||
|
* Bump middleman from 4.4.0 to 4.4.2
|
||||||
|
* Remove unnecessary files from docker images
|
||||||
|
|
||||||
|
## Version 2.11.0
|
||||||
|
|
||||||
|
*August 12, 2021*
|
||||||
|
|
||||||
|
* __[Security]__ Bump addressable transitive dependency from 2.7.0 to 2.8.0
|
||||||
|
* Support specifying custom meta tags in YAML front-matter
|
||||||
|
* Bump nokogiri from 1.11.3 to 1.12.3 (minimum supported version is 1.11.4)
|
||||||
|
* Bump middleman-autoprefixer from 2.10.1 to 3.0.0
|
||||||
|
* Bump jquery from 3.5.1 to 3.6.0
|
||||||
|
* Bump middleman from [`d180ca3`](https://github.com/middleman/middleman/commit/d180ca337202873f2601310c74ba2b6b4cf063ec) to 4.4.0
|
||||||
|
|
||||||
|
## Version 2.10.0
|
||||||
|
|
||||||
|
*April 13, 2021*
|
||||||
|
|
||||||
|
* Add support for Ruby 3.0 (thanks @shaun-scale)
|
||||||
|
* Add requirement for Git on installing dependencies
|
||||||
|
* Bump nokogiri from 1.11.2 to 1.11.3
|
||||||
|
* Bump middleman from 4.3.11 to [`d180ca3`](https://github.com/middleman/middleman/commit/d180ca337202873f2601310c74ba2b6b4cf063ec)
|
||||||
|
|
||||||
|
## Version 2.9.2
|
||||||
|
|
||||||
|
*March 30, 2021*
|
||||||
|
|
||||||
|
* __[Security]__ Bump kramdown from 2.3.0 to 2.3.1
|
||||||
|
* Bump nokogiri from 1.11.1 to 1.11.2
|
||||||
|
|
||||||
|
## Version 2.9.1
|
||||||
|
|
||||||
|
*February 27, 2021*
|
||||||
|
|
||||||
|
* Fix Slate language tabs not working if localStorage is disabled
|
||||||
|
|
||||||
|
## Version 2.9.0
|
||||||
|
|
||||||
|
*January 19, 2021*
|
||||||
|
|
||||||
|
* __Drop support for Ruby 2.3 and 2.4__
|
||||||
|
* __[Security]__ Bump nokogiri from 1.10.10 to 1.11.1
|
||||||
|
* __[Security]__ Bump redcarpet from 3.5.0 to 3.5.1
|
||||||
|
* Specify slate is not supported on Ruby 3.x
|
||||||
|
* Bump rouge from 3.24.0 to 3.26.0
|
||||||
|
|
||||||
|
## Version 2.8.0
|
||||||
|
|
||||||
|
*October 27, 2020*
|
||||||
|
|
||||||
|
* Remove last trailing newline when using the copy code button
|
||||||
|
* Rework docker image and make available at slatedocs/slate
|
||||||
|
* Improve Dockerfile layout to improve caching (thanks @micvbang)
|
||||||
|
* Bump rouge from 3.20 to 3.24
|
||||||
|
* Bump nokogiri from 1.10.9 to 1.10.10
|
||||||
|
* Bump middleman from 4.3.8 to 4.3.11
|
||||||
|
* Bump lunr.js from 2.3.8 to 2.3.9
|
||||||
|
|
||||||
|
## Version 2.7.1
|
||||||
|
|
||||||
|
*August 13, 2020*
|
||||||
|
|
||||||
|
* __[security]__ Bumped middleman from 4.3.7 to 4.3.8
|
||||||
|
|
||||||
|
_Note_: Slate uses redcarpet, not kramdown, for rendering markdown to HTML, and so was unaffected by the security vulnerability in middleman.
|
||||||
|
If you have changed slate to use kramdown, and with GFM, you may need to install the `kramdown-parser-gfm` gem.
|
||||||
|
|
||||||
|
## Version 2.7.0
|
||||||
|
|
||||||
|
*June 21, 2020*
|
||||||
|
|
||||||
|
* __[security]__ Bumped rack in Gemfile.lock from 2.2.2 to 2.2.3
|
||||||
|
* Bumped bundled jQuery from 3.2.1 to 3.5.1
|
||||||
|
* Bumped bundled lunr from 0.5.7 to 2.3.8
|
||||||
|
* Bumped imagesloaded from 3.1.8 to 4.1.4
|
||||||
|
* Bumped rouge from 3.17.0 to 3.20.0
|
||||||
|
* Bumped redcarpet from 3.4.0 to 3.5.0
|
||||||
|
* Fix color of highlighted code being unreadable when printing page
|
||||||
|
* Add clipboard icon for "Copy to Clipboard" functionality to code boxes (see note below)
|
||||||
|
* Fix handling of ToC selectors that contain punctutation (thanks @gruis)
|
||||||
|
* Fix language bar truncating languages that overflow screen width
|
||||||
|
* Strip HTML tags from ToC title before displaying it in title bar in JS (backup to stripping done in Ruby code) (thanks @atic)
|
||||||
|
|
||||||
|
To enable the new clipboard icon, you need to add `code_clipboard: true` to the frontmatter of source/index.html.md.
|
||||||
|
See [this line](https://github.com/slatedocs/slate/blame/main/source/index.html.md#L19) for an example of usage.
|
||||||
|
|
||||||
|
## Version 2.6.1
|
||||||
|
|
||||||
|
*May 30, 2020*
|
||||||
|
|
||||||
|
* __[security]__ update child dependency activesupport in Gemfile.lock to 5.4.2.3
|
||||||
|
* Update Middleman in Gemfile.lock to 4.3.7
|
||||||
|
* Replace Travis-CI with GitHub actions for continuous integration
|
||||||
|
* Replace Spectrum with GitHub discussions
|
||||||
|
|
||||||
|
## Version 2.6.0
|
||||||
|
|
||||||
|
*May 18, 2020*
|
||||||
|
|
||||||
|
__Note__: 2.5.0 was "pulled" due to a breaking bug discovered after release. It is recommended to skip it, and move straight to 2.6.0.
|
||||||
|
|
||||||
|
* Fix large whitespace gap in middle column for sections with codeblocks
|
||||||
|
* Fix highlighted code elements having a different background than rest of code block
|
||||||
|
* Change JSON keys to have a different font color than their values
|
||||||
|
* Disable asset hashing for woff and woff2 elements due to middleman bug breaking woff2 asset hashing in general
|
||||||
|
* Move Dockerfile to Debian from Alpine
|
||||||
|
* Converted repo to a [GitHub template](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-template-repository)
|
||||||
|
* Update sassc to 2.3.0 in Gemfile.lock
|
||||||
|
|
||||||
|
## Version 2.5.0
|
||||||
|
|
||||||
|
*May 8, 2020*
|
||||||
|
|
||||||
|
* __[security]__ update nokogiri to ~> 1.10.8
|
||||||
|
* Update links in example docs to https://github.com/slatedocs/slate from https://github.com/lord/slate
|
||||||
|
* Update LICENSE to include full Apache 2.0 text
|
||||||
|
* Test slate against Ruby 2.5 and 2.6 on Travis-CI
|
||||||
|
* Update Vagrantfile to use Ubuntu 18.04 (thanks @bradthurber)
|
||||||
|
* Parse arguments and flags for deploy.sh on script start, instead of potentially after building source files
|
||||||
|
* Install nodejs inside Vagrantfile (thanks @fernandoaguilar)
|
||||||
|
* Add Dockerfile for running slate (thanks @redhatxl)
|
||||||
|
* update middleman-syntax and rouge to ~>3.2
|
||||||
|
* update middleman to 4.3.6
|
||||||
|
|
||||||
|
## Version 2.4.0
|
||||||
|
|
||||||
|
*October 19, 2019*
|
||||||
|
|
||||||
|
- Move repository from lord/slate to slatedocs/slate
|
||||||
|
- Fix documentation to point at new repo link, thanks to [Arun](https://github.com/slash-arun), [Gustavo Gawryszewski](https://github.com/gawry), and [Daniel Korbit](https://github.com/danielkorbit)
|
||||||
|
- Update `nokogiri` to 1.10.4
|
||||||
|
- Update `ffi` in `Gemfile.lock` to fix security warnings, thanks to [Grey Baker](https://github.com/greysteil) and [jakemack](https://github.com/jakemack)
|
||||||
|
- Update `rack` to 2.0.7 in `Gemfile.lock` to fix security warnings, thanks to [Grey Baker](https://github.com/greysteil) and [jakemack](https://github.com/jakemack)
|
||||||
|
- Update middleman to `4.3` and relax constraints on middleman related gems, thanks to [jakemack](https://github.com/jakemack)
|
||||||
|
- Add sass gem, thanks to [jakemack](https://github.com/jakemack)
|
||||||
|
- Activate `asset_cache` in middleman to improve cacheability of static files, thanks to [Sam Gilman](https://github.com/thenengah)
|
||||||
|
- Update to using bundler 2 for `Gemfile.lock`, thanks to [jakemack](https://github.com/jakemack)
|
||||||
|
|
||||||
|
## Version 2.3.1
|
||||||
|
|
||||||
|
*July 5, 2018*
|
||||||
|
|
||||||
|
- 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*
|
||||||
|
|
||||||
|
- Add [multiple tabs per programming language](https://github.com/lord/slate/wiki/Multiple-language-tabs-per-programming-language) feature
|
||||||
|
- Upgrade Middleman to add Ruby 1.4.0 compatibility
|
||||||
|
- Switch default code highlighting color scheme to better highlight JSON
|
||||||
|
- Various small typo and bug fixes
|
||||||
|
|
||||||
|
## Version 1.4
|
||||||
|
|
||||||
|
*November 24, 2016*
|
||||||
|
|
||||||
|
- Upgrade Middleman and Rouge gems, should hopefully solve a number of bugs
|
||||||
|
- Update some links in README
|
||||||
|
- Fix broken Vagrant startup script
|
||||||
|
- Fix some problems with deploy.sh help message
|
||||||
|
- Fix bug with language tabs not hiding properly if no error
|
||||||
|
- Add `!default` to SASS variables
|
||||||
|
- Fix bug with logo margin
|
||||||
|
- Bump tested Ruby versions in .travis.yml
|
||||||
|
|
||||||
|
## Version 1.3.3
|
||||||
|
|
||||||
|
*June 11, 2016*
|
||||||
|
|
||||||
|
Documentation and example changes.
|
||||||
|
|
||||||
|
## Version 1.3.2
|
||||||
|
|
||||||
|
*February 3, 2016*
|
||||||
|
|
||||||
|
A small bugfix for slightly incorrect background colors on code samples in some cases.
|
||||||
|
|
||||||
|
## Version 1.3.1
|
||||||
|
|
||||||
|
*January 31, 2016*
|
||||||
|
|
||||||
|
A small bugfix for incorrect whitespace in code blocks.
|
||||||
|
|
||||||
|
## Version 1.3
|
||||||
|
|
||||||
|
*January 27, 2016*
|
||||||
|
|
||||||
|
We've upgraded Middleman and a number of other dependencies, which should fix quite a few bugs.
|
||||||
|
|
||||||
|
Instead of `rake build` and `rake deploy`, you should now run `bundle exec middleman build --clean` to build your server, and `./deploy.sh` to deploy it to Github Pages.
|
||||||
|
|
||||||
|
## Version 1.2
|
||||||
|
|
||||||
|
*June 20, 2015*
|
||||||
|
|
||||||
|
**Fixes:**
|
||||||
|
|
||||||
|
- Remove crash on invalid languages
|
||||||
|
- Update Tocify to scroll to the highlighted header in the Table of Contents
|
||||||
|
- Fix variable leak and update search algorithms
|
||||||
|
- Update Python examples to be valid Python
|
||||||
|
- Update gems
|
||||||
|
- More misc. bugfixes of Javascript errors
|
||||||
|
- Add Dockerfile
|
||||||
|
- Remove unused gems
|
||||||
|
- Optimize images, fonts, and generated asset files
|
||||||
|
- Add chinese font support
|
||||||
|
- Remove RedCarpet header ID patch
|
||||||
|
- Update language tabs to not disturb existing query strings
|
||||||
|
|
||||||
|
## Version 1.1
|
||||||
|
|
||||||
|
*July 27, 2014*
|
||||||
|
|
||||||
|
**Fixes:**
|
||||||
|
|
||||||
|
- Finally, a fix for the redcarpet upgrade bug
|
||||||
|
|
||||||
|
## Version 1.0
|
||||||
|
|
||||||
|
*July 2, 2014*
|
||||||
|
|
||||||
|
[View Issues](https://github.com/tripit/slate/issues?milestone=1&state=closed)
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
|
||||||
|
- Responsive designs for phones and tablets
|
||||||
|
- Started tagging versions
|
||||||
|
|
||||||
|
**Fixes:**
|
||||||
|
|
||||||
|
- Fixed 'unrecognized expression' error
|
||||||
|
- Fixed #undefined hash bug
|
||||||
|
- Fixed bug where the current language tab would be unselected
|
||||||
|
- Fixed bug where tocify wouldn't highlight the current section while searching
|
||||||
|
- Fixed bug where ids of header tags would have special characters that caused problems
|
||||||
|
- Updated layout so that pages with disabled search wouldn't load search.js
|
||||||
|
- Cleaned up Javascript
|
46
docs/api/CODE_OF_CONDUCT.md
Normal file
46
docs/api/CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to creating a positive environment include:
|
||||||
|
|
||||||
|
* Using welcoming and inclusive language
|
||||||
|
* Being respectful of differing viewpoints and experiences
|
||||||
|
* Gracefully accepting constructive criticism
|
||||||
|
* Focusing on what is best for the community
|
||||||
|
* Showing empathy towards other community members
|
||||||
|
|
||||||
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||||
|
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||||
|
|
||||||
|
## Our Responsibilities
|
||||||
|
|
||||||
|
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||||
|
|
||||||
|
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at hello@lord.io. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||||
|
|
||||||
|
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||||
|
|
||||||
|
[homepage]: http://contributor-covenant.org
|
||||||
|
[version]: http://contributor-covenant.org/version/1/4/
|
29
docs/api/Dockerfile
Normal file
29
docs/api/Dockerfile
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
FROM ruby:2.6-slim
|
||||||
|
|
||||||
|
WORKDIR /srv/slate
|
||||||
|
|
||||||
|
VOLUME /srv/slate/build
|
||||||
|
VOLUME /srv/slate/source
|
||||||
|
|
||||||
|
EXPOSE 4567
|
||||||
|
|
||||||
|
COPY Gemfile .
|
||||||
|
COPY Gemfile.lock .
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends \
|
||||||
|
build-essential \
|
||||||
|
git \
|
||||||
|
nodejs \
|
||||||
|
&& gem install bundler \
|
||||||
|
&& bundle install \
|
||||||
|
&& apt-get remove -y build-essential git \
|
||||||
|
&& apt-get autoremove -y \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
COPY . /srv/slate
|
||||||
|
|
||||||
|
RUN chmod +x /srv/slate/slate.sh
|
||||||
|
|
||||||
|
ENTRYPOINT ["/srv/slate/slate.sh"]
|
||||||
|
CMD ["build"]
|
13
docs/api/Gemfile
Normal file
13
docs/api/Gemfile
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
ruby '>= 2.5'
|
||||||
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
|
# Middleman
|
||||||
|
gem 'middleman', '~> 4.4'
|
||||||
|
gem 'middleman-syntax', '~> 3.2'
|
||||||
|
gem 'middleman-autoprefixer', '~> 3.0'
|
||||||
|
gem 'middleman-sprockets', '~> 4.1'
|
||||||
|
gem 'rouge', '~> 3.21'
|
||||||
|
gem 'redcarpet', '~> 3.5.0'
|
||||||
|
gem 'nokogiri', '~> 1.12.1'
|
||||||
|
gem 'sass'
|
||||||
|
gem 'webrick'
|
145
docs/api/Gemfile.lock
Normal file
145
docs/api/Gemfile.lock
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
GEM
|
||||||
|
remote: https://rubygems.org/
|
||||||
|
specs:
|
||||||
|
activesupport (6.1.4.1)
|
||||||
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
|
i18n (>= 1.6, < 2)
|
||||||
|
minitest (>= 5.1)
|
||||||
|
tzinfo (~> 2.0)
|
||||||
|
zeitwerk (~> 2.3)
|
||||||
|
addressable (2.8.0)
|
||||||
|
public_suffix (>= 2.0.2, < 5.0)
|
||||||
|
autoprefixer-rails (10.2.5.0)
|
||||||
|
execjs (< 2.8.0)
|
||||||
|
backports (3.21.0)
|
||||||
|
coffee-script (2.4.1)
|
||||||
|
coffee-script-source
|
||||||
|
execjs
|
||||||
|
coffee-script-source (1.12.2)
|
||||||
|
concurrent-ruby (1.1.9)
|
||||||
|
contracts (0.13.0)
|
||||||
|
dotenv (2.7.6)
|
||||||
|
erubis (2.7.0)
|
||||||
|
execjs (2.7.0)
|
||||||
|
fast_blank (1.0.1)
|
||||||
|
fastimage (2.2.5)
|
||||||
|
ffi (1.15.4)
|
||||||
|
haml (5.2.2)
|
||||||
|
temple (>= 0.8.0)
|
||||||
|
tilt
|
||||||
|
hamster (3.0.0)
|
||||||
|
concurrent-ruby (~> 1.0)
|
||||||
|
hashie (3.6.0)
|
||||||
|
i18n (1.6.0)
|
||||||
|
concurrent-ruby (~> 1.0)
|
||||||
|
kramdown (2.3.1)
|
||||||
|
rexml
|
||||||
|
listen (3.0.8)
|
||||||
|
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||||
|
rb-inotify (~> 0.9, >= 0.9.7)
|
||||||
|
memoist (0.16.2)
|
||||||
|
middleman (4.4.2)
|
||||||
|
coffee-script (~> 2.2)
|
||||||
|
haml (>= 4.0.5)
|
||||||
|
kramdown (>= 2.3.0)
|
||||||
|
middleman-cli (= 4.4.2)
|
||||||
|
middleman-core (= 4.4.2)
|
||||||
|
middleman-autoprefixer (3.0.0)
|
||||||
|
autoprefixer-rails (~> 10.0)
|
||||||
|
middleman-core (>= 4.0.0)
|
||||||
|
middleman-cli (4.4.2)
|
||||||
|
thor (>= 0.17.0, < 2.0)
|
||||||
|
middleman-core (4.4.2)
|
||||||
|
activesupport (>= 6.1, < 7.0)
|
||||||
|
addressable (~> 2.4)
|
||||||
|
backports (~> 3.6)
|
||||||
|
bundler (~> 2.0)
|
||||||
|
contracts (~> 0.13.0)
|
||||||
|
dotenv
|
||||||
|
erubis
|
||||||
|
execjs (~> 2.0)
|
||||||
|
fast_blank
|
||||||
|
fastimage (~> 2.0)
|
||||||
|
hamster (~> 3.0)
|
||||||
|
hashie (~> 3.4)
|
||||||
|
i18n (~> 1.6.0)
|
||||||
|
listen (~> 3.0.0)
|
||||||
|
memoist (~> 0.14)
|
||||||
|
padrino-helpers (~> 0.15.0)
|
||||||
|
parallel
|
||||||
|
rack (>= 1.4.5, < 3)
|
||||||
|
sassc (~> 2.0)
|
||||||
|
servolux
|
||||||
|
tilt (~> 2.0.9)
|
||||||
|
toml
|
||||||
|
uglifier (~> 3.0)
|
||||||
|
webrick
|
||||||
|
middleman-sprockets (4.1.1)
|
||||||
|
middleman-core (~> 4.0)
|
||||||
|
sprockets (>= 3.0)
|
||||||
|
middleman-syntax (3.2.0)
|
||||||
|
middleman-core (>= 3.2)
|
||||||
|
rouge (~> 3.2)
|
||||||
|
mini_portile2 (2.6.1)
|
||||||
|
minitest (5.14.4)
|
||||||
|
nokogiri (1.12.5)
|
||||||
|
mini_portile2 (~> 2.6.1)
|
||||||
|
racc (~> 1.4)
|
||||||
|
padrino-helpers (0.15.1)
|
||||||
|
i18n (>= 0.6.7, < 2)
|
||||||
|
padrino-support (= 0.15.1)
|
||||||
|
tilt (>= 1.4.1, < 3)
|
||||||
|
padrino-support (0.15.1)
|
||||||
|
parallel (1.21.0)
|
||||||
|
parslet (2.0.0)
|
||||||
|
public_suffix (4.0.6)
|
||||||
|
racc (1.5.2)
|
||||||
|
rack (2.2.3)
|
||||||
|
rb-fsevent (0.11.0)
|
||||||
|
rb-inotify (0.10.1)
|
||||||
|
ffi (~> 1.0)
|
||||||
|
redcarpet (3.5.1)
|
||||||
|
rexml (3.2.5)
|
||||||
|
rouge (3.26.1)
|
||||||
|
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.2)
|
||||||
|
thor (1.1.0)
|
||||||
|
tilt (2.0.10)
|
||||||
|
toml (0.3.0)
|
||||||
|
parslet (>= 1.8.0, < 3.0.0)
|
||||||
|
tzinfo (2.0.4)
|
||||||
|
concurrent-ruby (~> 1.0)
|
||||||
|
uglifier (3.2.0)
|
||||||
|
execjs (>= 0.3.0, < 3)
|
||||||
|
webrick (1.7.0)
|
||||||
|
zeitwerk (2.5.1)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
ruby
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
middleman (~> 4.4)
|
||||||
|
middleman-autoprefixer (~> 3.0)
|
||||||
|
middleman-sprockets (~> 4.1)
|
||||||
|
middleman-syntax (~> 3.2)
|
||||||
|
nokogiri (~> 1.12.1)
|
||||||
|
redcarpet (~> 3.5.0)
|
||||||
|
rouge (~> 3.21)
|
||||||
|
sass
|
||||||
|
webrick
|
||||||
|
|
||||||
|
RUBY VERSION
|
||||||
|
ruby 2.7.2p137
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
2.2.22
|
201
docs/api/LICENSE
Normal file
201
docs/api/LICENSE
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"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.
|
82
docs/api/README.md
Normal file
82
docs/api/README.md
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<p align="center">
|
||||||
|
<img src="https://raw.githubusercontent.com/slatedocs/img/main/logo-slate.png" alt="Slate: API Documentation Generator" width="226">
|
||||||
|
<br>
|
||||||
|
<a href="https://github.com/slatedocs/slate/actions?query=workflow%3ABuild+branch%3Amain"><img src="https://github.com/slatedocs/slate/workflows/Build/badge.svg?branch=main" alt="Build Status"></a>
|
||||||
|
<a href="https://hub.docker.com/r/slatedocs/slate"><img src="https://img.shields.io/docker/v/slatedocs/slate?sort=semver" alt="Docker Version" /></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center">Slate helps you create beautiful, intelligent, responsive API documentation.</p>
|
||||||
|
|
||||||
|
<p align="center"><img src="https://raw.githubusercontent.com/slatedocs/img/main/screenshot-slate.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://slatedocs.github.io/slate">slatedocs.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/rouge-ruby/rouge/wiki/List-of-supported-languages-and-lexers), no configuration required.
|
||||||
|
|
||||||
|
* **Automatic, smoothly scrolling table of contents** on the far left of the page. As you scroll, it displays your current position in the document. It's fast, too. We're using Slate at TripIt to build documentation for our new API, where our table of contents has over 180 entries. We've made sure that the performance remains excellent, even for larger documents.
|
||||||
|
|
||||||
|
* **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.
|
||||||
|
|
||||||
|
* **RTL Support** Full right-to-left layout for RTL languages such as Arabic, Persian (Farsi), Hebrew etc.
|
||||||
|
|
||||||
|
Getting started with Slate is super easy! Simply press the green "use this template" button above and follow the instructions below. Or, if you'd like to check out what Slate is capable of, take a look at the [sample docs](https://slatedocs.github.io/slate/).
|
||||||
|
|
||||||
|
Getting Started with Slate
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
To get started with Slate, please check out the [Getting Started](https://github.com/slatedocs/slate/wiki#getting-started)
|
||||||
|
section in our [wiki](https://github.com/slatedocs/slate/wiki).
|
||||||
|
|
||||||
|
We support running Slate in three different ways:
|
||||||
|
* [Natively](https://github.com/slatedocs/slate/wiki/Using-Slate-Natively)
|
||||||
|
* [Using Vagrant](https://github.com/slatedocs/slate/wiki/Using-Slate-in-Vagrant)
|
||||||
|
* [Using Docker](https://github.com/slatedocs/slate/wiki/Using-Slate-in-Docker)
|
||||||
|
|
||||||
|
Companies Using Slate
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
* [NASA](https://api.nasa.gov)
|
||||||
|
* [Sony](http://developers.cimediacloud.com)
|
||||||
|
* [Best Buy](https://bestbuyapis.github.io/api-documentation/)
|
||||||
|
* [Travis-CI](https://docs.travis-ci.com/api/)
|
||||||
|
* [Greenhouse](https://developers.greenhouse.io/harvest.html)
|
||||||
|
* [WooCommerce](http://woocommerce.github.io/woocommerce-rest-api-docs/)
|
||||||
|
* [Dwolla](https://docs.dwolla.com/)
|
||||||
|
* [Clearbit](https://clearbit.com/docs)
|
||||||
|
* [Coinbase](https://developers.coinbase.com/api)
|
||||||
|
* [Parrot Drones](http://developer.parrot.com/docs/bebop/)
|
||||||
|
* [CoinAPI](https://docs.coinapi.io/)
|
||||||
|
|
||||||
|
You can view more in [the list on the wiki](https://github.com/slatedocs/slate/wiki/Slate-in-the-Wild).
|
||||||
|
|
||||||
|
Questions? Need Help? Found a bug?
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
If you've got questions about setup, deploying, special feature implementation in your fork, or just want to chat with the developer, please feel free to [start a thread in our Discussions tab](https://github.com/slatedocs/slate/discussions)!
|
||||||
|
|
||||||
|
Found a bug with upstream Slate? Go ahead and [submit an issue](https://github.com/slatedocs/slate/issues). And, of course, feel free to submit pull requests with bug fixes or changes to the `dev` branch.
|
||||||
|
|
||||||
|
Contributors
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Slate was built by [Robert Lord](https://lord.io) while at [TripIt](https://www.tripit.com/). The project is now maintained by [Matthew Peveler](https://github.com/MasterOdin) and [Mike Ralphson](https://github.com/MikeRalphson).
|
||||||
|
|
||||||
|
Thanks to the following people who have submitted major pull requests:
|
||||||
|
|
||||||
|
- [@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](http://saucelabs.com) for sponsoring the development of the responsive styles.
|
47
docs/api/Vagrantfile
vendored
Normal file
47
docs/api/Vagrantfile
vendored
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
Vagrant.configure(2) do |config|
|
||||||
|
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 ruby ruby-dev
|
||||||
|
sudo apt-get install -yq pkg-config build-essential nodejs git libxml2-dev libxslt-dev
|
||||||
|
sudo apt-get autoremove -yq
|
||||||
|
gem install --no-ri --no-rdoc bundler
|
||||||
|
SHELL
|
||||||
|
|
||||||
|
# add the local user git config to the vm
|
||||||
|
config.vm.provision "file", source: "~/.gitconfig", destination: ".gitconfig"
|
||||||
|
|
||||||
|
config.vm.provision "install",
|
||||||
|
type: "shell",
|
||||||
|
privileged: false,
|
||||||
|
inline: <<-SHELL
|
||||||
|
echo "=============================================="
|
||||||
|
echo "Installing app dependencies"
|
||||||
|
cd /vagrant
|
||||||
|
sudo gem install bundler -v "$(grep -A 1 "BUNDLED WITH" Gemfile.lock | tail -n 1)"
|
||||||
|
bundle config build.nokogiri --use-system-libraries
|
||||||
|
bundle install
|
||||||
|
SHELL
|
||||||
|
|
||||||
|
config.vm.provision "run",
|
||||||
|
type: "shell",
|
||||||
|
privileged: false,
|
||||||
|
run: "always",
|
||||||
|
inline: <<-SHELL
|
||||||
|
echo "=============================================="
|
||||||
|
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 --watcher-force-polling --watcher-latency=1 &> ~/middleman.log &
|
||||||
|
SHELL
|
||||||
|
end
|
531
docs/api/build/index.html
Normal file
531
docs/api/build/index.html
Normal file
@ -0,0 +1,531 @@
|
|||||||
|
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="Documentation for the GoScrobble API"
|
||||||
|
>
|
||||||
|
<title>GoScrobble API Documentation</title>
|
||||||
|
|
||||||
|
<style media="screen">
|
||||||
|
.highlight table td { padding: 5px; }
|
||||||
|
.highlight table pre { margin: 0; }
|
||||||
|
.highlight .gh {
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
.highlight .sr {
|
||||||
|
color: #f6aa11;
|
||||||
|
}
|
||||||
|
.highlight .go {
|
||||||
|
color: #888888;
|
||||||
|
}
|
||||||
|
.highlight .gp {
|
||||||
|
color: #555555;
|
||||||
|
}
|
||||||
|
.highlight .gs {
|
||||||
|
}
|
||||||
|
.highlight .gu {
|
||||||
|
color: #aaaaaa;
|
||||||
|
}
|
||||||
|
.highlight .nb {
|
||||||
|
color: #f6aa11;
|
||||||
|
}
|
||||||
|
.highlight .cm {
|
||||||
|
color: #75715e;
|
||||||
|
}
|
||||||
|
.highlight .cp {
|
||||||
|
color: #75715e;
|
||||||
|
}
|
||||||
|
.highlight .c1 {
|
||||||
|
color: #75715e;
|
||||||
|
}
|
||||||
|
.highlight .cs {
|
||||||
|
color: #75715e;
|
||||||
|
}
|
||||||
|
.highlight .c, .highlight .ch, .highlight .cd, .highlight .cpf {
|
||||||
|
color: #75715e;
|
||||||
|
}
|
||||||
|
.highlight .err {
|
||||||
|
color: #960050;
|
||||||
|
}
|
||||||
|
.highlight .gr {
|
||||||
|
color: #960050;
|
||||||
|
}
|
||||||
|
.highlight .gt {
|
||||||
|
color: #960050;
|
||||||
|
}
|
||||||
|
.highlight .gd {
|
||||||
|
color: #49483e;
|
||||||
|
}
|
||||||
|
.highlight .gi {
|
||||||
|
color: #49483e;
|
||||||
|
}
|
||||||
|
.highlight .ge {
|
||||||
|
color: #49483e;
|
||||||
|
}
|
||||||
|
.highlight .kc {
|
||||||
|
color: #66d9ef;
|
||||||
|
}
|
||||||
|
.highlight .kd {
|
||||||
|
color: #66d9ef;
|
||||||
|
}
|
||||||
|
.highlight .kr {
|
||||||
|
color: #66d9ef;
|
||||||
|
}
|
||||||
|
.highlight .no {
|
||||||
|
color: #66d9ef;
|
||||||
|
}
|
||||||
|
.highlight .kt {
|
||||||
|
color: #66d9ef;
|
||||||
|
}
|
||||||
|
.highlight .mf {
|
||||||
|
color: #ae81ff;
|
||||||
|
}
|
||||||
|
.highlight .mh {
|
||||||
|
color: #ae81ff;
|
||||||
|
}
|
||||||
|
.highlight .il {
|
||||||
|
color: #ae81ff;
|
||||||
|
}
|
||||||
|
.highlight .mi {
|
||||||
|
color: #ae81ff;
|
||||||
|
}
|
||||||
|
.highlight .mo {
|
||||||
|
color: #ae81ff;
|
||||||
|
}
|
||||||
|
.highlight .m, .highlight .mb, .highlight .mx {
|
||||||
|
color: #ae81ff;
|
||||||
|
}
|
||||||
|
.highlight .sc {
|
||||||
|
color: #ae81ff;
|
||||||
|
}
|
||||||
|
.highlight .se {
|
||||||
|
color: #ae81ff;
|
||||||
|
}
|
||||||
|
.highlight .ss {
|
||||||
|
color: #ae81ff;
|
||||||
|
}
|
||||||
|
.highlight .sd {
|
||||||
|
color: #e6db74;
|
||||||
|
}
|
||||||
|
.highlight .s2 {
|
||||||
|
color: #e6db74;
|
||||||
|
}
|
||||||
|
.highlight .sb {
|
||||||
|
color: #e6db74;
|
||||||
|
}
|
||||||
|
.highlight .sh {
|
||||||
|
color: #e6db74;
|
||||||
|
}
|
||||||
|
.highlight .si {
|
||||||
|
color: #e6db74;
|
||||||
|
}
|
||||||
|
.highlight .sx {
|
||||||
|
color: #e6db74;
|
||||||
|
}
|
||||||
|
.highlight .s1 {
|
||||||
|
color: #e6db74;
|
||||||
|
}
|
||||||
|
.highlight .s, .highlight .sa, .highlight .dl {
|
||||||
|
color: #e6db74;
|
||||||
|
}
|
||||||
|
.highlight .na {
|
||||||
|
color: #a6e22e;
|
||||||
|
}
|
||||||
|
.highlight .nc {
|
||||||
|
color: #a6e22e;
|
||||||
|
}
|
||||||
|
.highlight .nd {
|
||||||
|
color: #a6e22e;
|
||||||
|
}
|
||||||
|
.highlight .ne {
|
||||||
|
color: #a6e22e;
|
||||||
|
}
|
||||||
|
.highlight .nf, .highlight .fm {
|
||||||
|
color: #a6e22e;
|
||||||
|
}
|
||||||
|
.highlight .vc {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
.highlight .nn {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
.highlight .ni {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
.highlight .bp {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
.highlight .vg {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
.highlight .vi {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
.highlight .nv, .highlight .vm {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
.highlight .w {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
.highlight {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
.highlight .n, .highlight .py, .highlight .nx {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
.highlight .nl {
|
||||||
|
color: #f92672;
|
||||||
|
}
|
||||||
|
.highlight .ow {
|
||||||
|
color: #f92672;
|
||||||
|
}
|
||||||
|
.highlight .nt {
|
||||||
|
color: #f92672;
|
||||||
|
}
|
||||||
|
.highlight .k, .highlight .kv {
|
||||||
|
color: #f92672;
|
||||||
|
}
|
||||||
|
.highlight .kn {
|
||||||
|
color: #f92672;
|
||||||
|
}
|
||||||
|
.highlight .kp {
|
||||||
|
color: #f92672;
|
||||||
|
}
|
||||||
|
.highlight .o {
|
||||||
|
color: #f92672;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style media="print">
|
||||||
|
* {
|
||||||
|
-webkit-transition:none!important;
|
||||||
|
transition:none!important;
|
||||||
|
}
|
||||||
|
.highlight table td { padding: 5px; }
|
||||||
|
.highlight table pre { margin: 0; }
|
||||||
|
.highlight, .highlight .w {
|
||||||
|
color: #586e75;
|
||||||
|
}
|
||||||
|
.highlight .err {
|
||||||
|
color: #002b36;
|
||||||
|
background-color: #dc322f;
|
||||||
|
}
|
||||||
|
.highlight .c, .highlight .ch, .highlight .cd, .highlight .cm, .highlight .cpf, .highlight .c1, .highlight .cs {
|
||||||
|
color: #657b83;
|
||||||
|
}
|
||||||
|
.highlight .cp {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.highlight .nt {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.highlight .o, .highlight .ow {
|
||||||
|
color: #93a1a1;
|
||||||
|
}
|
||||||
|
.highlight .p, .highlight .pi {
|
||||||
|
color: #93a1a1;
|
||||||
|
}
|
||||||
|
.highlight .gi {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.highlight .gd {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.highlight .gh {
|
||||||
|
color: #268bd2;
|
||||||
|
background-color: #002b36;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.highlight .k, .highlight .kn, .highlight .kp, .highlight .kr, .highlight .kv {
|
||||||
|
color: #6c71c4;
|
||||||
|
}
|
||||||
|
.highlight .kc {
|
||||||
|
color: #cb4b16;
|
||||||
|
}
|
||||||
|
.highlight .kt {
|
||||||
|
color: #cb4b16;
|
||||||
|
}
|
||||||
|
.highlight .kd {
|
||||||
|
color: #cb4b16;
|
||||||
|
}
|
||||||
|
.highlight .s, .highlight .sb, .highlight .sc, .highlight .dl, .highlight .sd, .highlight .s2, .highlight .sh, .highlight .sx, .highlight .s1 {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.highlight .sa {
|
||||||
|
color: #6c71c4;
|
||||||
|
}
|
||||||
|
.highlight .sr {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.highlight .si {
|
||||||
|
color: #d33682;
|
||||||
|
}
|
||||||
|
.highlight .se {
|
||||||
|
color: #d33682;
|
||||||
|
}
|
||||||
|
.highlight .nn {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.highlight .nc {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.highlight .no {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.highlight .na {
|
||||||
|
color: #268bd2;
|
||||||
|
}
|
||||||
|
.highlight .m, .highlight .mb, .highlight .mf, .highlight .mh, .highlight .mi, .highlight .il, .highlight .mo, .highlight .mx {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.highlight .ss {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<link href="stylesheets/screen-cfdc3565.css" rel="stylesheet" media="screen" />
|
||||||
|
<link href="stylesheets/print-953e3353.css" rel="stylesheet" media="print" />
|
||||||
|
<script src="javascripts/all-b12a2749.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function() { setupCodeCopy(); });
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="index" data-languages="["shell"]">
|
||||||
|
<a href="#" id="nav-button">
|
||||||
|
<span>
|
||||||
|
NAV
|
||||||
|
<img src="images/navbar-cad8cdcb.png" alt="" />
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
<div class="toc-wrapper">
|
||||||
|
<img src="images/logo-7aa55c75.png" class="logo" alt="" />
|
||||||
|
<div class="lang-selector">
|
||||||
|
<a href="#" data-language-name="shell">shell</a>
|
||||||
|
</div>
|
||||||
|
<div class="search">
|
||||||
|
<input type="text" class="search" id="input-search" placeholder="Search">
|
||||||
|
</div>
|
||||||
|
<ul class="search-results"></ul>
|
||||||
|
<ul id="toc" class="toc-list-h1">
|
||||||
|
<li>
|
||||||
|
<a href="#introduction" class="toc-h1 toc-link" data-title="Introduction">Introduction</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#server-info" class="toc-h1 toc-link" data-title="Server Info">Server Info</a>
|
||||||
|
<ul class="toc-list-h2">
|
||||||
|
<li>
|
||||||
|
<a href="#v1-serverinfo" class="toc-h2 toc-link" data-title="v1/serverinfo">v1/serverinfo</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#authentication" class="toc-h1 toc-link" data-title="Authentication">Authentication</a>
|
||||||
|
<ul class="toc-list-h2">
|
||||||
|
<li>
|
||||||
|
<a href="#v1-login" class="toc-h2 toc-link" data-title="v1/login">v1/login</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#v1-register" class="toc-h2 toc-link" data-title="v1/register">v1/register</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#v1-sendreset" class="toc-h2 toc-link" data-title="v1/sendreset">v1/sendreset</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#v1-resetpassword" class="toc-h2 toc-link" data-title="v1/resetpassword">v1/resetpassword</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="toc-footer">
|
||||||
|
<li><a href='https://goscrobble.com'>GoScrobble website</a></li>
|
||||||
|
<li><a href='https://gitlab.com/goscrobble/goscrobble-api'>Backend Repository</a></li>
|
||||||
|
<li><a href='https://gitlab.com/goscrobble/goscrobble-web'>Frontend Repository</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="page-wrapper">
|
||||||
|
<div class="dark-box"></div>
|
||||||
|
<div class="content">
|
||||||
|
<h1 id='introduction'>Introduction</h1>
|
||||||
|
<p>Welcome to the GoScrobble API documentation.</p>
|
||||||
|
|
||||||
|
<p>The majority of these API endpoints are public with reasonable rate limits.</p>
|
||||||
|
<h1 id='server-info'>Server Info</h1><h2 id='v1-serverinfo'>v1/serverinfo</h2>
|
||||||
|
<blockquote>
|
||||||
|
<p>Check server version and registration status:</p>
|
||||||
|
</blockquote>
|
||||||
|
<div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="s2">"https://goscrobble.com/api/v1/serverinfo"</span>
|
||||||
|
</code></pre></div>
|
||||||
|
<blockquote>
|
||||||
|
<p>Response:</p>
|
||||||
|
</blockquote>
|
||||||
|
<div class="highlight"><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w">
|
||||||
|
</span><span class="nl">"version"</span><span class="p">:</span><span class="s2">"0.1.1"</span><span class="p">,</span><span class="w">
|
||||||
|
</span><span class="nl">"registration_enabled"</span><span class="p">:</span><span class="s2">"1"</span><span class="w">
|
||||||
|
</span><span class="p">}</span><span class="w">
|
||||||
|
</span></code></pre></div>
|
||||||
|
<p>This endpoint is used to get server API version and registration status.</p>
|
||||||
|
<h3 id='http-request'>HTTP Request</h3>
|
||||||
|
<p><code>GET https://goscrobble.com/api/v1/serverstatus</code></p>
|
||||||
|
<h1 id='authentication'>Authentication</h1><h2 id='v1-login'>v1/login</h2>
|
||||||
|
<blockquote>
|
||||||
|
<p>To obtain a JWT token (Replace default credentials):</p>
|
||||||
|
</blockquote>
|
||||||
|
<div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="s2">"https://goscrobble.com/api/v1/login"</span> <span class="se">\</span>
|
||||||
|
<span class="nt">-H</span> <span class="s2">"Content-Type: application/json"</span> <span class="se">\</span>
|
||||||
|
<span class="nt">--data</span> <span class="s1">'{"username":"abc","password":"def"}'</span>
|
||||||
|
</code></pre></div>
|
||||||
|
<blockquote>
|
||||||
|
<p>Response:</p>
|
||||||
|
</blockquote>
|
||||||
|
<div class="highlight"><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w">
|
||||||
|
</span><span class="nl">"token"</span><span class="p">:</span><span class="w"> </span><span class="s2">"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI6ZmFsc2UsImVtYWlsIjoidGVzdEB0ZXN0LmNvbSIsImV4cCI6MTY0MTAwMjUxOSwiaWF0IjoxNjQwMzk3NzE5LCJtb2QiOnRydWUsInJlZnJlc2hfZXhwIjoxNjQxMDAyNTE5LCJyZWZyZXNoX3Rva2VuIjoiYWJjZGVmZ2hqaWtsbW5vcHF3ZXJ0dXZ3eHl6Iiwic3ViIjoiNDE4ZmRkZmItOGIxYi01MWFiLTliZHMtNGZnMDhjYTYzY2ZmIiwidXNlcm5hbWUiOiJ0ZXN0In0.fuPXjQ7IzNyttgIKpdS4-KBQ-QeHTl-BfgYkSnMCmpVrBunzMrSwr1RzxI7Xg2WWF-FHtW3Bnv9RpSqLDN4F2g"</span><span class="w">
|
||||||
|
</span><span class="p">}</span><span class="w">
|
||||||
|
</span></code></pre></div>
|
||||||
|
<p>This endpoint is used to authenticate and retrieve a JWT token.</p>
|
||||||
|
<h3 id='http-request'>HTTP Request</h3>
|
||||||
|
<p><code>POST https://goscrobble.com/api/v1/login</code></p>
|
||||||
|
<h3 id='query-parameters'>Query Parameters</h3>
|
||||||
|
<table><thead>
|
||||||
|
<tr>
|
||||||
|
<th>Parameter</th>
|
||||||
|
<th>Required</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
</thead><tbody>
|
||||||
|
<tr>
|
||||||
|
<td>username</td>
|
||||||
|
<td>true</td>
|
||||||
|
<td>Account username</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>password</td>
|
||||||
|
<td>true</td>
|
||||||
|
<td>Account password</td>
|
||||||
|
</tr>
|
||||||
|
</tbody></table>
|
||||||
|
<h2 id='v1-register'>v1/register</h2>
|
||||||
|
<blockquote>
|
||||||
|
<p>Create a new account (Replace default credentials):</p>
|
||||||
|
</blockquote>
|
||||||
|
<div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="s2">"https://goscrobble.com/api/v1/register"</span> <span class="se">\</span>
|
||||||
|
<span class="nt">-H</span> <span class="s2">"Content-Type: application/json"</span> <span class="se">\</span>
|
||||||
|
<span class="nt">--data</span> <span class="s1">'{"email": "test@test.com", "username":"abc","password":"def"}'</span>
|
||||||
|
</code></pre></div>
|
||||||
|
<blockquote>
|
||||||
|
<p>Response:</p>
|
||||||
|
</blockquote>
|
||||||
|
<div class="highlight"><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w">
|
||||||
|
</span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"User created succesfully. You may now login"</span><span class="w">
|
||||||
|
</span><span class="p">}</span><span class="w">
|
||||||
|
</span></code></pre></div>
|
||||||
|
<p>If the server has REGISTRATION_ENABLED=true set, this endpoint will allow you to create a new account. Password must be at least 8 characters long.</p>
|
||||||
|
<h3 id='http-request-2'>HTTP Request</h3>
|
||||||
|
<p><code>POST https://goscrobble.com/api/v1/register</code></p>
|
||||||
|
<h3 id='query-parameters-2'>Query Parameters</h3>
|
||||||
|
<table><thead>
|
||||||
|
<tr>
|
||||||
|
<th>Parameter</th>
|
||||||
|
<th>Required</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
</thead><tbody>
|
||||||
|
<tr>
|
||||||
|
<td>email</td>
|
||||||
|
<td>true</td>
|
||||||
|
<td>Account email</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>username</td>
|
||||||
|
<td>true</td>
|
||||||
|
<td>Account username</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>password</td>
|
||||||
|
<td>true</td>
|
||||||
|
<td>Account password</td>
|
||||||
|
</tr>
|
||||||
|
</tbody></table>
|
||||||
|
<h2 id='v1-sendreset'>v1/sendreset</h2>
|
||||||
|
<blockquote>
|
||||||
|
<p>Trigger a password reset email:</p>
|
||||||
|
</blockquote>
|
||||||
|
<div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="s2">"https://goscrobble.com/api/v1/sendreset"</span> <span class="se">\</span>
|
||||||
|
<span class="nt">-H</span> <span class="s2">"Content-Type: application/json"</span> <span class="se">\</span>
|
||||||
|
<span class="nt">--data</span> <span class="s1">'{"email":"test@test.com"}'</span>
|
||||||
|
</code></pre></div>
|
||||||
|
<blockquote>
|
||||||
|
<p>Response:</p>
|
||||||
|
</blockquote>
|
||||||
|
<div class="highlight"><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w">
|
||||||
|
</span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Password reset email sent"</span><span class="w">
|
||||||
|
</span><span class="p">}</span><span class="w">
|
||||||
|
</span></code></pre></div>
|
||||||
|
<p>This endpoint triggers a password reset email to be sent to the email on an account.</p>
|
||||||
|
<h3 id='http-request-3'>HTTP Request</h3>
|
||||||
|
<p><code>POST https://goscrobble.com/api/v1/sendreset</code></p>
|
||||||
|
<h3 id='query-parameters-3'>Query Parameters</h3>
|
||||||
|
<table><thead>
|
||||||
|
<tr>
|
||||||
|
<th>Parameter</th>
|
||||||
|
<th>Required</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
</thead><tbody>
|
||||||
|
<tr>
|
||||||
|
<td>email</td>
|
||||||
|
<td>true</td>
|
||||||
|
<td>Account username</td>
|
||||||
|
</tr>
|
||||||
|
</tbody></table>
|
||||||
|
<h2 id='v1-resetpassword'>v1/resetpassword</h2>
|
||||||
|
<blockquote>
|
||||||
|
<p>Trigger a password reset email:</p>
|
||||||
|
</blockquote>
|
||||||
|
<div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="s2">"https://goscrobble.com/api/v1/resetpassword"</span> <span class="se">\</span>
|
||||||
|
<span class="nt">-H</span> <span class="s2">"Content-Type: application/json"</span> <span class="se">\</span>
|
||||||
|
<span class="nt">--data</span> <span class="s1">'{"token":"abcdefghijklmnopqrstuvwxyz", "password": "Hunter1"}'</span>
|
||||||
|
</code></pre></div>
|
||||||
|
<blockquote>
|
||||||
|
<p>Response:</p>
|
||||||
|
</blockquote>
|
||||||
|
<div class="highlight"><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w">
|
||||||
|
</span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Password updated successfully!"</span><span class="w">
|
||||||
|
</span><span class="p">}</span><span class="w">
|
||||||
|
</span></code></pre></div>
|
||||||
|
<p>This endpoint confirms a password reset with a valid hash from the reset email. You must call v1/sendreset first and obtain the hash.</p>
|
||||||
|
<h3 id='http-request-4'>HTTP Request</h3>
|
||||||
|
<p><code>POST https://goscrobble.com/api/v1/resetpassword</code></p>
|
||||||
|
<h3 id='query-parameters-4'>Query Parameters</h3>
|
||||||
|
<table><thead>
|
||||||
|
<tr>
|
||||||
|
<th>Parameter</th>
|
||||||
|
<th>Required</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
</thead><tbody>
|
||||||
|
<tr>
|
||||||
|
<td>token</td>
|
||||||
|
<td>true</td>
|
||||||
|
<td>Reset token from the password reset email</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>password</td>
|
||||||
|
<td>true</td>
|
||||||
|
<td>New account password</td>
|
||||||
|
</tr>
|
||||||
|
</tbody></table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="dark-box">
|
||||||
|
<div class="lang-selector">
|
||||||
|
<a href="#" data-language-name="shell">shell</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
63
docs/api/config.rb
Normal file
63
docs/api/config.rb
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
# Unique header generation
|
||||||
|
require './lib/unique_head.rb'
|
||||||
|
|
||||||
|
# Markdown
|
||||||
|
set :markdown_engine, :redcarpet
|
||||||
|
set :markdown,
|
||||||
|
fenced_code_blocks: true,
|
||||||
|
smartypants: true,
|
||||||
|
disable_indented_code_blocks: true,
|
||||||
|
prettify: true,
|
||||||
|
strikethrough: true,
|
||||||
|
tables: true,
|
||||||
|
with_toc_data: true,
|
||||||
|
no_intra_emphasis: true,
|
||||||
|
renderer: UniqueHeadCounter
|
||||||
|
|
||||||
|
# Assets
|
||||||
|
set :css_dir, 'stylesheets'
|
||||||
|
set :js_dir, 'javascripts'
|
||||||
|
set :images_dir, 'images'
|
||||||
|
set :fonts_dir, 'fonts'
|
||||||
|
|
||||||
|
# Activate the syntax highlighter
|
||||||
|
activate :syntax
|
||||||
|
ready do
|
||||||
|
require './lib/monokai_sublime_slate.rb'
|
||||||
|
require './lib/multilang.rb'
|
||||||
|
end
|
||||||
|
|
||||||
|
activate :sprockets
|
||||||
|
|
||||||
|
activate :autoprefixer do |config|
|
||||||
|
config.browsers = ['last 2 version', 'Firefox ESR']
|
||||||
|
config.cascade = false
|
||||||
|
config.inline = true
|
||||||
|
end
|
||||||
|
|
||||||
|
# Github pages require relative links
|
||||||
|
activate :relative_assets
|
||||||
|
set :relative_links, true
|
||||||
|
|
||||||
|
# Build Configuration
|
||||||
|
configure :build do
|
||||||
|
# We do want to hash woff and woff2 as there's a bug where woff2 will use
|
||||||
|
# woff asset hash which breaks things. Trying to use a combination of ignore and
|
||||||
|
# rewrite_ignore does not work as it conflicts weirdly with relative_assets. Disabling
|
||||||
|
# the .woff2 extension only does not work as .woff will still activate it so have to
|
||||||
|
# have both. See https://github.com/slatedocs/slate/issues/1171 for more details.
|
||||||
|
activate :asset_hash, :exts => app.config[:asset_extensions] - %w[.woff .woff2]
|
||||||
|
# If you're having trouble with Middleman hanging, commenting
|
||||||
|
# out the following two lines has been known to help
|
||||||
|
activate :minify_css
|
||||||
|
activate :minify_javascript
|
||||||
|
# activate :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
|
226
docs/api/deploy.sh
Executable file
226
docs/api/deploy.sh
Executable file
@ -0,0 +1,226 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -o errexit #abort if any command fails
|
||||||
|
me=$(basename "$0")
|
||||||
|
|
||||||
|
help_message="\
|
||||||
|
Usage: $me [-c FILE] [<options>]
|
||||||
|
Deploy generated files to a git branch.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
|
||||||
|
-h, --help Show this help information.
|
||||||
|
-v, --verbose Increase verbosity. Useful for debugging.
|
||||||
|
-e, --allow-empty Allow deployment of an empty directory.
|
||||||
|
-m, --message MESSAGE Specify the message used when committing on the
|
||||||
|
deploy branch.
|
||||||
|
-n, --no-hash Don't append the source commit's hash to the deploy
|
||||||
|
commit's message.
|
||||||
|
--source-only Only build but not push
|
||||||
|
--push-only Only push but not build
|
||||||
|
"
|
||||||
|
|
||||||
|
|
||||||
|
run_build() {
|
||||||
|
bundle exec middleman build --clean
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_args() {
|
||||||
|
# Set args from a local environment file.
|
||||||
|
if [ -e ".env" ]; then
|
||||||
|
source .env
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Parse arg flags
|
||||||
|
# If something is exposed as an environment variable, set/overwrite it
|
||||||
|
# here. Otherwise, set/overwrite the internal variable instead.
|
||||||
|
while : ; do
|
||||||
|
if [[ $1 = "-h" || $1 = "--help" ]]; then
|
||||||
|
echo "$help_message"
|
||||||
|
exit 0
|
||||||
|
elif [[ $1 = "-v" || $1 = "--verbose" ]]; then
|
||||||
|
verbose=true
|
||||||
|
shift
|
||||||
|
elif [[ $1 = "-e" || $1 = "--allow-empty" ]]; then
|
||||||
|
allow_empty=true
|
||||||
|
shift
|
||||||
|
elif [[ ( $1 = "-m" || $1 = "--message" ) && -n $2 ]]; then
|
||||||
|
commit_message=$2
|
||||||
|
shift 2
|
||||||
|
elif [[ $1 = "-n" || $1 = "--no-hash" ]]; then
|
||||||
|
GIT_DEPLOY_APPEND_HASH=false
|
||||||
|
shift
|
||||||
|
elif [[ $1 = "--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.
|
||||||
|
|
||||||
|
# Source directory & target branch.
|
||||||
|
deploy_directory=build
|
||||||
|
deploy_branch=gh-pages
|
||||||
|
|
||||||
|
#if no user identity is already set in the current git environment, use this:
|
||||||
|
default_username=${GIT_DEPLOY_USERNAME:-deploy.sh}
|
||||||
|
default_email=${GIT_DEPLOY_EMAIL:-}
|
||||||
|
|
||||||
|
#repository to deploy to. must be readable and writable.
|
||||||
|
repo=origin
|
||||||
|
|
||||||
|
#append commit hash to the end of message by default
|
||||||
|
append_hash=${GIT_DEPLOY_APPEND_HASH:-true}
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
enable_expanded_output
|
||||||
|
|
||||||
|
if ! git diff --exit-code --quiet --cached; then
|
||||||
|
echo Aborting due to uncommitted changes in the index >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
commit_title=`git log -n 1 --format="%s" HEAD`
|
||||||
|
commit_hash=` git log -n 1 --format="%H" HEAD`
|
||||||
|
|
||||||
|
#default commit message uses last title if a custom one is not supplied
|
||||||
|
if [[ -z $commit_message ]]; then
|
||||||
|
commit_message="publish: $commit_title"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#append hash to commit message unless no hash flag was found
|
||||||
|
if [ $append_hash = true ]; then
|
||||||
|
commit_message="$commit_message"$'\n\n'"generated from commit $commit_hash"
|
||||||
|
fi
|
||||||
|
|
||||||
|
previous_branch=`git rev-parse --abbrev-ref HEAD`
|
||||||
|
|
||||||
|
if [ ! -d "$deploy_directory" ]; then
|
||||||
|
echo "Deploy directory '$deploy_directory' does not exist. Aborting." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# must use short form of flag in ls for compatibility with macOS and BSD
|
||||||
|
if [[ -z `ls -A "$deploy_directory" 2> /dev/null` && -z $allow_empty ]]; then
|
||||||
|
echo "Deploy directory '$deploy_directory' is empty. Aborting. If you're sure you want to deploy an empty tree, use the --allow-empty / -e flag." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if git ls-remote --exit-code $repo "refs/heads/$deploy_branch" ; then
|
||||||
|
# deploy_branch exists in $repo; make sure we have the latest version
|
||||||
|
|
||||||
|
disable_expanded_output
|
||||||
|
git fetch --force $repo $deploy_branch:$deploy_branch
|
||||||
|
enable_expanded_output
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check if deploy_branch exists locally
|
||||||
|
if git show-ref --verify --quiet "refs/heads/$deploy_branch"
|
||||||
|
then incremental_deploy
|
||||||
|
else initial_deploy
|
||||||
|
fi
|
||||||
|
|
||||||
|
restore_head
|
||||||
|
}
|
||||||
|
|
||||||
|
initial_deploy() {
|
||||||
|
git --work-tree "$deploy_directory" checkout --orphan $deploy_branch
|
||||||
|
git --work-tree "$deploy_directory" add --all
|
||||||
|
commit+push
|
||||||
|
}
|
||||||
|
|
||||||
|
incremental_deploy() {
|
||||||
|
#make deploy_branch the current branch
|
||||||
|
git symbolic-ref HEAD refs/heads/$deploy_branch
|
||||||
|
#put the previously committed contents of deploy_branch into the index
|
||||||
|
git --work-tree "$deploy_directory" reset --mixed --quiet
|
||||||
|
git --work-tree "$deploy_directory" add --all
|
||||||
|
|
||||||
|
set +o errexit
|
||||||
|
diff=$(git --work-tree "$deploy_directory" diff --exit-code --quiet HEAD --)$?
|
||||||
|
set -o errexit
|
||||||
|
case $diff in
|
||||||
|
0) echo No changes to files in $deploy_directory. Skipping commit.;;
|
||||||
|
1) commit+push;;
|
||||||
|
*)
|
||||||
|
echo git diff exited with code $diff. Aborting. Staying on branch $deploy_branch so you can debug. To switch back to main, use: git symbolic-ref HEAD refs/heads/main && git reset --mixed >&2
|
||||||
|
return $diff
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
commit+push() {
|
||||||
|
set_user_id
|
||||||
|
git --work-tree "$deploy_directory" commit -m "$commit_message"
|
||||||
|
|
||||||
|
disable_expanded_output
|
||||||
|
#--quiet is important here to avoid outputting the repo URL, which may contain a secret token
|
||||||
|
git push --quiet $repo $deploy_branch
|
||||||
|
enable_expanded_output
|
||||||
|
}
|
||||||
|
|
||||||
|
#echo expanded commands as they are executed (for debugging)
|
||||||
|
enable_expanded_output() {
|
||||||
|
if [ $verbose ]; then
|
||||||
|
set -o xtrace
|
||||||
|
set +o verbose
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#this is used to avoid outputting the repo URL, which may contain a secret token
|
||||||
|
disable_expanded_output() {
|
||||||
|
if [ $verbose ]; then
|
||||||
|
set +o xtrace
|
||||||
|
set -o verbose
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
set_user_id() {
|
||||||
|
if [[ -z `git config user.name` ]]; then
|
||||||
|
git config user.name "$default_username"
|
||||||
|
fi
|
||||||
|
if [[ -z `git config user.email` ]]; then
|
||||||
|
git config user.email "$default_email"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_head() {
|
||||||
|
if [[ $previous_branch = "HEAD" ]]; then
|
||||||
|
#we weren't on any branch before, so just set HEAD back to the commit it was on
|
||||||
|
git update-ref --no-deref HEAD $commit_hash $deploy_branch
|
||||||
|
else
|
||||||
|
git symbolic-ref HEAD refs/heads/$previous_branch
|
||||||
|
fi
|
||||||
|
|
||||||
|
git reset --mixed
|
||||||
|
}
|
||||||
|
|
||||||
|
filter() {
|
||||||
|
sed -e "s|$repo|\$repo|g"
|
||||||
|
}
|
||||||
|
|
||||||
|
sanitize() {
|
||||||
|
"$@" 2> >(filter 1>&2) | filter
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_args "$@"
|
||||||
|
|
||||||
|
if [[ ${source_only} ]]; then
|
||||||
|
run_build
|
||||||
|
elif [[ ${push_only} ]]; then
|
||||||
|
main "$@"
|
||||||
|
else
|
||||||
|
run_build
|
||||||
|
main "$@"
|
||||||
|
fi
|
148
docs/api/font-selection.json
Executable file
148
docs/api/font-selection.json
Executable file
@ -0,0 +1,148 @@
|
|||||||
|
{
|
||||||
|
"IcoMoonType": "selection",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"icon": {
|
||||||
|
"paths": [
|
||||||
|
"M438.857 73.143q119.429 0 220.286 58.857t159.714 159.714 58.857 220.286-58.857 220.286-159.714 159.714-220.286 58.857-220.286-58.857-159.714-159.714-58.857-220.286 58.857-220.286 159.714-159.714 220.286-58.857zM512 785.714v-108.571q0-8-5.143-13.429t-12.571-5.429h-109.714q-7.429 0-13.143 5.714t-5.714 13.143v108.571q0 7.429 5.714 13.143t13.143 5.714h109.714q7.429 0 12.571-5.429t5.143-13.429zM510.857 589.143l10.286-354.857q0-6.857-5.714-10.286-5.714-4.571-13.714-4.571h-125.714q-8 0-13.714 4.571-5.714 3.429-5.714 10.286l9.714 354.857q0 5.714 5.714 10t13.714 4.286h105.714q8 0 13.429-4.286t6-10z"
|
||||||
|
],
|
||||||
|
"attrs": [],
|
||||||
|
"isMulticolor": false,
|
||||||
|
"tags": [
|
||||||
|
"exclamation-circle"
|
||||||
|
],
|
||||||
|
"defaultCode": 61546,
|
||||||
|
"grid": 14
|
||||||
|
},
|
||||||
|
"attrs": [],
|
||||||
|
"properties": {
|
||||||
|
"id": 100,
|
||||||
|
"order": 4,
|
||||||
|
"prevSize": 28,
|
||||||
|
"code": 58880,
|
||||||
|
"name": "exclamation-sign",
|
||||||
|
"ligatures": ""
|
||||||
|
},
|
||||||
|
"setIdx": 0,
|
||||||
|
"iconIdx": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": {
|
||||||
|
"paths": [
|
||||||
|
"M585.143 786.286v-91.429q0-8-5.143-13.143t-13.143-5.143h-54.857v-292.571q0-8-5.143-13.143t-13.143-5.143h-182.857q-8 0-13.143 5.143t-5.143 13.143v91.429q0 8 5.143 13.143t13.143 5.143h54.857v182.857h-54.857q-8 0-13.143 5.143t-5.143 13.143v91.429q0 8 5.143 13.143t13.143 5.143h256q8 0 13.143-5.143t5.143-13.143zM512 274.286v-91.429q0-8-5.143-13.143t-13.143-5.143h-109.714q-8 0-13.143 5.143t-5.143 13.143v91.429q0 8 5.143 13.143t13.143 5.143h109.714q8 0 13.143-5.143t5.143-13.143zM877.714 512q0 119.429-58.857 220.286t-159.714 159.714-220.286 58.857-220.286-58.857-159.714-159.714-58.857-220.286 58.857-220.286 159.714-159.714 220.286-58.857 220.286 58.857 159.714 159.714 58.857 220.286z"
|
||||||
|
],
|
||||||
|
"attrs": [],
|
||||||
|
"isMulticolor": false,
|
||||||
|
"tags": [
|
||||||
|
"info-circle"
|
||||||
|
],
|
||||||
|
"defaultCode": 61530,
|
||||||
|
"grid": 14
|
||||||
|
},
|
||||||
|
"attrs": [],
|
||||||
|
"properties": {
|
||||||
|
"id": 85,
|
||||||
|
"order": 3,
|
||||||
|
"name": "info-sign",
|
||||||
|
"prevSize": 28,
|
||||||
|
"code": 58882
|
||||||
|
},
|
||||||
|
"setIdx": 0,
|
||||||
|
"iconIdx": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": {
|
||||||
|
"paths": [
|
||||||
|
"M733.714 419.429q0-16-10.286-26.286l-52-51.429q-10.857-10.857-25.714-10.857t-25.714 10.857l-233.143 232.571-129.143-129.143q-10.857-10.857-25.714-10.857t-25.714 10.857l-52 51.429q-10.286 10.286-10.286 26.286 0 15.429 10.286 25.714l206.857 206.857q10.857 10.857 25.714 10.857 15.429 0 26.286-10.857l310.286-310.286q10.286-10.286 10.286-25.714zM877.714 512q0 119.429-58.857 220.286t-159.714 159.714-220.286 58.857-220.286-58.857-159.714-159.714-58.857-220.286 58.857-220.286 159.714-159.714 220.286-58.857 220.286 58.857 159.714 159.714 58.857 220.286z"
|
||||||
|
],
|
||||||
|
"attrs": [],
|
||||||
|
"isMulticolor": false,
|
||||||
|
"tags": [
|
||||||
|
"check-circle"
|
||||||
|
],
|
||||||
|
"defaultCode": 61528,
|
||||||
|
"grid": 14
|
||||||
|
},
|
||||||
|
"attrs": [],
|
||||||
|
"properties": {
|
||||||
|
"id": 83,
|
||||||
|
"order": 9,
|
||||||
|
"prevSize": 28,
|
||||||
|
"code": 58886,
|
||||||
|
"name": "ok-sign"
|
||||||
|
},
|
||||||
|
"setIdx": 0,
|
||||||
|
"iconIdx": 6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": {
|
||||||
|
"paths": [
|
||||||
|
"M658.286 475.429q0-105.714-75.143-180.857t-180.857-75.143-180.857 75.143-75.143 180.857 75.143 180.857 180.857 75.143 180.857-75.143 75.143-180.857zM950.857 950.857q0 29.714-21.714 51.429t-51.429 21.714q-30.857 0-51.429-21.714l-196-195.429q-102.286 70.857-228 70.857-81.714 0-156.286-31.714t-128.571-85.714-85.714-128.571-31.714-156.286 31.714-156.286 85.714-128.571 128.571-85.714 156.286-31.714 156.286 31.714 128.571 85.714 85.714 128.571 31.714 156.286q0 125.714-70.857 228l196 196q21.143 21.143 21.143 51.429z"
|
||||||
|
],
|
||||||
|
"width": 951,
|
||||||
|
"attrs": [],
|
||||||
|
"isMulticolor": false,
|
||||||
|
"tags": [
|
||||||
|
"search"
|
||||||
|
],
|
||||||
|
"defaultCode": 61442,
|
||||||
|
"grid": 14
|
||||||
|
},
|
||||||
|
"attrs": [],
|
||||||
|
"properties": {
|
||||||
|
"id": 2,
|
||||||
|
"order": 1,
|
||||||
|
"prevSize": 28,
|
||||||
|
"code": 58887,
|
||||||
|
"name": "icon-search"
|
||||||
|
},
|
||||||
|
"setIdx": 0,
|
||||||
|
"iconIdx": 7
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"height": 1024,
|
||||||
|
"metadata": {
|
||||||
|
"name": "slate",
|
||||||
|
"license": "SIL OFL 1.1"
|
||||||
|
},
|
||||||
|
"preferences": {
|
||||||
|
"showGlyphs": true,
|
||||||
|
"showQuickUse": true,
|
||||||
|
"showQuickUse2": true,
|
||||||
|
"showSVGs": true,
|
||||||
|
"fontPref": {
|
||||||
|
"prefix": "icon-",
|
||||||
|
"metadata": {
|
||||||
|
"fontFamily": "slate",
|
||||||
|
"majorVersion": 1,
|
||||||
|
"minorVersion": 0,
|
||||||
|
"description": "Based on FontAwesome",
|
||||||
|
"license": "SIL OFL 1.1"
|
||||||
|
},
|
||||||
|
"metrics": {
|
||||||
|
"emSize": 1024,
|
||||||
|
"baseline": 6.25,
|
||||||
|
"whitespace": 50
|
||||||
|
},
|
||||||
|
"resetPoint": 58880,
|
||||||
|
"showSelector": false,
|
||||||
|
"selector": "class",
|
||||||
|
"classSelector": ".icon",
|
||||||
|
"showMetrics": false,
|
||||||
|
"showMetadata": true,
|
||||||
|
"showVersion": true,
|
||||||
|
"ie7": false
|
||||||
|
},
|
||||||
|
"imagePref": {
|
||||||
|
"prefix": "icon-",
|
||||||
|
"png": true,
|
||||||
|
"useClassSelector": true,
|
||||||
|
"color": 4473924,
|
||||||
|
"bgColor": 16777215
|
||||||
|
},
|
||||||
|
"historySize": 100,
|
||||||
|
"showCodes": true,
|
||||||
|
"gridSize": 16,
|
||||||
|
"showLiga": false
|
||||||
|
}
|
||||||
|
}
|
95
docs/api/lib/monokai_sublime_slate.rb
Normal file
95
docs/api/lib/monokai_sublime_slate.rb
Normal 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
|
16
docs/api/lib/multilang.rb
Normal file
16
docs/api/lib/multilang.rb
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
module Multilang
|
||||||
|
def block_code(code, 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
|
||||||
|
|
||||||
|
require 'middleman-core/renderers/redcarpet'
|
||||||
|
Middleman::Renderers::MiddlemanRedcarpetHTML.send :include, Multilang
|
22
docs/api/lib/nesting_unique_head.rb
Normal file
22
docs/api/lib/nesting_unique_head.rb
Normal 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
|
31
docs/api/lib/toc_data.rb
Normal file
31
docs/api/lib/toc_data.rb
Normal 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
|
24
docs/api/lib/unique_head.rb
Normal file
24
docs/api/lib/unique_head.rb
Normal 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
|
248
docs/api/slate.sh
Executable file
248
docs/api/slate.sh
Executable file
@ -0,0 +1,248 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -o errexit #abort if any command fails
|
||||||
|
|
||||||
|
me=$(basename "$0")
|
||||||
|
|
||||||
|
help_message="\
|
||||||
|
Usage: $me [<options>] <command> [<command-options>]
|
||||||
|
Run commands related to the slate process.
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
|
||||||
|
serve Run the middleman server process, useful for
|
||||||
|
development.
|
||||||
|
build Run the build process.
|
||||||
|
deploy Will build and deploy files to branch. Use
|
||||||
|
--no-build to only deploy.
|
||||||
|
|
||||||
|
Global Options:
|
||||||
|
|
||||||
|
-h, --help Show this help information.
|
||||||
|
-v, --verbose Increase verbosity. Useful for debugging.
|
||||||
|
|
||||||
|
Deploy options:
|
||||||
|
-e, --allow-empty Allow deployment of an empty directory.
|
||||||
|
-m, --message MESSAGE Specify the message used when committing on the
|
||||||
|
deploy branch.
|
||||||
|
-n, --no-hash Don't append the source commit's hash to the deploy
|
||||||
|
commit's message.
|
||||||
|
--no-build Do not build the source files.
|
||||||
|
"
|
||||||
|
|
||||||
|
|
||||||
|
run_serve() {
|
||||||
|
exec bundle exec middleman serve --watcher-force-polling
|
||||||
|
}
|
||||||
|
|
||||||
|
run_build() {
|
||||||
|
bundle exec middleman build --clean
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_args() {
|
||||||
|
# Set args from a local environment file.
|
||||||
|
if [ -e ".env" ]; then
|
||||||
|
source .env
|
||||||
|
fi
|
||||||
|
|
||||||
|
command=
|
||||||
|
|
||||||
|
# Parse arg flags
|
||||||
|
# If something is exposed as an environment variable, set/overwrite it
|
||||||
|
# here. Otherwise, set/overwrite the internal variable instead.
|
||||||
|
while : ; do
|
||||||
|
if [[ $1 = "-h" || $1 = "--help" ]]; then
|
||||||
|
echo "$help_message"
|
||||||
|
exit 0
|
||||||
|
elif [[ $1 = "-v" || $1 = "--verbose" ]]; then
|
||||||
|
verbose=true
|
||||||
|
shift
|
||||||
|
elif [[ $1 = "-e" || $1 = "--allow-empty" ]]; then
|
||||||
|
allow_empty=true
|
||||||
|
shift
|
||||||
|
elif [[ ( $1 = "-m" || $1 = "--message" ) && -n $2 ]]; then
|
||||||
|
commit_message=$2
|
||||||
|
shift 2
|
||||||
|
elif [[ $1 = "-n" || $1 = "--no-hash" ]]; then
|
||||||
|
GIT_DEPLOY_APPEND_HASH=false
|
||||||
|
shift
|
||||||
|
elif [[ $1 = "--no-build" ]]; then
|
||||||
|
no_build=true
|
||||||
|
shift
|
||||||
|
elif [[ $1 = "serve" || $1 = "build" || $1 = "deploy" ]]; then
|
||||||
|
if [ ! -z "${command}" ]; then
|
||||||
|
>&2 echo "You can only specify one command."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
command=$1
|
||||||
|
shift
|
||||||
|
elif [ -z $1 ]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "${command}" ]; then
|
||||||
|
>&2 echo "Command not specified."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set internal option vars from the environment and arg flags. All internal
|
||||||
|
# vars should be declared here, with sane defaults if applicable.
|
||||||
|
|
||||||
|
# Source directory & target branch.
|
||||||
|
deploy_directory=build
|
||||||
|
deploy_branch=gh-pages
|
||||||
|
|
||||||
|
#if no user identity is already set in the current git environment, use this:
|
||||||
|
default_username=${GIT_DEPLOY_USERNAME:-deploy.sh}
|
||||||
|
default_email=${GIT_DEPLOY_EMAIL:-}
|
||||||
|
|
||||||
|
#repository to deploy to. must be readable and writable.
|
||||||
|
repo=origin
|
||||||
|
|
||||||
|
#append commit hash to the end of message by default
|
||||||
|
append_hash=${GIT_DEPLOY_APPEND_HASH:-true}
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
enable_expanded_output
|
||||||
|
|
||||||
|
if ! git diff --exit-code --quiet --cached; then
|
||||||
|
echo Aborting due to uncommitted changes in the index >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
commit_title=`git log -n 1 --format="%s" HEAD`
|
||||||
|
commit_hash=` git log -n 1 --format="%H" HEAD`
|
||||||
|
|
||||||
|
#default commit message uses last title if a custom one is not supplied
|
||||||
|
if [[ -z $commit_message ]]; then
|
||||||
|
commit_message="publish: $commit_title"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#append hash to commit message unless no hash flag was found
|
||||||
|
if [ $append_hash = true ]; then
|
||||||
|
commit_message="$commit_message"$'\n\n'"generated from commit $commit_hash"
|
||||||
|
fi
|
||||||
|
|
||||||
|
previous_branch=`git rev-parse --abbrev-ref HEAD`
|
||||||
|
|
||||||
|
if [ ! -d "$deploy_directory" ]; then
|
||||||
|
echo "Deploy directory '$deploy_directory' does not exist. Aborting." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# must use short form of flag in ls for compatibility with macOS and BSD
|
||||||
|
if [[ -z `ls -A "$deploy_directory" 2> /dev/null` && -z $allow_empty ]]; then
|
||||||
|
echo "Deploy directory '$deploy_directory' is empty. Aborting. If you're sure you want to deploy an empty tree, use the --allow-empty / -e flag." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if git ls-remote --exit-code $repo "refs/heads/$deploy_branch" ; then
|
||||||
|
# deploy_branch exists in $repo; make sure we have the latest version
|
||||||
|
|
||||||
|
disable_expanded_output
|
||||||
|
git fetch --force $repo $deploy_branch:$deploy_branch
|
||||||
|
enable_expanded_output
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check if deploy_branch exists locally
|
||||||
|
if git show-ref --verify --quiet "refs/heads/$deploy_branch"
|
||||||
|
then incremental_deploy
|
||||||
|
else initial_deploy
|
||||||
|
fi
|
||||||
|
|
||||||
|
restore_head
|
||||||
|
}
|
||||||
|
|
||||||
|
initial_deploy() {
|
||||||
|
git --work-tree "$deploy_directory" checkout --orphan $deploy_branch
|
||||||
|
git --work-tree "$deploy_directory" add --all
|
||||||
|
commit+push
|
||||||
|
}
|
||||||
|
|
||||||
|
incremental_deploy() {
|
||||||
|
#make deploy_branch the current branch
|
||||||
|
git symbolic-ref HEAD refs/heads/$deploy_branch
|
||||||
|
#put the previously committed contents of deploy_branch into the index
|
||||||
|
git --work-tree "$deploy_directory" reset --mixed --quiet
|
||||||
|
git --work-tree "$deploy_directory" add --all
|
||||||
|
|
||||||
|
set +o errexit
|
||||||
|
diff=$(git --work-tree "$deploy_directory" diff --exit-code --quiet HEAD --)$?
|
||||||
|
set -o errexit
|
||||||
|
case $diff in
|
||||||
|
0) echo No changes to files in $deploy_directory. Skipping commit.;;
|
||||||
|
1) commit+push;;
|
||||||
|
*)
|
||||||
|
echo git diff exited with code $diff. Aborting. Staying on branch $deploy_branch so you can debug. To switch back to main, use: git symbolic-ref HEAD refs/heads/main && git reset --mixed >&2
|
||||||
|
return $diff
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
commit+push() {
|
||||||
|
set_user_id
|
||||||
|
git --work-tree "$deploy_directory" commit -m "$commit_message"
|
||||||
|
|
||||||
|
disable_expanded_output
|
||||||
|
#--quiet is important here to avoid outputting the repo URL, which may contain a secret token
|
||||||
|
git push --quiet $repo $deploy_branch
|
||||||
|
enable_expanded_output
|
||||||
|
}
|
||||||
|
|
||||||
|
#echo expanded commands as they are executed (for debugging)
|
||||||
|
enable_expanded_output() {
|
||||||
|
if [ $verbose ]; then
|
||||||
|
set -o xtrace
|
||||||
|
set +o verbose
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#this is used to avoid outputting the repo URL, which may contain a secret token
|
||||||
|
disable_expanded_output() {
|
||||||
|
if [ $verbose ]; then
|
||||||
|
set +o xtrace
|
||||||
|
set -o verbose
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
set_user_id() {
|
||||||
|
if [[ -z `git config user.name` ]]; then
|
||||||
|
git config user.name "$default_username"
|
||||||
|
fi
|
||||||
|
if [[ -z `git config user.email` ]]; then
|
||||||
|
git config user.email "$default_email"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_head() {
|
||||||
|
if [[ $previous_branch = "HEAD" ]]; then
|
||||||
|
#we weren't on any branch before, so just set HEAD back to the commit it was on
|
||||||
|
git update-ref --no-deref HEAD $commit_hash $deploy_branch
|
||||||
|
else
|
||||||
|
git symbolic-ref HEAD refs/heads/$previous_branch
|
||||||
|
fi
|
||||||
|
|
||||||
|
git reset --mixed
|
||||||
|
}
|
||||||
|
|
||||||
|
filter() {
|
||||||
|
sed -e "s|$repo|\$repo|g"
|
||||||
|
}
|
||||||
|
|
||||||
|
sanitize() {
|
||||||
|
"$@" 2> >(filter 1>&2) | filter
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_args "$@"
|
||||||
|
|
||||||
|
if [ "${command}" = "serve" ]; then
|
||||||
|
run_serve
|
||||||
|
elif [[ "${command}" = "build" ]]; then
|
||||||
|
run_build
|
||||||
|
elif [[ ${command} = "deploy" ]]; then
|
||||||
|
if [[ ${no_build} != true ]]; then
|
||||||
|
run_build
|
||||||
|
fi
|
||||||
|
main "$@"
|
||||||
|
fi
|
BIN
docs/api/source/fonts/slate.eot
Normal file
BIN
docs/api/source/fonts/slate.eot
Normal file
Binary file not shown.
14
docs/api/source/fonts/slate.svg
Normal file
14
docs/api/source/fonts/slate.svg
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?>
|
||||||
|
<!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>
|
||||||
|
<font id="slate" horiz-adv-x="1024">
|
||||||
|
<font-face units-per-em="1024" ascent="960" descent="-64" />
|
||||||
|
<missing-glyph horiz-adv-x="1024" />
|
||||||
|
<glyph unicode=" " d="" horiz-adv-x="512" />
|
||||||
|
<glyph unicode="" d="M438.857 877.714q119.429 0 220.286-58.857t159.714-159.714 58.857-220.286-58.857-220.286-159.714-159.714-220.286-58.857-220.286 58.857-159.714 159.714-58.857 220.286 58.857 220.286 159.714 159.714 220.286 58.857zM512 165.143v108.571q0 8-5.143 13.429t-12.571 5.429h-109.714q-7.429 0-13.143-5.714t-5.714-13.143v-108.571q0-7.429 5.714-13.143t13.143-5.714h109.714q7.429 0 12.571 5.429t5.143 13.429zM510.857 361.714l10.286 354.857q0 6.857-5.714 10.286-5.714 4.571-13.714 4.571h-125.714q-8 0-13.714-4.571-5.714-3.429-5.714-10.286l9.714-354.857q0-5.714 5.714-10t13.714-4.286h105.714q8 0 13.429 4.286t6 10z" />
|
||||||
|
<glyph unicode="" d="M585.143 164.571v91.429q0 8-5.143 13.143t-13.143 5.143h-54.857v292.571q0 8-5.143 13.143t-13.143 5.143h-182.857q-8 0-13.143-5.143t-5.143-13.143v-91.429q0-8 5.143-13.143t13.143-5.143h54.857v-182.857h-54.857q-8 0-13.143-5.143t-5.143-13.143v-91.429q0-8 5.143-13.143t13.143-5.143h256q8 0 13.143 5.143t5.143 13.143zM512 676.571v91.429q0 8-5.143 13.143t-13.143 5.143h-109.714q-8 0-13.143-5.143t-5.143-13.143v-91.429q0-8 5.143-13.143t13.143-5.143h109.714q8 0 13.143 5.143t5.143 13.143zM877.714 438.857q0-119.429-58.857-220.286t-159.714-159.714-220.286-58.857-220.286 58.857-159.714 159.714-58.857 220.286 58.857 220.286 159.714 159.714 220.286 58.857 220.286-58.857 159.714-159.714 58.857-220.286z" />
|
||||||
|
<glyph unicode="" d="M733.714 531.428q0 16-10.286 26.286l-52 51.429q-10.857 10.857-25.714 10.857t-25.714-10.857l-233.143-232.571-129.143 129.143q-10.857 10.857-25.714 10.857t-25.714-10.857l-52-51.429q-10.286-10.286-10.286-26.286 0-15.429 10.286-25.714l206.857-206.857q10.857-10.857 25.714-10.857 15.429 0 26.286 10.857l310.286 310.286q10.286 10.286 10.286 25.714zM877.714 438.857q0-119.429-58.857-220.286t-159.714-159.714-220.286-58.857-220.286 58.857-159.714 159.714-58.857 220.286 58.857 220.286 159.714 159.714 220.286 58.857 220.286-58.857 159.714-159.714 58.857-220.286z" />
|
||||||
|
<glyph unicode="" d="M658.286 475.428q0 105.714-75.143 180.857t-180.857 75.143-180.857-75.143-75.143-180.857 75.143-180.857 180.857-75.143 180.857 75.143 75.143 180.857zM950.857 0q0-29.714-21.714-51.429t-51.429-21.714q-30.857 0-51.429 21.714l-196 195.429q-102.286-70.857-228-70.857-81.714 0-156.286 31.714t-128.571 85.714-85.714 128.571-31.714 156.286 31.714 156.286 85.714 128.571 128.571 85.714 156.286 31.714 156.286-31.714 128.571-85.714 85.714-128.571 31.714-156.286q0-125.714-70.857-228l196-196q21.143-21.143 21.143-51.429z" horiz-adv-x="951" />
|
||||||
|
</font></defs></svg>
|
After Width: | Height: | Size: 2.9 KiB |
BIN
docs/api/source/fonts/slate.ttf
Normal file
BIN
docs/api/source/fonts/slate.ttf
Normal file
Binary file not shown.
BIN
docs/api/source/fonts/slate.woff
Normal file
BIN
docs/api/source/fonts/slate.woff
Normal file
Binary file not shown.
BIN
docs/api/source/fonts/slate.woff2
Normal file
BIN
docs/api/source/fonts/slate.woff2
Normal file
Binary file not shown.
BIN
docs/api/source/images/logo.png
Normal file
BIN
docs/api/source/images/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 51 KiB |
BIN
docs/api/source/images/navbar.png
Normal file
BIN
docs/api/source/images/navbar.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 96 B |
126
docs/api/source/includes/_authentication.md
Normal file
126
docs/api/source/includes/_authentication.md
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
# Authentication
|
||||||
|
|
||||||
|
## v1/login
|
||||||
|
|
||||||
|
> To obtain a JWT token (Replace default credentials):
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl "https://goscrobble.com/api/v1/login" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data '{"username":"abc","password":"def"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
> Response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"token": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI6ZmFsc2UsImVtYWlsIjoidGVzdEB0ZXN0LmNvbSIsImV4cCI6MTY0MTAwMjUxOSwiaWF0IjoxNjQwMzk3NzE5LCJtb2QiOnRydWUsInJlZnJlc2hfZXhwIjoxNjQxMDAyNTE5LCJyZWZyZXNoX3Rva2VuIjoiYWJjZGVmZ2hqaWtsbW5vcHF3ZXJ0dXZ3eHl6Iiwic3ViIjoiNDE4ZmRkZmItOGIxYi01MWFiLTliZHMtNGZnMDhjYTYzY2ZmIiwidXNlcm5hbWUiOiJ0ZXN0In0.fuPXjQ7IzNyttgIKpdS4-KBQ-QeHTl-BfgYkSnMCmpVrBunzMrSwr1RzxI7Xg2WWF-FHtW3Bnv9RpSqLDN4F2g"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This endpoint is used to authenticate and retrieve a JWT token.
|
||||||
|
|
||||||
|
### HTTP Request
|
||||||
|
|
||||||
|
`POST https://goscrobble.com/api/v1/login`
|
||||||
|
|
||||||
|
### Query Parameters
|
||||||
|
|
||||||
|
Parameter | Required | Description
|
||||||
|
--------- | ------- | -----------
|
||||||
|
username | true | Account username
|
||||||
|
password | true | Account password
|
||||||
|
|
||||||
|
## v1/register
|
||||||
|
|
||||||
|
> Create a new account (Replace default credentials):
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl "https://goscrobble.com/api/v1/register" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data '{"email": "test@test.com", "username":"abc","password":"def"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
> Response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "User created succesfully. You may now login"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If the server has REGISTRATION_ENABLED=true set, this endpoint will allow you to create a new account. Password must be at least 8 characters long.
|
||||||
|
|
||||||
|
### HTTP Request
|
||||||
|
|
||||||
|
`POST https://goscrobble.com/api/v1/register`
|
||||||
|
|
||||||
|
### Query Parameters
|
||||||
|
|
||||||
|
Parameter | Required | Description
|
||||||
|
--------- | ------- | -----------
|
||||||
|
email | true | Account email
|
||||||
|
username | true | Account username
|
||||||
|
password | true | Account password
|
||||||
|
|
||||||
|
## v1/sendreset
|
||||||
|
|
||||||
|
> Trigger a password reset email:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl "https://goscrobble.com/api/v1/sendreset" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data '{"email":"test@test.com"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
> Response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "Password reset email sent"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This endpoint triggers a password reset email to be sent to the email on an account.
|
||||||
|
|
||||||
|
### HTTP Request
|
||||||
|
|
||||||
|
`POST https://goscrobble.com/api/v1/sendreset`
|
||||||
|
|
||||||
|
### Query Parameters
|
||||||
|
|
||||||
|
Parameter | Required | Description
|
||||||
|
--------- | ------- | -----------
|
||||||
|
email | true | Account username
|
||||||
|
|
||||||
|
## v1/resetpassword
|
||||||
|
|
||||||
|
> Trigger a password reset email:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl "https://goscrobble.com/api/v1/resetpassword" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data '{"token":"abcdefghijklmnopqrstuvwxyz", "password": "Hunter1"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
> Response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "Password updated successfully!"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This endpoint confirms a password reset with a valid hash from the reset email. You must call v1/sendreset first and obtain the hash.
|
||||||
|
|
||||||
|
### HTTP Request
|
||||||
|
|
||||||
|
`POST https://goscrobble.com/api/v1/resetpassword`
|
||||||
|
|
||||||
|
### Query Parameters
|
||||||
|
|
||||||
|
Parameter | Required | Description
|
||||||
|
--------- | ------- | -----------
|
||||||
|
token | true | Reset token from the password reset email
|
||||||
|
password | true | New account password
|
||||||
|
|
22
docs/api/source/includes/_errors.md
Normal file
22
docs/api/source/includes/_errors.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Errors
|
||||||
|
|
||||||
|
<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 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.
|
5
docs/api/source/includes/_introduction.md
Normal file
5
docs/api/source/includes/_introduction.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Introduction
|
||||||
|
|
||||||
|
Welcome to the GoScrobble API documentation.
|
||||||
|
|
||||||
|
The majority of these API endpoints are public with reasonable rate limits.
|
22
docs/api/source/includes/_serverinfo.md
Normal file
22
docs/api/source/includes/_serverinfo.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Server Info
|
||||||
|
## v1/serverinfo
|
||||||
|
> Check server version and registration status:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl "https://goscrobble.com/api/v1/serverinfo"
|
||||||
|
```
|
||||||
|
|
||||||
|
> Response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"version":"0.1.1",
|
||||||
|
"registration_enabled":"1"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This endpoint is used to get server API version and registration status.
|
||||||
|
|
||||||
|
### HTTP Request
|
||||||
|
|
||||||
|
`GET https://goscrobble.com/api/v1/serverstatus`
|
25
docs/api/source/index.html.md
Normal file
25
docs/api/source/index.html.md
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
title: GoScrobble API Documentation
|
||||||
|
|
||||||
|
language_tabs: # must be one of https://git.io/vQNgJ
|
||||||
|
- shell
|
||||||
|
|
||||||
|
toc_footers:
|
||||||
|
- <a href='https://goscrobble.com'>GoScrobble website</a>
|
||||||
|
- <a href='https://gitlab.com/goscrobble/goscrobble-api'>Backend Repository</a>
|
||||||
|
- <a href='https://gitlab.com/goscrobble/goscrobble-web'>Frontend Repository</a>
|
||||||
|
|
||||||
|
includes:
|
||||||
|
- introduction
|
||||||
|
- serverinfo
|
||||||
|
- authentication
|
||||||
|
|
||||||
|
search: true
|
||||||
|
|
||||||
|
code_clipboard: true
|
||||||
|
|
||||||
|
meta:
|
||||||
|
- name: description
|
||||||
|
content: Documentation for the GoScrobble API
|
||||||
|
---
|
||||||
|
|
2
docs/api/source/javascripts/all.js
Normal file
2
docs/api/source/javascripts/all.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
//= require ./all_nosearch
|
||||||
|
//= require ./app/_search
|
27
docs/api/source/javascripts/all_nosearch.js
Normal file
27
docs/api/source/javascripts/all_nosearch.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
//= require ./lib/_energize
|
||||||
|
//= require ./app/_copy
|
||||||
|
//= require ./app/_toc
|
||||||
|
//= require ./app/_lang
|
||||||
|
|
||||||
|
function adjustLanguageSelectorWidth() {
|
||||||
|
const elem = $('.dark-box > .lang-selector');
|
||||||
|
elem.width(elem.parent().width());
|
||||||
|
}
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
loadToc($('#toc'), '.toc-link', '.toc-list-h2', 10);
|
||||||
|
setupLanguages($('body').data('languages'));
|
||||||
|
$('.content').imagesLoaded( function() {
|
||||||
|
window.recacheHeights();
|
||||||
|
window.refreshToc();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(window).resize(function() {
|
||||||
|
adjustLanguageSelectorWidth();
|
||||||
|
});
|
||||||
|
adjustLanguageSelectorWidth();
|
||||||
|
});
|
||||||
|
|
||||||
|
window.onpopstate = function() {
|
||||||
|
activateLanguage(getLanguageFromQueryString());
|
||||||
|
};
|
15
docs/api/source/javascripts/app/_copy.js
Normal file
15
docs/api/source/javascripts/app/_copy.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
function copyToClipboard(container) {
|
||||||
|
const el = document.createElement('textarea');
|
||||||
|
el.value = container.textContent.replace(/\n$/, '');
|
||||||
|
document.body.appendChild(el);
|
||||||
|
el.select();
|
||||||
|
document.execCommand('copy');
|
||||||
|
document.body.removeChild(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupCodeCopy() {
|
||||||
|
$('pre.highlight').prepend('<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]);
|
||||||
|
});
|
||||||
|
}
|
171
docs/api/source/javascripts/app/_lang.js
Normal file
171
docs/api/source/javascripts/app/_lang.js
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
//= require ../lib/_jquery
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2008-2013 Concur Technologies, Inc.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
;(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var languages = [];
|
||||||
|
|
||||||
|
window.setupLanguages = setupLanguages;
|
||||||
|
window.activateLanguage = activateLanguage;
|
||||||
|
window.getLanguageFromQueryString = getLanguageFromQueryString;
|
||||||
|
|
||||||
|
function activateLanguage(language) {
|
||||||
|
if (!language) return;
|
||||||
|
if (language === "") return;
|
||||||
|
|
||||||
|
$(".lang-selector a").removeClass('active');
|
||||||
|
$(".lang-selector a[data-language-name='" + language + "']").addClass('active');
|
||||||
|
for (var i=0; i < languages.length; i++) {
|
||||||
|
$(".highlight.tab-" + languages[i]).hide();
|
||||||
|
$(".lang-specific." + languages[i]).hide();
|
||||||
|
}
|
||||||
|
$(".highlight.tab-" + language).show();
|
||||||
|
$(".lang-specific." + language).show();
|
||||||
|
|
||||||
|
window.recacheHeights();
|
||||||
|
|
||||||
|
// scroll to the new location of the position
|
||||||
|
if ($(window.location.hash).get(0)) {
|
||||||
|
$(window.location.hash).get(0).scrollIntoView(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseURL and stringifyURL are from https://github.com/sindresorhus/query-string
|
||||||
|
// MIT licensed
|
||||||
|
// https://github.com/sindresorhus/query-string/blob/7bee64c16f2da1a326579e96977b9227bf6da9e6/license
|
||||||
|
function parseURL(str) {
|
||||||
|
if (typeof str !== 'string') {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
str = str.trim().replace(/^(\?|#|&)/, '');
|
||||||
|
|
||||||
|
if (!str) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return str.split('&').reduce(function (ret, param) {
|
||||||
|
var parts = param.replace(/\+/g, ' ').split('=');
|
||||||
|
var key = parts[0];
|
||||||
|
var val = parts[1];
|
||||||
|
|
||||||
|
key = decodeURIComponent(key);
|
||||||
|
// missing `=` should be `null`:
|
||||||
|
// http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
|
||||||
|
val = val === undefined ? null : decodeURIComponent(val);
|
||||||
|
|
||||||
|
if (!ret.hasOwnProperty(key)) {
|
||||||
|
ret[key] = val;
|
||||||
|
} else if (Array.isArray(ret[key])) {
|
||||||
|
ret[key].push(val);
|
||||||
|
} else {
|
||||||
|
ret[key] = [ret[key], val];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}, {});
|
||||||
|
};
|
||||||
|
|
||||||
|
function stringifyURL(obj) {
|
||||||
|
return obj ? Object.keys(obj).sort().map(function (key) {
|
||||||
|
var val = obj[key];
|
||||||
|
|
||||||
|
if (Array.isArray(val)) {
|
||||||
|
return val.sort().map(function (val2) {
|
||||||
|
return encodeURIComponent(key) + '=' + encodeURIComponent(val2);
|
||||||
|
}).join('&');
|
||||||
|
}
|
||||||
|
|
||||||
|
return encodeURIComponent(key) + '=' + encodeURIComponent(val);
|
||||||
|
}).join('&') : '';
|
||||||
|
};
|
||||||
|
|
||||||
|
// gets the language set in the query string
|
||||||
|
function getLanguageFromQueryString() {
|
||||||
|
if (location.search.length >= 1) {
|
||||||
|
var language = parseURL(location.search).language;
|
||||||
|
if (language) {
|
||||||
|
return language;
|
||||||
|
} else if (jQuery.inArray(location.search.substr(1), languages) != -1) {
|
||||||
|
return location.search.substr(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns a new query string with the new language in it
|
||||||
|
function generateNewQueryString(language) {
|
||||||
|
var url = parseURL(location.search);
|
||||||
|
if (url.language) {
|
||||||
|
url.language = language;
|
||||||
|
return stringifyURL(url);
|
||||||
|
}
|
||||||
|
return language;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if a button is clicked, add the state to the history
|
||||||
|
function pushURL(language) {
|
||||||
|
if (!history) { return; }
|
||||||
|
var hash = window.location.hash;
|
||||||
|
if (hash) {
|
||||||
|
hash = hash.replace(/^#+/, '');
|
||||||
|
}
|
||||||
|
history.pushState({}, '', '?' + generateNewQueryString(language) + '#' + hash);
|
||||||
|
|
||||||
|
// save language as next default
|
||||||
|
if (localStorage) {
|
||||||
|
localStorage.setItem("language", language);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupLanguages(l) {
|
||||||
|
var defaultLanguage = null;
|
||||||
|
if (localStorage) {
|
||||||
|
defaultLanguage = localStorage.getItem("language");
|
||||||
|
}
|
||||||
|
|
||||||
|
languages = l;
|
||||||
|
|
||||||
|
var presetLanguage = getLanguageFromQueryString();
|
||||||
|
if (presetLanguage) {
|
||||||
|
// the language is in the URL, so use that language!
|
||||||
|
activateLanguage(presetLanguage);
|
||||||
|
|
||||||
|
if (localStorage) {
|
||||||
|
localStorage.setItem("language", presetLanguage);
|
||||||
|
}
|
||||||
|
} else if ((defaultLanguage !== null) && (jQuery.inArray(defaultLanguage, languages) != -1)) {
|
||||||
|
// the language was the last selected one saved in localstorage, so use that language!
|
||||||
|
activateLanguage(defaultLanguage);
|
||||||
|
} else {
|
||||||
|
// no language selected, so use the default
|
||||||
|
activateLanguage(languages[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we click on a language tab, activate that language
|
||||||
|
$(function() {
|
||||||
|
$(".lang-selector a").on("click", function() {
|
||||||
|
var language = $(this).data("language-name");
|
||||||
|
pushURL(language);
|
||||||
|
activateLanguage(language);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})();
|
102
docs/api/source/javascripts/app/_search.js
Normal file
102
docs/api/source/javascripts/app/_search.js
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
//= require ../lib/_lunr
|
||||||
|
//= require ../lib/_jquery
|
||||||
|
//= require ../lib/_jquery.highlight
|
||||||
|
;(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var content, searchResults;
|
||||||
|
var highlightOpts = { element: 'span', className: 'search-highlight' };
|
||||||
|
var searchDelay = 0;
|
||||||
|
var timeoutHandle = 0;
|
||||||
|
var index;
|
||||||
|
|
||||||
|
function populate() {
|
||||||
|
index = lunr(function(){
|
||||||
|
|
||||||
|
this.ref('id');
|
||||||
|
this.field('title', { boost: 10 });
|
||||||
|
this.field('body');
|
||||||
|
this.pipeline.add(lunr.trimmer, lunr.stopWordFilter);
|
||||||
|
var lunrConfig = this;
|
||||||
|
|
||||||
|
$('h1, h2').each(function() {
|
||||||
|
var title = $(this);
|
||||||
|
var body = title.nextUntil('h1, h2');
|
||||||
|
lunrConfig.add({
|
||||||
|
id: title.prop('id'),
|
||||||
|
title: title.text(),
|
||||||
|
body: body.text()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
determineSearchDelay();
|
||||||
|
}
|
||||||
|
|
||||||
|
$(populate);
|
||||||
|
$(bind);
|
||||||
|
|
||||||
|
function determineSearchDelay() {
|
||||||
|
if (index.tokenSet.toArray().length>5000) {
|
||||||
|
searchDelay = 300;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function bind() {
|
||||||
|
content = $('.content');
|
||||||
|
searchResults = $('.search-results');
|
||||||
|
|
||||||
|
$('#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) searchInput.value = '';
|
||||||
|
|
||||||
|
if (searchInput.value) {
|
||||||
|
var results = index.search(searchInput.value).filter(function(r) {
|
||||||
|
return r.score > 0.0001;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (results.length) {
|
||||||
|
searchResults.empty();
|
||||||
|
$.each(results, function (index, result) {
|
||||||
|
var elem = document.getElementById(result.ref);
|
||||||
|
searchResults.append("<li><a href='#" + result.ref + "'>" + $(elem).text() + "</a></li>");
|
||||||
|
});
|
||||||
|
highlight.call(searchInput);
|
||||||
|
} else {
|
||||||
|
searchResults.html('<li></li>');
|
||||||
|
$('.search-results li').text('No Results Found for "' + searchInput.value + '"');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unhighlight();
|
||||||
|
searchResults.removeClass('visible');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function highlight() {
|
||||||
|
if (this.value) content.highlight(this.value, highlightOpts);
|
||||||
|
}
|
||||||
|
|
||||||
|
function unhighlight() {
|
||||||
|
content.unhighlight(highlightOpts);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
122
docs/api/source/javascripts/app/_toc.js
Normal file
122
docs/api/source/javascripts/app/_toc.js
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
//= require ../lib/_jquery
|
||||||
|
//= require ../lib/_imagesloaded.min
|
||||||
|
;(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() {
|
||||||
|
$(".toc-wrapper").removeClass('open');
|
||||||
|
$("#nav-button").removeClass('open');
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
var best = null;
|
||||||
|
for (var name in headerHeights) {
|
||||||
|
if ((headerHeights[name] < currentTop && headerHeights[name] > headerHeights[best]) || best === null) {
|
||||||
|
best = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Catch the initial load case
|
||||||
|
if (currentTop == scrollOffset && !loaded) {
|
||||||
|
best = window.location.hash;
|
||||||
|
loaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.loadToc = loadToc;
|
||||||
|
})();
|
169
docs/api/source/javascripts/lib/_energize.js
Normal file
169
docs/api/source/javascripts/lib/_energize.js
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
/**
|
||||||
|
* energize.js v0.1.0
|
||||||
|
*
|
||||||
|
* Speeds up click events on mobile devices.
|
||||||
|
* https://github.com/davidcalhoun/energize.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function() { // Sandbox
|
||||||
|
/**
|
||||||
|
* Don't add to non-touch devices, which don't need to be sped up
|
||||||
|
*/
|
||||||
|
if(!('ontouchstart' in window)) return;
|
||||||
|
|
||||||
|
var lastClick = {},
|
||||||
|
isThresholdReached, touchstart, touchmove, touchend,
|
||||||
|
click, closest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* isThresholdReached
|
||||||
|
*
|
||||||
|
* Compare touchstart with touchend xy coordinates,
|
||||||
|
* and only fire simulated click event if the coordinates
|
||||||
|
* are nearby. (don't want clicking to be confused with a swipe)
|
||||||
|
*/
|
||||||
|
isThresholdReached = function(startXY, xy) {
|
||||||
|
return Math.abs(startXY[0] - xy[0]) > 5 || Math.abs(startXY[1] - xy[1]) > 5;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* touchstart
|
||||||
|
*
|
||||||
|
* Save xy coordinates when the user starts touching the screen
|
||||||
|
*/
|
||||||
|
touchstart = function(e) {
|
||||||
|
this.startXY = [e.touches[0].clientX, e.touches[0].clientY];
|
||||||
|
this.threshold = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* touchmove
|
||||||
|
*
|
||||||
|
* Check if the user is scrolling past the threshold.
|
||||||
|
* Have to check here because touchend will not always fire
|
||||||
|
* on some tested devices (Kindle Fire?)
|
||||||
|
*/
|
||||||
|
touchmove = function(e) {
|
||||||
|
// NOOP if the threshold has already been reached
|
||||||
|
if(this.threshold) return false;
|
||||||
|
|
||||||
|
this.threshold = isThresholdReached(this.startXY, [e.touches[0].clientX, e.touches[0].clientY]);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* touchend
|
||||||
|
*
|
||||||
|
* If the user didn't scroll past the threshold between
|
||||||
|
* touchstart and touchend, fire a simulated click.
|
||||||
|
*
|
||||||
|
* (This will fire before a native click)
|
||||||
|
*/
|
||||||
|
touchend = function(e) {
|
||||||
|
// Don't fire a click if the user scrolled past the threshold
|
||||||
|
if(this.threshold || isThresholdReached(this.startXY, [e.changedTouches[0].clientX, e.changedTouches[0].clientY])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and fire a click event on the target element
|
||||||
|
* https://developer.mozilla.org/en/DOM/event.initMouseEvent
|
||||||
|
*/
|
||||||
|
var touch = e.changedTouches[0],
|
||||||
|
evt = document.createEvent('MouseEvents');
|
||||||
|
evt.initMouseEvent('click', true, true, window, 0, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
|
||||||
|
evt.simulated = true; // distinguish from a normal (nonsimulated) click
|
||||||
|
e.target.dispatchEvent(evt);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* click
|
||||||
|
*
|
||||||
|
* Because we've already fired a click event in touchend,
|
||||||
|
* we need to listed for all native click events here
|
||||||
|
* and suppress them as necessary.
|
||||||
|
*/
|
||||||
|
click = function(e) {
|
||||||
|
/**
|
||||||
|
* Prevent ghost clicks by only allowing clicks we created
|
||||||
|
* in the click event we fired (look for e.simulated)
|
||||||
|
*/
|
||||||
|
var time = Date.now(),
|
||||||
|
timeDiff = time - lastClick.time,
|
||||||
|
x = e.clientX,
|
||||||
|
y = e.clientY,
|
||||||
|
xyDiff = [Math.abs(lastClick.x - x), Math.abs(lastClick.y - y)],
|
||||||
|
target = closest(e.target, 'A') || e.target, // needed for standalone apps
|
||||||
|
nodeName = target.nodeName,
|
||||||
|
isLink = nodeName === 'A',
|
||||||
|
standAlone = window.navigator.standalone && isLink && e.target.getAttribute("href");
|
||||||
|
|
||||||
|
lastClick.time = time;
|
||||||
|
lastClick.x = x;
|
||||||
|
lastClick.y = y;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unfortunately Android sometimes fires click events without touch events (seen on Kindle Fire),
|
||||||
|
* so we have to add more logic to determine the time of the last click. Not perfect...
|
||||||
|
*
|
||||||
|
* Older, simpler check: if((!e.simulated) || standAlone)
|
||||||
|
*/
|
||||||
|
if((!e.simulated && (timeDiff < 500 || (timeDiff < 1500 && xyDiff[0] < 50 && xyDiff[1] < 50))) || standAlone) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
if(!standAlone) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Special logic for standalone web apps
|
||||||
|
* See http://stackoverflow.com/questions/2898740/iphone-safari-web-app-opens-links-in-new-window
|
||||||
|
*/
|
||||||
|
if(standAlone) {
|
||||||
|
window.location = target.getAttribute("href");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an energize-focus class to the targeted link (mimics :focus behavior)
|
||||||
|
* TODO: test and/or remove? Does this work?
|
||||||
|
*/
|
||||||
|
if(!target || !target.classList) return;
|
||||||
|
target.classList.add("energize-focus");
|
||||||
|
window.setTimeout(function(){
|
||||||
|
target.classList.remove("energize-focus");
|
||||||
|
}, 150);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* closest
|
||||||
|
* @param {HTMLElement} node current node to start searching from.
|
||||||
|
* @param {string} tagName the (uppercase) name of the tag you're looking for.
|
||||||
|
*
|
||||||
|
* Find the closest ancestor tag of a given node.
|
||||||
|
*
|
||||||
|
* Starts at node and goes up the DOM tree looking for a
|
||||||
|
* matching nodeName, continuing until hitting document.body
|
||||||
|
*/
|
||||||
|
closest = function(node, tagName){
|
||||||
|
var curNode = node;
|
||||||
|
|
||||||
|
while(curNode !== document.body) { // go up the dom until we find the tag we're after
|
||||||
|
if(!curNode || curNode.nodeName === tagName) { return curNode; } // found
|
||||||
|
curNode = curNode.parentNode; // not found, so keep going up
|
||||||
|
}
|
||||||
|
|
||||||
|
return null; // not found
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add all delegated event listeners
|
||||||
|
*
|
||||||
|
* All the events we care about bubble up to document,
|
||||||
|
* so we can take advantage of event delegation.
|
||||||
|
*
|
||||||
|
* Note: no need to wait for DOMContentLoaded here
|
||||||
|
*/
|
||||||
|
document.addEventListener('touchstart', touchstart, false);
|
||||||
|
document.addEventListener('touchmove', touchmove, false);
|
||||||
|
document.addEventListener('touchend', touchend, false);
|
||||||
|
document.addEventListener('click', click, true); // TODO: why does this use capture?
|
||||||
|
|
||||||
|
})();
|
7
docs/api/source/javascripts/lib/_imagesloaded.min.js
vendored
Normal file
7
docs/api/source/javascripts/lib/_imagesloaded.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
108
docs/api/source/javascripts/lib/_jquery.highlight.js
Normal file
108
docs/api/source/javascripts/lib/_jquery.highlight.js
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* jQuery Highlight plugin
|
||||||
|
*
|
||||||
|
* Based on highlight v3 by Johann Burkard
|
||||||
|
* 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:
|
||||||
|
* - has an option to highlight only entire words (wordsOnly - false by default),
|
||||||
|
* - has an option to be case sensitive (caseSensitive - false by default)
|
||||||
|
* - highlight element tag and class names can be specified in options
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* // wrap every occurrance of text 'lorem' in content
|
||||||
|
* // with <span class='highlight'> (default options)
|
||||||
|
* $('#content').highlight('lorem');
|
||||||
|
*
|
||||||
|
* // search for and highlight more terms at once
|
||||||
|
* // so you can save some time on traversing DOM
|
||||||
|
* $('#content').highlight(['lorem', 'ipsum']);
|
||||||
|
* $('#content').highlight('lorem ipsum');
|
||||||
|
*
|
||||||
|
* // search only for entire word 'lorem'
|
||||||
|
* $('#content').highlight('lorem', { wordsOnly: true });
|
||||||
|
*
|
||||||
|
* // don't ignore case during search of term 'lorem'
|
||||||
|
* $('#content').highlight('lorem', { caseSensitive: true });
|
||||||
|
*
|
||||||
|
* // wrap every occurrance of term 'ipsum' in content
|
||||||
|
* // with <em class='important'>
|
||||||
|
* $('#content').highlight('ipsum', { element: 'em', className: 'important' });
|
||||||
|
*
|
||||||
|
* // remove default highlight
|
||||||
|
* $('#content').unhighlight();
|
||||||
|
*
|
||||||
|
* // remove custom highlight
|
||||||
|
* $('#content').unhighlight({ element: 'em', className: 'important' });
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009 Bartek Szopka
|
||||||
|
*
|
||||||
|
* Licensed under MIT license.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
jQuery.extend({
|
||||||
|
highlight: function (node, re, nodeName, className) {
|
||||||
|
if (node.nodeType === 3) {
|
||||||
|
var match = node.data.match(re);
|
||||||
|
if (match) {
|
||||||
|
var highlight = document.createElement(nodeName || 'span');
|
||||||
|
highlight.className = className || 'highlight';
|
||||||
|
var wordNode = node.splitText(match.index);
|
||||||
|
wordNode.splitText(match[0].length);
|
||||||
|
var wordClone = wordNode.cloneNode(true);
|
||||||
|
highlight.appendChild(wordClone);
|
||||||
|
wordNode.parentNode.replaceChild(highlight, wordNode);
|
||||||
|
return 1; //skip added node in parent
|
||||||
|
}
|
||||||
|
} else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
|
||||||
|
!/(script|style)/i.test(node.tagName) && // ignore script and style nodes
|
||||||
|
!(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted
|
||||||
|
for (var i = 0; i < node.childNodes.length; i++) {
|
||||||
|
i += jQuery.highlight(node.childNodes[i], re, nodeName, className);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
jQuery.fn.unhighlight = function (options) {
|
||||||
|
var settings = { className: 'highlight', element: 'span' };
|
||||||
|
jQuery.extend(settings, options);
|
||||||
|
|
||||||
|
return this.find(settings.element + "." + settings.className).each(function () {
|
||||||
|
var parent = this.parentNode;
|
||||||
|
parent.replaceChild(this.firstChild, this);
|
||||||
|
parent.normalize();
|
||||||
|
}).end();
|
||||||
|
};
|
||||||
|
|
||||||
|
jQuery.fn.highlight = function (words, options) {
|
||||||
|
var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false };
|
||||||
|
jQuery.extend(settings, options);
|
||||||
|
|
||||||
|
if (words.constructor === String) {
|
||||||
|
words = [words];
|
||||||
|
}
|
||||||
|
words = jQuery.grep(words, function(word, i){
|
||||||
|
return word != '';
|
||||||
|
});
|
||||||
|
words = jQuery.map(words, function(word, i) {
|
||||||
|
return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
||||||
|
});
|
||||||
|
if (words.length == 0) { return this; };
|
||||||
|
|
||||||
|
var flag = settings.caseSensitive ? "" : "i";
|
||||||
|
var pattern = "(" + words.join("|") + ")";
|
||||||
|
if (settings.wordsOnly) {
|
||||||
|
pattern = "\\b" + pattern + "\\b";
|
||||||
|
}
|
||||||
|
var re = new RegExp(pattern, flag);
|
||||||
|
|
||||||
|
return this.each(function () {
|
||||||
|
jQuery.highlight(this, re, settings.element, settings.className);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
10881
docs/api/source/javascripts/lib/_jquery.js
Normal file
10881
docs/api/source/javascripts/lib/_jquery.js
Normal file
File diff suppressed because it is too large
Load Diff
3475
docs/api/source/javascripts/lib/_lunr.js
Normal file
3475
docs/api/source/javascripts/lib/_lunr.js
Normal file
File diff suppressed because it is too large
Load Diff
137
docs/api/source/layouts/layout.erb
Normal file
137
docs/api/source/layouts/layout.erb
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
<%#
|
||||||
|
Copyright 2008-2013 Concur Technologies, Inc.
|
||||||
|
|
||||||
|
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.
|
||||||
|
%>
|
||||||
|
<% 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>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||||
|
<% if current_page.data.key?('meta') %>
|
||||||
|
<% current_page.data.meta.each do |meta| %>
|
||||||
|
<meta
|
||||||
|
<% meta.each do |key, value| %>
|
||||||
|
<%= "#{key}=\"#{value}\"" %>
|
||||||
|
<% end %>
|
||||||
|
>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
<title><%= current_page.data.title || "API Documentation" %></title>
|
||||||
|
|
||||||
|
<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 %>
|
||||||
|
<% if current_page.data.search %>
|
||||||
|
<%= javascript_include_tag "all" %>
|
||||||
|
<% 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 %>">
|
||||||
|
<a href="#" id="nav-button">
|
||||||
|
<span>
|
||||||
|
NAV
|
||||||
|
<%= image_tag('navbar.png') %>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
<div class="toc-wrapper">
|
||||||
|
<%= image_tag "logo.png", class: 'logo' %>
|
||||||
|
<% if language_tabs.any? %>
|
||||||
|
<div class="lang-selector">
|
||||||
|
<% language_tabs.each do |lang| %>
|
||||||
|
<% if lang.is_a? Hash %>
|
||||||
|
<a href="#" data-language-name="<%= lang.keys.first %>"><%= lang.values.first %></a>
|
||||||
|
<% else %>
|
||||||
|
<a href="#" data-language-name="<%= lang %>"><%= lang %></a>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<% if current_page.data.search %>
|
||||||
|
<div class="search">
|
||||||
|
<input type="text" class="search" id="input-search" placeholder="Search">
|
||||||
|
</div>
|
||||||
|
<ul class="search-results"></ul>
|
||||||
|
<% end %>
|
||||||
|
<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| %>
|
||||||
|
<li><%= footer %></li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<div class="page-wrapper">
|
||||||
|
<div class="dark-box"></div>
|
||||||
|
<div class="content">
|
||||||
|
<%= page_content %>
|
||||||
|
</div>
|
||||||
|
<div class="dark-box">
|
||||||
|
<% if language_tabs.any? %>
|
||||||
|
<div class="lang-selector">
|
||||||
|
<% language_tabs.each do |lang| %>
|
||||||
|
<% if lang.is_a? Hash %>
|
||||||
|
<a href="#" data-language-name="<%= lang.keys.first %>"><%= lang.values.first %></a>
|
||||||
|
<% else %>
|
||||||
|
<a href="#" data-language-name="<%= lang %>"><%= lang %></a>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
38
docs/api/source/stylesheets/_icon-font.scss
Normal file
38
docs/api/source/stylesheets/_icon-font.scss
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'slate';
|
||||||
|
src:font-url('slate.eot?-syv14m');
|
||||||
|
src:font-url('slate.eot?#iefix-syv14m') format('embedded-opentype'),
|
||||||
|
font-url('slate.woff2?-syv14m') format('woff2'),
|
||||||
|
font-url('slate.woff?-syv14m') format('woff'),
|
||||||
|
font-url('slate.ttf?-syv14m') format('truetype'),
|
||||||
|
font-url('slate.svg?-syv14m#slate') format('svg');
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
%icon {
|
||||||
|
font-family: 'slate';
|
||||||
|
speak: none;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
font-variant: normal;
|
||||||
|
text-transform: none;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
%icon-exclamation-sign {
|
||||||
|
@extend %icon;
|
||||||
|
content: "\e600";
|
||||||
|
}
|
||||||
|
%icon-info-sign {
|
||||||
|
@extend %icon;
|
||||||
|
content: "\e602";
|
||||||
|
}
|
||||||
|
%icon-ok-sign {
|
||||||
|
@extend %icon;
|
||||||
|
content: "\e606";
|
||||||
|
}
|
||||||
|
%icon-search {
|
||||||
|
@extend %icon;
|
||||||
|
content: "\e607";
|
||||||
|
}
|
427
docs/api/source/stylesheets/_normalize.scss
Normal file
427
docs/api/source/stylesheets/_normalize.scss
Normal file
@ -0,0 +1,427 @@
|
|||||||
|
/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Set default font family to sans-serif.
|
||||||
|
* 2. Prevent iOS text size adjust after orientation change, without disabling
|
||||||
|
* user zoom.
|
||||||
|
*/
|
||||||
|
|
||||||
|
html {
|
||||||
|
font-family: sans-serif; /* 1 */
|
||||||
|
-ms-text-size-adjust: 100%; /* 2 */
|
||||||
|
-webkit-text-size-adjust: 100%; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove default margin.
|
||||||
|
*/
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* HTML5 display definitions
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correct `block` display not defined for any HTML5 element in IE 8/9.
|
||||||
|
* Correct `block` display not defined for `details` or `summary` in IE 10/11
|
||||||
|
* and Firefox.
|
||||||
|
* Correct `block` display not defined for `main` in IE 11.
|
||||||
|
*/
|
||||||
|
|
||||||
|
article,
|
||||||
|
aside,
|
||||||
|
details,
|
||||||
|
figcaption,
|
||||||
|
figure,
|
||||||
|
footer,
|
||||||
|
header,
|
||||||
|
hgroup,
|
||||||
|
main,
|
||||||
|
menu,
|
||||||
|
nav,
|
||||||
|
section,
|
||||||
|
summary {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct `inline-block` display not defined in IE 8/9.
|
||||||
|
* 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
|
||||||
|
*/
|
||||||
|
|
||||||
|
audio,
|
||||||
|
canvas,
|
||||||
|
progress,
|
||||||
|
video {
|
||||||
|
display: inline-block; /* 1 */
|
||||||
|
vertical-align: baseline; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent modern browsers from displaying `audio` without controls.
|
||||||
|
* Remove excess height in iOS 5 devices.
|
||||||
|
*/
|
||||||
|
|
||||||
|
audio:not([controls]) {
|
||||||
|
display: none;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address `[hidden]` styling not present in IE 8/9/10.
|
||||||
|
* Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[hidden],
|
||||||
|
template {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Links
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the gray background color from active links in IE 10.
|
||||||
|
*/
|
||||||
|
|
||||||
|
a {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Improve readability when focused and also mouse hovered in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
a:active,
|
||||||
|
a:hover {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Text-level semantics
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address styling not present in IE 8/9/10/11, Safari, and Chrome.
|
||||||
|
*/
|
||||||
|
|
||||||
|
abbr[title] {
|
||||||
|
border-bottom: 1px dotted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
|
||||||
|
*/
|
||||||
|
|
||||||
|
b,
|
||||||
|
strong {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address styling not present in Safari and Chrome.
|
||||||
|
*/
|
||||||
|
|
||||||
|
dfn {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address variable `h1` font-size and margin within `section` and `article`
|
||||||
|
* contexts in Firefox 4+, Safari, and Chrome.
|
||||||
|
*/
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 2em;
|
||||||
|
margin: 0.67em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address styling not present in IE 8/9.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mark {
|
||||||
|
background: #ff0;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address inconsistent and variable font size in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent `sub` and `sup` affecting `line-height` in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sub,
|
||||||
|
sup {
|
||||||
|
font-size: 75%;
|
||||||
|
line-height: 0;
|
||||||
|
position: relative;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
sup {
|
||||||
|
top: -0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub {
|
||||||
|
bottom: -0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Embedded content
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove border when inside `a` element in IE 8/9/10.
|
||||||
|
*/
|
||||||
|
|
||||||
|
img {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correct overflow not hidden in IE 9/10/11.
|
||||||
|
*/
|
||||||
|
|
||||||
|
svg:not(:root) {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grouping content
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address margin not present in IE 8/9 and Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
figure {
|
||||||
|
margin: 1em 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address differences between Firefox and other browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
hr {
|
||||||
|
-moz-box-sizing: content-box;
|
||||||
|
box-sizing: content-box;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contain overflow in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
pre {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address odd `em`-unit font size rendering in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
code,
|
||||||
|
kbd,
|
||||||
|
pre,
|
||||||
|
samp {
|
||||||
|
font-family: monospace, monospace;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Forms
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Known limitation: by default, Chrome and Safari on OS X allow very limited
|
||||||
|
* styling of `select`, unless a `border` property is set.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct color not being inherited.
|
||||||
|
* Known issue: affects color of disabled elements.
|
||||||
|
* 2. Correct font properties not being inherited.
|
||||||
|
* 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
input,
|
||||||
|
optgroup,
|
||||||
|
select,
|
||||||
|
textarea {
|
||||||
|
color: inherit; /* 1 */
|
||||||
|
font: inherit; /* 2 */
|
||||||
|
margin: 0; /* 3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address `overflow` set to `hidden` in IE 8/9/10/11.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address inconsistent `text-transform` inheritance for `button` and `select`.
|
||||||
|
* All other form control elements do not inherit `text-transform` values.
|
||||||
|
* Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
|
||||||
|
* Correct `select` style inheritance in Firefox.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
select {
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
|
||||||
|
* and `video` controls.
|
||||||
|
* 2. Correct inability to style clickable `input` types in iOS.
|
||||||
|
* 3. Improve usability and consistency of cursor style between image-type
|
||||||
|
* `input` and others.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
html input[type="button"], /* 1 */
|
||||||
|
input[type="reset"],
|
||||||
|
input[type="submit"] {
|
||||||
|
-webkit-appearance: button; /* 2 */
|
||||||
|
cursor: pointer; /* 3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-set default cursor for disabled elements.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button[disabled],
|
||||||
|
html input[disabled] {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove inner padding and border in Firefox 4+.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button::-moz-focus-inner,
|
||||||
|
input::-moz-focus-inner {
|
||||||
|
border: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address Firefox 4+ setting `line-height` on `input` using `!important` in
|
||||||
|
* the UA stylesheet.
|
||||||
|
*/
|
||||||
|
|
||||||
|
input {
|
||||||
|
line-height: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* It's recommended that you don't attempt to style these elements.
|
||||||
|
* Firefox's implementation doesn't respect box-sizing, padding, or width.
|
||||||
|
*
|
||||||
|
* 1. Address box sizing set to `content-box` in IE 8/9/10.
|
||||||
|
* 2. Remove excess padding in IE 8/9/10.
|
||||||
|
*/
|
||||||
|
|
||||||
|
input[type="checkbox"],
|
||||||
|
input[type="radio"] {
|
||||||
|
box-sizing: border-box; /* 1 */
|
||||||
|
padding: 0; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fix the cursor style for Chrome's increment/decrement buttons. For certain
|
||||||
|
* `font-size` values of the `input`, it causes the cursor style of the
|
||||||
|
* decrement button to change from `default` to `text`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
input[type="number"]::-webkit-inner-spin-button,
|
||||||
|
input[type="number"]::-webkit-outer-spin-button {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Address `appearance` set to `searchfield` in Safari and Chrome.
|
||||||
|
* 2. Address `box-sizing` set to `border-box` in Safari and Chrome
|
||||||
|
* (include `-moz` to future-proof).
|
||||||
|
*/
|
||||||
|
|
||||||
|
input[type="search"] {
|
||||||
|
-webkit-appearance: textfield; /* 1 */
|
||||||
|
-moz-box-sizing: content-box;
|
||||||
|
-webkit-box-sizing: content-box; /* 2 */
|
||||||
|
box-sizing: content-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove inner padding and search cancel button in Safari and Chrome on OS X.
|
||||||
|
* Safari (but not Chrome) clips the cancel button when the search input has
|
||||||
|
* padding (and `textfield` appearance).
|
||||||
|
*/
|
||||||
|
|
||||||
|
input[type="search"]::-webkit-search-cancel-button,
|
||||||
|
input[type="search"]::-webkit-search-decoration {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define consistent border, margin, and padding.
|
||||||
|
*/
|
||||||
|
|
||||||
|
fieldset {
|
||||||
|
border: 1px solid #c0c0c0;
|
||||||
|
margin: 0 2px;
|
||||||
|
padding: 0.35em 0.625em 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct `color` not being inherited in IE 8/9/10/11.
|
||||||
|
* 2. Remove padding so people aren't caught out if they zero out fieldsets.
|
||||||
|
*/
|
||||||
|
|
||||||
|
legend {
|
||||||
|
border: 0; /* 1 */
|
||||||
|
padding: 0; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove default vertical scrollbar in IE 8/9/10/11.
|
||||||
|
*/
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Don't inherit the `font-weight` (applied by a rule above).
|
||||||
|
* NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
|
||||||
|
*/
|
||||||
|
|
||||||
|
optgroup {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tables
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove most spacing between table cells.
|
||||||
|
*/
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
td,
|
||||||
|
th {
|
||||||
|
padding: 0;
|
||||||
|
}
|
140
docs/api/source/stylesheets/_rtl.scss
Normal file
140
docs/api/source/stylesheets/_rtl.scss
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
103
docs/api/source/stylesheets/_variables.scss
Normal file
103
docs/api/source/stylesheets/_variables.scss
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2008-2013 Concur Technologies, Inc.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// CUSTOMIZE SLATE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Use these settings to help adjust the appearance of Slate
|
||||||
|
|
||||||
|
|
||||||
|
// BACKGROUND COLORS
|
||||||
|
////////////////////
|
||||||
|
$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: #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: #F3F7F9 !default;
|
||||||
|
$aside-notice-bg: #8fbcd4 !default;
|
||||||
|
$aside-warning-bg: #c97a7e !default;
|
||||||
|
$aside-success-bg: #6ac174 !default;
|
||||||
|
$search-notice-bg: #c97a7e !default;
|
||||||
|
|
||||||
|
|
||||||
|
// TEXT COLORS
|
||||||
|
////////////////////
|
||||||
|
$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
|
||||||
|
|
||||||
|
|
||||||
|
// SIZES
|
||||||
|
////////////////////
|
||||||
|
$nav-width: 230px !default; // width of the navbar
|
||||||
|
$examples-width: 50% !default; // portion of the screen taken up by code examples
|
||||||
|
$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
|
||||||
|
$nav-indent: 10px !default; // extra padding for ToC subitems
|
||||||
|
$code-annotation-padding: 13px !default; // padding inside code annotations
|
||||||
|
$h1-margin-bottom: 21px !default; // padding under the largest header tags
|
||||||
|
$tablet-width: 930px !default; // min width before reverting to tablet size
|
||||||
|
$phone-width: $tablet-width - $nav-width !default; // min width before reverting to mobile size
|
||||||
|
|
||||||
|
|
||||||
|
// FONTS
|
||||||
|
////////////////////
|
||||||
|
%default-font {
|
||||||
|
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 {
|
||||||
|
@extend %default-font;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
%code-font {
|
||||||
|
font-family: Consolas, Menlo, Monaco, "Lucida Console", "Liberation Mono", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Courier New", monospace, serif;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// OTHER
|
||||||
|
////////////////////
|
||||||
|
$nav-footer-border-color: #666 !default;
|
||||||
|
$search-box-border-color: #666 !default;
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// INTERNAL
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// These settings are probably best left alone.
|
||||||
|
|
||||||
|
%break-words {
|
||||||
|
word-break: break-all;
|
||||||
|
hyphens: auto;
|
||||||
|
}
|
153
docs/api/source/stylesheets/print.css.scss
Normal file
153
docs/api/source/stylesheets/print.css.scss
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
@charset "utf-8";
|
||||||
|
@import 'normalize';
|
||||||
|
@import 'variables';
|
||||||
|
@import 'icon-font';
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2008-2013 Concur Technologies, Inc.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
$print-color: #999;
|
||||||
|
$print-color-light: #ccc;
|
||||||
|
$print-font-size: 12px;
|
||||||
|
|
||||||
|
body {
|
||||||
|
@extend %default-font;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tocify, .toc-footer, .lang-selector, .search, #nav-button {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tocify-wrapper>img {
|
||||||
|
margin: 0 auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
font-size: 12px;
|
||||||
|
|
||||||
|
pre, code {
|
||||||
|
@extend %code-font;
|
||||||
|
@extend %break-words;
|
||||||
|
border: 1px solid $print-color;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
code {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
padding: 1.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
padding: 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border: 1px solid $print-color;
|
||||||
|
tr {
|
||||||
|
border-bottom: 1px solid $print-color;
|
||||||
|
}
|
||||||
|
td,th {
|
||||||
|
padding: 0.7em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
@extend %header-font;
|
||||||
|
font-size: 2.5em;
|
||||||
|
padding-top: 0.5em;
|
||||||
|
padding-bottom: 0.5em;
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-bottom: $h1-margin-bottom;
|
||||||
|
border: 2px solid $print-color-light;
|
||||||
|
border-width: 2px 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
@extend %header-font;
|
||||||
|
font-size: 1.8em;
|
||||||
|
margin-top: 2em;
|
||||||
|
border-top: 2px solid $print-color-light;
|
||||||
|
padding-top: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1+h2, h1+div+h2 {
|
||||||
|
border-top: none;
|
||||||
|
padding-top: 0;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3, h4 {
|
||||||
|
@extend %header-font;
|
||||||
|
font-size: 0.8em;
|
||||||
|
margin-top: 1.5em;
|
||||||
|
margin-bottom: 0.8em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
h5, h6 {
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside {
|
||||||
|
padding: 1em;
|
||||||
|
border: 1px solid $print-color-light;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-top: 1.5em;
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside:before {
|
||||||
|
vertical-align: middle;
|
||||||
|
padding-right: 0.5em;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside.notice:before {
|
||||||
|
@extend %icon-info-sign;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside.warning:before {
|
||||||
|
@extend %icon-exclamation-sign;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside.success:before {
|
||||||
|
@extend %icon-ok-sign;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-clipboard {
|
||||||
|
@media print {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
}
|
634
docs/api/source/stylesheets/screen.css.scss
Normal file
634
docs/api/source/stylesheets/screen.css.scss
Normal file
@ -0,0 +1,634 @@
|
|||||||
|
@charset "utf-8";
|
||||||
|
@import 'normalize';
|
||||||
|
@import 'variables';
|
||||||
|
@import 'icon-font';
|
||||||
|
// @import 'rtl'; // uncomment to switch to RTL format
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2008-2013 Concur Technologies, Inc.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// GENERAL STUFF
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
html, body {
|
||||||
|
color: $main-text;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
@extend %default-font;
|
||||||
|
background-color: $main-bg;
|
||||||
|
height: 100%;
|
||||||
|
-webkit-text-size-adjust: none; /* Never autoresize text */
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// TABLE OF CONTENTS
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#toc > ul > li > a > span {
|
||||||
|
float: right;
|
||||||
|
background-color: #2484FF;
|
||||||
|
border-radius: 40px;
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toc-wrapper {
|
||||||
|
transition: left 0.3s ease-in-out;
|
||||||
|
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
position: fixed;
|
||||||
|
z-index: 30;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: $nav-width;
|
||||||
|
background-color: $nav-bg;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
// language selector for mobile devices
|
||||||
|
.lang-selector {
|
||||||
|
display: none;
|
||||||
|
a {
|
||||||
|
padding-top: 0.5em;
|
||||||
|
padding-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is the logo at the top of the ToC
|
||||||
|
.logo {
|
||||||
|
display: block;
|
||||||
|
margin: 0px auto $logo-margin auto;
|
||||||
|
max-width: 100%;
|
||||||
|
height: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&>.search {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
input {
|
||||||
|
background: $nav-bg;
|
||||||
|
border-width: 0 0 1px 0;
|
||||||
|
border-color: $search-box-border-color;
|
||||||
|
padding: 6px 0 6px 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: $nav-v-padding $nav-padding;
|
||||||
|
width: $nav-width - ($nav-padding*2);
|
||||||
|
outline: none;
|
||||||
|
color: $nav-text;
|
||||||
|
border-radius: 0; /* ios has a default border radius */
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
position: absolute;
|
||||||
|
top: 17px;
|
||||||
|
left: $nav-padding;
|
||||||
|
color: $nav-text;
|
||||||
|
@extend %icon-search;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-results {
|
||||||
|
margin-top: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 0;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
transition-property: height, margin;
|
||||||
|
transition-duration: 180ms;
|
||||||
|
transition-timing-function: ease-in-out;
|
||||||
|
background: $nav-subitem-bg;
|
||||||
|
&.visible {
|
||||||
|
height: 30%;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin: 1em $nav-padding;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $nav-text;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
ul, li {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
line-height: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
color: $nav-text;
|
||||||
|
transition-property: background;
|
||||||
|
transition-timing-function: linear;
|
||||||
|
transition-duration: 200ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is the currently selected ToC entry
|
||||||
|
.toc-link.active {
|
||||||
|
background-color: $nav-active-bg;
|
||||||
|
color: $nav-active-text;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toc-h2 {
|
||||||
|
padding-left: $nav-padding + $nav-indent;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toc-footer {
|
||||||
|
padding: 1em 0;
|
||||||
|
margin-top: 1em;
|
||||||
|
border-top: 1px dashed $nav-footer-border-color;
|
||||||
|
|
||||||
|
li,a {
|
||||||
|
color: $nav-text;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
font-size: 0.8em;
|
||||||
|
line-height: 1.7;
|
||||||
|
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
|
||||||
|
#nav-button {
|
||||||
|
span {
|
||||||
|
display: block;
|
||||||
|
$side-pad: $main-padding / 2 - 8px;
|
||||||
|
padding: $side-pad $side-pad $side-pad;
|
||||||
|
background-color: rgba($main-bg, 0.7);
|
||||||
|
transform-origin: 0 0;
|
||||||
|
transform: rotate(-90deg) translate(-100%, 0);
|
||||||
|
border-radius: 0 0 0 5px;
|
||||||
|
}
|
||||||
|
padding: 0 1.5em 5em 0; // increase touch size area
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 100;
|
||||||
|
color: #000;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: bold;
|
||||||
|
opacity: 0.7;
|
||||||
|
line-height: 16px;
|
||||||
|
img {
|
||||||
|
height: 16px;
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
transition: left 0.3s ease-in-out;
|
||||||
|
|
||||||
|
&:hover { opacity: 1; }
|
||||||
|
&.open {left: $nav-width}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// PAGE LAYOUT AND CODE SAMPLE BACKGROUND
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
.page-wrapper {
|
||||||
|
margin-left: $nav-width;
|
||||||
|
position: relative;
|
||||||
|
z-index: 10;
|
||||||
|
background-color: $main-bg;
|
||||||
|
min-height: 100%;
|
||||||
|
|
||||||
|
padding-bottom: 1px; // prevent margin overflow
|
||||||
|
|
||||||
|
// The dark box is what gives the code samples their dark background.
|
||||||
|
// It sits essentially under the actual content block, which has a
|
||||||
|
// transparent background.
|
||||||
|
// I know, it's hackish, but it's the simplist way to make the left
|
||||||
|
// half of the content always this background color.
|
||||||
|
.dark-box {
|
||||||
|
width: $examples-width;
|
||||||
|
background-color: $examples-bg;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lang-selector {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 50;
|
||||||
|
border-bottom: 5px solid $lang-select-active-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.lang-selector {
|
||||||
|
display: flex;
|
||||||
|
background-color: $lang-select-bg;
|
||||||
|
width: 100%;
|
||||||
|
font-weight: bold;
|
||||||
|
overflow-x: auto;
|
||||||
|
a {
|
||||||
|
display: inline;
|
||||||
|
color: $lang-select-text;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 0 10px;
|
||||||
|
line-height: 30px;
|
||||||
|
outline: 0;
|
||||||
|
|
||||||
|
&:active, &:focus {
|
||||||
|
background-color: $lang-select-pressed-bg;
|
||||||
|
color: $lang-select-pressed-text;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-color: $lang-select-active-bg;
|
||||||
|
color: $lang-select-active-text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: '';
|
||||||
|
clear: both;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// CONTENT STYLES
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
&>h1, &>h2, &>h3, &>h4, &>h5, &>h6, &>p, &>table, &>ul, &>ol, &>aside, &>dl {
|
||||||
|
margin-right: $examples-width;
|
||||||
|
padding: 0 $main-padding;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
@extend %left-col;
|
||||||
|
}
|
||||||
|
|
||||||
|
&>ul, &>ol {
|
||||||
|
padding-left: $main-padding + 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the div is the tocify hidden div for placeholding stuff
|
||||||
|
&>h1, &>h2, &>div {
|
||||||
|
clear:both;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
@extend %header-font;
|
||||||
|
font-size: 25px;
|
||||||
|
padding-top: 0.5em;
|
||||||
|
padding-bottom: 0.5em;
|
||||||
|
margin-bottom: $h1-margin-bottom;
|
||||||
|
margin-top: 2em;
|
||||||
|
border-top: 1px solid #ccc;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
background-color: #fdfdfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1:first-child, div:first-child + h1 {
|
||||||
|
border-top-width: 0;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
@extend %header-font;
|
||||||
|
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.2), rgba(#fff, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// h2s right after h1s should bump right up
|
||||||
|
// against the h1s.
|
||||||
|
h1 + h2, h1 + div + h2 {
|
||||||
|
margin-top: $h1-margin-bottom * -1;
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3, h4, h5, h6 {
|
||||||
|
@extend %header-font;
|
||||||
|
font-size: 15px;
|
||||||
|
margin-top: 2.5em;
|
||||||
|
margin-bottom: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4, h5, h6 {
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
margin: 2em 0;
|
||||||
|
border-top: 2px solid $examples-bg;
|
||||||
|
border-bottom: 2px solid $main-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
overflow: auto;
|
||||||
|
th,td {
|
||||||
|
text-align: left;
|
||||||
|
vertical-align: top;
|
||||||
|
line-height: 1.6;
|
||||||
|
code {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:last-child {
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:nth-child(odd)>td {
|
||||||
|
background-color: lighten($main-bg,4.2%);
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:nth-child(even)>td {
|
||||||
|
background-color: lighten($main-bg,2.4%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dt {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
dd {
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p, li, dt, dd {
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
background-color: rgba(0,0,0,0.05);
|
||||||
|
padding: 3px;
|
||||||
|
border-radius: 3px;
|
||||||
|
@extend %break-words;
|
||||||
|
@extend %code-font;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre>code {
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside {
|
||||||
|
padding-top: 1em;
|
||||||
|
padding-bottom: 1em;
|
||||||
|
margin-top: 1.5em;
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
background: $aside-notice-bg;
|
||||||
|
line-height: 1.6;
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
background-color: $aside-warning-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.success {
|
||||||
|
background-color: $aside-success-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aside:before {
|
||||||
|
vertical-align: middle;
|
||||||
|
padding-right: 0.5em;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside.notice:before {
|
||||||
|
@extend %icon-info-sign;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside.warning:before {
|
||||||
|
@extend %icon-exclamation-sign;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside.success:before {
|
||||||
|
@extend %icon-ok-sign;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-highlight {
|
||||||
|
padding: 2px;
|
||||||
|
margin: -3px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #F7E633;
|
||||||
|
background: linear-gradient(to top left, #F7E633 0%, #F1D32F 100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// CODE SAMPLE STYLES
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
margin: 0;
|
||||||
|
width: $examples-width;
|
||||||
|
|
||||||
|
float:right;
|
||||||
|
clear:right;
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
@extend %right-col;
|
||||||
|
|
||||||
|
&>p { margin: 0; }
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #fff;
|
||||||
|
text-decoration: none;
|
||||||
|
border-bottom: dashed 1px #ccc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
@extend %code-font;
|
||||||
|
padding-top: 2em;
|
||||||
|
padding-bottom: 2em;
|
||||||
|
padding: 2em $main-padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
&>p {
|
||||||
|
background-color: $code-annotation-bg;
|
||||||
|
padding: $code-annotation-padding 2em;
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// RESPONSIVE DESIGN
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// These are the styles for phones and tablets
|
||||||
|
// There are also a couple styles disperesed
|
||||||
|
|
||||||
|
@media (max-width: $tablet-width) {
|
||||||
|
.toc-wrapper {
|
||||||
|
left: -$nav-width;
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-wrapper {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav-button {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toc-link {
|
||||||
|
padding-top: 0.3em;
|
||||||
|
padding-bottom: 0.3em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: $phone-width) {
|
||||||
|
.dark-box {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
%left-col {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toc-wrapper .lang-selector {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-wrapper .lang-selector {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
%right-col {
|
||||||
|
width: auto;
|
||||||
|
float: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
%right-col + %left-col {
|
||||||
|
margin-top: $main-padding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight .c, .highlight .cm, .highlight .c1, .highlight .cs {
|
||||||
|
color: #909090;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
}
|
@ -1,3 +1,8 @@
|
|||||||
|
# 0.1.0
|
||||||
|
- Split frontend/backend code into separate repos (https://gitlab.com/goscrobble/goscrobble-web)
|
||||||
|
- Added new ENV VARS to support unique configurations: DATA_DIRECTORY, FRONTEND_DIRECTORY, API_DOCS_DIRECTORY
|
||||||
|
- Started API documentation @ /docs (https://goscrobble.com/docs/)
|
||||||
|
|
||||||
# 0.0.33
|
# 0.0.33
|
||||||
- Add mod permission
|
- Add mod permission
|
||||||
- Add track/edit page
|
- Add track/edit page
|
||||||
|
@ -35,4 +35,4 @@ These are stored in `web/.env.production` and `web/.env.development`
|
|||||||
|
|
||||||
DATA_DIRECTORY="/var/www/goscrobble-data"
|
DATA_DIRECTORY="/var/www/goscrobble-data"
|
||||||
FRONTEND_DIRECTORY="/var/www/goscrobble-web"
|
FRONTEND_DIRECTORY="/var/www/goscrobble-web"
|
||||||
|
API_DOCS_DIRECTORY="/var/www/goscrobble-api/docs/api/build"
|
||||||
|
@ -25,6 +25,7 @@ var ReverseProxies []string
|
|||||||
// Directories
|
// Directories
|
||||||
var FrontendDirectory string
|
var FrontendDirectory string
|
||||||
var DataDirectory string
|
var DataDirectory string
|
||||||
|
var ApiDocsDirectory string
|
||||||
|
|
||||||
// RequestRequest - Incoming JSON!
|
// RequestRequest - Incoming JSON!
|
||||||
type RequestRequest struct {
|
type RequestRequest struct {
|
||||||
@ -96,27 +97,33 @@ func HandleRequests(port string) {
|
|||||||
// This just prevents it serving frontend stuff over /api
|
// This just prevents it serving frontend stuff over /api
|
||||||
r.PathPrefix("/api")
|
r.PathPrefix("/api")
|
||||||
|
|
||||||
// SERVE STATIC FILES - NO AUTH
|
// Serve Images
|
||||||
spaStatic := spaStaticHandler{staticPath: DataDirectory}
|
spaStatic := spaStaticHandler{staticPath: DataDirectory}
|
||||||
r.PathPrefix("/img").Handler(spaStatic)
|
r.PathPrefix("/img").Handler(spaStatic)
|
||||||
|
|
||||||
apiDocs := spaStaticHandler{staticPath: "docs/api/build"}
|
// Serve API Docs
|
||||||
r.PathPrefix("/docs").Handler(apiDocs)
|
apiDocs := apiDocHandler{staticPath: ApiDocsDirectory, indexPath: "index.html"}
|
||||||
|
r.PathPrefix("/docs/").Handler(apiDocs)
|
||||||
|
|
||||||
// SERVE FRONTEND - NO AUTH
|
// This is a really terrible work around to Slate using relative paths and not
|
||||||
|
// picking up the css/img files when you don't have a trailing slash\
|
||||||
|
apiDocRedirect := apiDocRedirectHandler{}
|
||||||
|
r.PathPrefix("/docs").Handler(apiDocRedirect)
|
||||||
|
|
||||||
|
// Serve Frontend
|
||||||
spa := spaHandler{staticPath: FrontendDirectory + string(os.PathSeparator) + "build", indexPath: "index.html"}
|
spa := spaHandler{staticPath: FrontendDirectory + string(os.PathSeparator) + "build", indexPath: "index.html"}
|
||||||
r.PathPrefix("/").Handler(spa)
|
r.PathPrefix("/").Handler(spa)
|
||||||
|
|
||||||
|
// Setup CORS rules
|
||||||
c := cors.New(cors.Options{
|
c := cors.New(cors.Options{
|
||||||
AllowedOrigins: []string{"*"},
|
AllowedOrigins: []string{"*"},
|
||||||
AllowCredentials: true,
|
AllowCredentials: true,
|
||||||
AllowedMethods: []string{"GET", "POST", "PATCH", "DELETE"},
|
AllowedMethods: []string{"GET", "POST", "PATCH", "DELETE"},
|
||||||
AllowedHeaders: []string{"*"},
|
AllowedHeaders: []string{"*"},
|
||||||
})
|
})
|
||||||
|
|
||||||
handler := c.Handler(r)
|
handler := c.Handler(r)
|
||||||
|
|
||||||
// Serve it up!
|
// Serve it!
|
||||||
fmt.Printf("Goscrobble listening on port %s", port)
|
fmt.Printf("Goscrobble listening on port %s", port)
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
|
|
||||||
@ -781,7 +788,7 @@ func getServerInfo(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
info := ServerInfo{
|
info := ServerInfo{
|
||||||
Version: "0.0.33",
|
Version: "0.1.0",
|
||||||
RegistrationEnabled: cachedRegistrationEnabled,
|
RegistrationEnabled: cachedRegistrationEnabled,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// spaStaticHandler - Handles static imges
|
// spaStaticHandler - Handles static imges
|
||||||
@ -18,7 +19,17 @@ type spaHandler struct {
|
|||||||
indexPath string
|
indexPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerHTTP - Frontend React server
|
// apiDocHandler - Handles API Docs
|
||||||
|
type apiDocHandler struct {
|
||||||
|
staticPath string
|
||||||
|
indexPath string
|
||||||
|
}
|
||||||
|
|
||||||
|
// apiDocRedirectHandler - Handles redirect to add trailing slash (Fixes relative URLs...)
|
||||||
|
type apiDocRedirectHandler struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServeHTTP - Frontend React server
|
||||||
func (h spaStaticHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (h spaStaticHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
// Get the absolute path to prevent directory traversal
|
// Get the absolute path to prevent directory traversal
|
||||||
path, err := filepath.Abs(r.URL.Path)
|
path, err := filepath.Abs(r.URL.Path)
|
||||||
@ -43,7 +54,7 @@ func (h spaStaticHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
http.FileServer(http.Dir(h.staticPath)).ServeHTTP(w, r)
|
http.FileServer(http.Dir(h.staticPath)).ServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerHTTP - Frontend React server
|
// ServeHTTP - Frontend React server
|
||||||
func (h spaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (h spaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
// Get the absolute path to prevent directory traversal
|
// Get the absolute path to prevent directory traversal
|
||||||
path, err := filepath.Abs(r.URL.Path)
|
path, err := filepath.Abs(r.URL.Path)
|
||||||
@ -72,3 +83,42 @@ func (h spaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
// otherwise, use http.FileServer to serve the static dir
|
// otherwise, use http.FileServer to serve the static dir
|
||||||
http.FileServer(http.Dir(h.staticPath)).ServeHTTP(w, r)
|
http.FileServer(http.Dir(h.staticPath)).ServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ServeHTTP - API Redirect to add trailing slash
|
||||||
|
func (h apiDocRedirectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
http.Redirect(w, r, "/docs/", 301)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServeHTTP - API Docs
|
||||||
|
func (h apiDocHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Get the absolute path to prevent directory traversal
|
||||||
|
path, err := filepath.Abs(r.URL.Path)
|
||||||
|
if err != nil {
|
||||||
|
// If we failed to get the absolute path respond with a 400 bad request and return
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
path = filepath.Join(h.staticPath, strings.Replace(path, "/docs", "", 1))
|
||||||
|
|
||||||
|
info, err := os.Stat(path)
|
||||||
|
if info.IsDir() {
|
||||||
|
// Root directory, server index.html
|
||||||
|
http.ServeFile(w, r, filepath.Join(h.staticPath, h.indexPath))
|
||||||
|
return
|
||||||
|
} else if os.IsNotExist(err) {
|
||||||
|
// file does not exist, serve index.html
|
||||||
|
http.ServeFile(w, r, filepath.Join(h.staticPath, h.indexPath))
|
||||||
|
return
|
||||||
|
} else if err != nil {
|
||||||
|
// if we got an error (that wasn't that the file doesn't exist) stating the
|
||||||
|
// file, return a 500 internal server error and stop
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strip /docs from request and serve folder
|
||||||
|
handler := http.FileServer(http.Dir(h.staticPath))
|
||||||
|
http.StripPrefix("/docs", handler).ServeHTTP(w, r)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user