├── .travis.yml ├── Rakefile ├── source ├── javascripts │ ├── all.js │ ├── all_nosearch.js │ ├── app │ │ ├── toc.js │ │ ├── search.js │ │ └── lang.js │ └── lib │ │ ├── jquery.highlight.js │ │ ├── energize.js │ │ ├── jquery_ui.js │ │ ├── jquery.tocify.js │ │ └── lunr.js ├── images │ ├── logo.png │ └── navbar.png ├── fonts │ ├── icomoon.eot │ ├── icomoon.ttf │ ├── icomoon.woff │ └── icomoon.svg ├── oauth.md ├── stylesheets │ ├── _syntax.scss.erb │ ├── _icon-font.scss │ ├── print.css.scss │ ├── _variables.scss │ ├── _normalize.css │ └── screen.css.scss ├── includes │ └── _errors.md └── layouts │ └── layout.erb ├── Gemfile ├── .gitignore ├── Dockerfile ├── CONTRIBUTING.md ├── LICENSE ├── config.rb ├── CHANGELOG.md ├── README.md └── Gemfile.lock /.travis.yml: -------------------------------------------------------------------------------- 1 | rvm: 2 | - 1.9.3 3 | - 2.0.0 4 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'middleman-gh-pages' 2 | 3 | task :default => [:build] 4 | -------------------------------------------------------------------------------- /source/javascripts/all.js: -------------------------------------------------------------------------------- 1 | //= require_tree ./lib 2 | //= require_tree ./app 3 | -------------------------------------------------------------------------------- /source/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hellocodeco/old-exist-api-docs/HEAD/source/images/logo.png -------------------------------------------------------------------------------- /source/fonts/icomoon.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hellocodeco/old-exist-api-docs/HEAD/source/fonts/icomoon.eot -------------------------------------------------------------------------------- /source/fonts/icomoon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hellocodeco/old-exist-api-docs/HEAD/source/fonts/icomoon.ttf -------------------------------------------------------------------------------- /source/fonts/icomoon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hellocodeco/old-exist-api-docs/HEAD/source/fonts/icomoon.woff -------------------------------------------------------------------------------- /source/images/navbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hellocodeco/old-exist-api-docs/HEAD/source/images/navbar.png -------------------------------------------------------------------------------- /source/javascripts/all_nosearch.js: -------------------------------------------------------------------------------- 1 | //= require_tree ./lib 2 | //= require_tree ./app 3 | //= stub ./app/search.js 4 | //= stub ./lib/lunr.js 5 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'http://rubygems.org' 2 | 3 | # Middleman 4 | gem 'middleman', '~>3.3.10' 5 | gem 'middleman-gh-pages', '~> 0.0.3' 6 | gem 'middleman-syntax', '~> 2.0.0' 7 | gem 'rouge', '~> 1.8.0' 8 | gem 'redcarpet', '~> 3.2.2' 9 | 10 | gem 'rake', '~> 10.4.2' 11 | gem 'therubyracer', '~> 0.12.1', platforms: :ruby 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | coverage 6 | InstalledFiles 7 | lib/bundler/man 8 | pkg 9 | rdoc 10 | spec/reports 11 | test/tmp 12 | test/version_tmp 13 | tmp 14 | *.DS_STORE 15 | build/ 16 | .cache 17 | 18 | # YARD artifacts 19 | .yardoc 20 | _yardoc 21 | doc/ 22 | .idea/ 23 | fabfile.py 24 | 25 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:trusty 2 | 3 | RUN apt-get update 4 | RUN apt-get install -yq ruby ruby-dev build-essential git 5 | RUN gem install --no-ri --no-rdoc bundler 6 | ADD Gemfile /app/Gemfile 7 | ADD Gemfile.lock /app/Gemfile.lock 8 | RUN cd /app; bundle install 9 | ADD . /app 10 | EXPOSE 4567 11 | WORKDIR /app 12 | CMD ["bundle", "exec", "middleman", "server"] 13 | -------------------------------------------------------------------------------- /source/oauth.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Exist OAuth2 reference (deprecated) 3 | 4 | language_tabs: 5 | - shell 6 | - python 7 | 8 | toc_footers: 9 | - Sign up for an account 10 | - Developer mailing list 11 | - Docs powered by Slate 12 | 13 | includes: 14 | 15 | 16 | search: true 17 | --- 18 | 19 | # Introduction 20 | 21 | These docs have graduated to the main [developer documentation page](/). -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Slate 2 | 3 | Thanks for contributing to Slate! A couple of quick guidelines for submitting PRs: 4 | 5 | - Please point your pull requests at the `dev` branch, and keep your commit messages clear and informative. 6 | - Please make sure your contributions work in the most recent version of Chrome, Firefox, and IE. 7 | - If you're implementing a new feature, even if it's relatively small, it's nice to open an issue before you start so that others know what you're working on and can help make sure you're on the right track. 8 | 9 | Thanks again! Happy coding. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2008-2013 Concur Technologies, Inc. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | not use this file except in compliance with the License. You may obtain 5 | a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | License for the specific language governing permissions and limitations 13 | under the License. -------------------------------------------------------------------------------- /config.rb: -------------------------------------------------------------------------------- 1 | # Markdown 2 | set :markdown_engine, :redcarpet 3 | set :markdown, 4 | fenced_code_blocks: true, 5 | smartypants: true, 6 | disable_indented_code_blocks: true, 7 | prettify: true, 8 | tables: true, 9 | with_toc_data: true, 10 | no_intra_emphasis: true 11 | 12 | # Assets 13 | set :css_dir, 'stylesheets' 14 | set :js_dir, 'javascripts' 15 | set :images_dir, 'images' 16 | set :fonts_dir, 'fonts' 17 | 18 | # Activate the syntax highlighter 19 | activate :syntax 20 | 21 | # Github pages require relative links 22 | activate :relative_assets 23 | set :relative_links, true 24 | 25 | # Build Configuration 26 | configure :build do 27 | activate :minify_css 28 | activate :minify_javascript 29 | # activate :relative_assets 30 | # activate :asset_hash 31 | # activate :gzip 32 | end 33 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## Version 1.1 4 | 5 | *July 27th, 2014* 6 | 7 | **Fixes:** 8 | 9 | - Finally, a fix for the redcarpet upgrade bug 10 | 11 | ## Version 1.0 12 | 13 | *July 2, 2014* 14 | 15 | [View Issues](https://github.com/tripit/slate/issues?milestone=1&state=closed) 16 | 17 | **Features:** 18 | 19 | - Responsive designs for phones and tablets 20 | - Started tagging versions 21 | 22 | **Fixes:** 23 | 24 | - Fixed 'unrecognized expression' error 25 | - Fixed #undefined hash bug 26 | - Fixed bug where the current language tab would be unselected 27 | - Fixed bug where tocify wouldn't highlight the current section while searching 28 | - Fixed bug where ids of header tags would have special characters that caused problems 29 | - Updated layout so that pages with disabled search wouldn't load search.js 30 | - Cleaned up Javascript 31 | -------------------------------------------------------------------------------- /source/stylesheets/_syntax.scss.erb: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2008-2013 Concur Technologies, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | */ 16 | 17 | @import 'variables'; 18 | 19 | <%= Rouge::Themes::Base16::Monokai.render(:scope => '.highlight') %> 20 | 21 | .highlight .c, .highlight .cm, .highlight .c1, .highlight .cs { 22 | color: #909090; 23 | } 24 | 25 | .highlight, .highlight .w { 26 | background-color: $code-bg; 27 | } -------------------------------------------------------------------------------- /source/includes/_errors.md: -------------------------------------------------------------------------------- 1 | # Errors 2 | 3 | 4 | 5 | The Kittn API uses the following error codes: 6 | 7 | 8 | Error Code | Meaning 9 | ---------- | ------- 10 | 400 | Bad Request -- Your request sucks 11 | 401 | Unauthorized -- Your API key is wrong 12 | 403 | Forbidden -- The kitten requested is hidden for administrators only 13 | 404 | Not Found -- The specified kitten could not be found 14 | 405 | Method Not Allowed -- You tried to access a kitten with an invalid method 15 | 406 | Not Acceptable -- You requested a format that isn't json 16 | 410 | Gone -- The kitten requested has been removed from our servers 17 | 418 | I'm a teapot 18 | 429 | Too Many Requests -- You're requesting too many kittens! Slow down! 19 | 500 | Internal Server Error -- We had a problem with our server. Try again later. 20 | 503 | Service Unavailable -- We're temporarially offline for maintanance. Please try again later. 21 | -------------------------------------------------------------------------------- /source/stylesheets/_icon-font.scss: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'icomoon'; 3 | src:font-url('icomoon.eot'); 4 | src:font-url('icomoon.eot?#iefix') format('embedded-opentype'), 5 | font-url('icomoon.ttf') format('truetype'), 6 | font-url('icomoon.woff') format('woff'), 7 | font-url('icomoon.svg#icomoon') format('svg'); 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | 12 | %icon { 13 | font-family: 'icomoon'; 14 | speak: none; 15 | font-style: normal; 16 | font-weight: normal; 17 | font-variant: normal; 18 | text-transform: none; 19 | line-height: 1; 20 | } 21 | 22 | %icon-exclamation-sign { 23 | @extend %icon; 24 | content: "\e600"; 25 | } 26 | %icon-question-sign { 27 | @extend %icon; 28 | content: "\e601"; 29 | } 30 | %icon-info-sign { 31 | @extend %icon; 32 | content: "\e602"; 33 | } 34 | %icon-remove-sign { 35 | @extend %icon; 36 | content: "\e603"; 37 | } 38 | %icon-plus-sign { 39 | @extend %icon; 40 | content: "\e604"; 41 | } 42 | %icon-minus-sign { 43 | @extend %icon; 44 | content: "\e605"; 45 | } 46 | %icon-ok-sign { 47 | @extend %icon; 48 | content: "\e606"; 49 | } 50 | %icon-search { 51 | @extend %icon; 52 | content: "\e607"; 53 | } 54 | -------------------------------------------------------------------------------- /source/javascripts/app/toc.js: -------------------------------------------------------------------------------- 1 | (function (global) { 2 | 'use strict'; 3 | 4 | var closeToc = function() { 5 | $(".tocify-wrapper").removeClass('open'); 6 | $("#nav-button").removeClass('open'); 7 | }; 8 | 9 | var makeToc = function() { 10 | global.toc = $("#toc").tocify({ 11 | selectors: 'h1, h2', 12 | extendPage: false, 13 | theme: 'none', 14 | smoothScroll: false, 15 | showEffectSpeed: 0, 16 | hideEffectSpeed: 180, 17 | ignoreSelector: '.toc-ignore', 18 | highlightOffset: 60, 19 | scrollTo: -1, 20 | scrollHistory: true, 21 | hashGenerator: function (text, element) { 22 | return element.prop('id'); 23 | } 24 | }).data('toc-tocify'); 25 | 26 | $("#nav-button").click(function() { 27 | $(".tocify-wrapper").toggleClass('open'); 28 | $("#nav-button").toggleClass('open'); 29 | return false; 30 | }); 31 | 32 | $(".page-wrapper").click(closeToc); 33 | $(".tocify-item").click(closeToc); 34 | }; 35 | 36 | // Hack to make already open sections to start opened, 37 | // instead of displaying an ugly animation 38 | function animate () { 39 | setTimeout(function() { 40 | toc.setOption('showEffectSpeed', 180); 41 | }, 50); 42 | } 43 | 44 | $(makeToc); 45 | $(animate); 46 | 47 | })(window); 48 | 49 | -------------------------------------------------------------------------------- /source/javascripts/app/search.js: -------------------------------------------------------------------------------- 1 | (function (global) { 2 | 'use strict'; 3 | 4 | var $global = $(global); 5 | var content, darkBox, searchResults; 6 | var highlightOpts = { element: 'span', className: 'search-highlight' }; 7 | 8 | var index = new lunr.Index(); 9 | 10 | index.ref('id'); 11 | index.field('title', { boost: 10 }); 12 | index.field('body'); 13 | index.pipeline.add(lunr.trimmer, lunr.stopWordFilter); 14 | 15 | $(populate); 16 | $(bind); 17 | 18 | function populate() { 19 | $('h1, h2').each(function() { 20 | var title = $(this); 21 | var body = title.nextUntil('h1, h2'); 22 | index.add({ 23 | id: title.prop('id'), 24 | title: title.text(), 25 | body: body.text() 26 | }); 27 | }); 28 | } 29 | 30 | function bind() { 31 | content = $('.content'); 32 | darkBox = $('.dark-box'); 33 | searchResults = $('.search-results'); 34 | 35 | $('#input-search').on('keyup', search); 36 | } 37 | 38 | function search(event) { 39 | unhighlight(); 40 | searchResults.addClass('visible'); 41 | 42 | // ESC clears the field 43 | if (event.keyCode === 27) this.value = ''; 44 | 45 | if (this.value) { 46 | var results = index.search(this.value).filter(function(r) { 47 | return r.score > 0.0001; 48 | }); 49 | 50 | if (results.length) { 51 | searchResults.empty(); 52 | $.each(results, function (index, result) { 53 | var elem = document.getElementById(result.ref); 54 | searchResults.append("
  • " + $(elem).text() + "
  • "); 55 | }); 56 | highlight.call(this); 57 | } else { 58 | searchResults.html('
  • '); 59 | $('.search-results li').text('No Results Found for "' + this.value + '"'); 60 | } 61 | } else { 62 | unhighlight(); 63 | searchResults.removeClass('visible'); 64 | } 65 | } 66 | 67 | function highlight() { 68 | if (this.value) content.highlight(this.value, highlightOpts); 69 | } 70 | 71 | function unhighlight() { 72 | content.unhighlight(highlightOpts); 73 | } 74 | 75 | })(window); 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repository contains the docs for Exist's API, which live at [developer.exist.io](http://developer.exist.io). 2 | They're built on Slate, so I've left the Slate readme contents here so you have instructions for building your own copy. 3 | 4 | 5 | Slate 6 | ======== 7 | 8 | [![Build Status](https://travis-ci.org/tripit/slate.svg?branch=master)](https://travis-ci.org/tripit/slate) [![Dependency Status](https://gemnasium.com/tripit/slate.png)](https://gemnasium.com/tripit/slate) 9 | 10 | Slate helps you create beautiful API documentation. Think of it as an intelligent, responsive documentation template for your API. 11 | 12 | Getting Started with Slate 13 | ------------------------------ 14 | 15 | ### Prerequisites 16 | 17 | You're going to need: 18 | 19 | - **Linux or OS X** — Windows may work, but is unsupported. 20 | - **Ruby, version 1.9.3 or newer** 21 | - **Bundler** — If Ruby is already installed, but the `bundle` command doesn't work, just run `gem install bundler` in a terminal. 22 | 23 | ### Getting Set Up 24 | 25 | 1. Fork this repository on Github. 26 | 2. Clone *your forked repository* (not our original one) to your hard drive with `git clone https://github.com/YOURUSERNAME/slate.git` 27 | 3. `cd slate` 28 | 4. Install all dependencies: `bundle install` 29 | 5. Start the test server: `bundle exec middleman server` 30 | 31 | Or use the included Dockerfile! (must install Docker first) 32 | 33 | ```shell 34 | docker build -t slate . 35 | docker run -d -p 4567:4567 slate 36 | ``` 37 | 38 | You can now see the docs at . Whoa! That was fast! 39 | 40 | *Note: if you're using the Docker setup on OSX, the docs will be 41 | availalable at the output of `boot2docker ip` instead of `localhost:4567`.* 42 | 43 | Now that Slate is all set up your machine, you'll probably want to learn more about [editing Slate markdown](https://github.com/tripit/slate/wiki/Markdown-Syntax), or [how to publish your docs](https://github.com/tripit/slate/wiki/Deploying-Slate). 44 | 45 | 46 | Need Help? Found a bug? 47 | -------------------- 48 | 49 | Just [submit a issue](https://github.com/tripit/slate/issues) to the Slate Github if you need any help. And, of course, feel free to submit pull requests with bug fixes or changes. 50 | 51 | 52 | Contributors 53 | -------------------- 54 | 55 | Slate was built by [Robert Lord](http://lord.io) while at [TripIt](http://tripit.com). 56 | 57 | Thanks to the following people who have submitted major pull requests: 58 | 59 | - [@chrissrogers](https://github.com/chrissrogers) 60 | - [@bootstraponline](https://github.com/bootstraponline) 61 | - [@realityking](https://github.com/realityking) 62 | 63 | Also, thanks to [Sauce Labs](http://saucelabs.com) for helping sponsor the project. 64 | 65 | Special Thanks 66 | -------------------- 67 | - [Middleman](https://github.com/middleman/middleman) 68 | - [jquery.tocify.js](https://github.com/gfranko/jquery.tocify.js) 69 | - [middleman-syntax](https://github.com/middleman/middleman-syntax) 70 | - [middleman-gh-pages](https://github.com/neo/middleman-gh-pages) 71 | - [Font Awesome](http://fortawesome.github.io/Font-Awesome/) 72 | -------------------------------------------------------------------------------- /source/javascripts/app/lang.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2008-2013 Concur Technologies, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | */ 16 | (function (global) { 17 | 'use strict'; 18 | 19 | var languages = []; 20 | 21 | global.setupLanguages = setupLanguages; 22 | global.activateLanguage = activateLanguage; 23 | 24 | function activateLanguage(language) { 25 | if (!language) return; 26 | if (language === "") return; 27 | 28 | $(".lang-selector a").removeClass('active'); 29 | $(".lang-selector a[data-language-name='" + language + "']").addClass('active'); 30 | for (var i=0; i < languages.length; i++) { 31 | $(".highlight." + languages[i]).hide(); 32 | } 33 | $(".highlight." + language).show(); 34 | 35 | global.toc.calculateHeights(); 36 | 37 | // scroll to the new location of the position 38 | if ($(window.location.hash).get(0)) { 39 | $(window.location.hash).get(0).scrollIntoView(true); 40 | } 41 | } 42 | 43 | // if a button is clicked, add the state to the history 44 | function pushURL(language) { 45 | if (!history) { return; } 46 | var hash = window.location.hash; 47 | if (hash) { 48 | hash = hash.replace(/^#+/, ''); 49 | } 50 | history.pushState({}, '', '?' + language + '#' + hash); 51 | 52 | // save language as next default 53 | localStorage.setItem("language", language); 54 | } 55 | 56 | function setupLanguages(l) { 57 | var currentLanguage = l[0]; 58 | var defaultLanguage = localStorage.getItem("language"); 59 | 60 | languages = l; 61 | 62 | if ((location.search.substr(1) !== "") && (jQuery.inArray(location.search.substr(1), languages)) != -1) { 63 | // the language is in the URL, so use that language! 64 | activateLanguage(location.search.substr(1)); 65 | 66 | localStorage.setItem("language", location.search.substr(1)); 67 | } else if ((defaultLanguage !== null) && (jQuery.inArray(defaultLanguage, languages) != -1)) { 68 | // the language was the last selected one saved in localstorage, so use that language! 69 | activateLanguage(defaultLanguage); 70 | } else { 71 | // no language selected, so use the default 72 | activateLanguage(languages[0]); 73 | } 74 | } 75 | 76 | // if we click on a language tab, activate that language 77 | $(function() { 78 | $(".lang-selector a").on("click", function() { 79 | var language = $(this).data("language-name"); 80 | pushURL(language); 81 | activateLanguage(language); 82 | return false; 83 | }); 84 | window.onpopstate = function(event) { 85 | activateLanguage(window.location.search.substr(1)); 86 | }; 87 | }); 88 | })(window); 89 | -------------------------------------------------------------------------------- /source/stylesheets/print.css.scss: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | @import 'normalize'; 3 | @import 'compass'; 4 | @import 'variables'; 5 | @import 'icon-font'; 6 | 7 | /* 8 | Copyright 2008-2013 Concur Technologies, Inc. 9 | 10 | Licensed under the Apache License, Version 2.0 (the "License"); you may 11 | not use this file except in compliance with the License. You may obtain 12 | a copy of the License at 13 | 14 | http://www.apache.org/licenses/LICENSE-2.0 15 | 16 | Unless required by applicable law or agreed to in writing, software 17 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 18 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 19 | License for the specific language governing permissions and limitations 20 | under the License. 21 | */ 22 | 23 | $print-color: #999; 24 | $print-color-light: #ccc; 25 | $print-font-size: 12px; 26 | 27 | body { 28 | @extend %default-font; 29 | } 30 | 31 | .tocify, .toc-footer, .lang-selector, .search, #nav-button { 32 | display: none; 33 | } 34 | 35 | .tocify-wrapper>img { 36 | margin: 0 auto; 37 | display: block; 38 | } 39 | 40 | .content { 41 | font-size: 12px; 42 | 43 | pre, code { 44 | @extend %code-font; 45 | @extend %break-words; 46 | border: 1px solid $print-color; 47 | border-radius: 5px; 48 | font-size: 0.8em; 49 | } 50 | 51 | pre { 52 | padding: 1.3em; 53 | } 54 | 55 | code { 56 | padding: 0.2em; 57 | } 58 | 59 | table { 60 | border: 1px solid $print-color; 61 | tr { 62 | border-bottom: 1px solid $print-color; 63 | } 64 | td,th { 65 | padding: 0.7em; 66 | } 67 | } 68 | 69 | p { 70 | line-height: 1.5; 71 | } 72 | 73 | a { 74 | text-decoration: none; 75 | color: #000; 76 | } 77 | 78 | h1 { 79 | @extend %header-font; 80 | font-size: 2.5em; 81 | padding-top: 0.5em; 82 | padding-bottom: 0.5em; 83 | margin-top: 1em; 84 | margin-bottom: $h1-margin-bottom; 85 | border: 2px solid $print-color-light; 86 | border-width: 2px 0; 87 | text-align: center; 88 | } 89 | 90 | h2 { 91 | @extend %header-font; 92 | font-size: 1.8em; 93 | margin-top: 2em; 94 | border-top: 2px solid $print-color-light; 95 | padding-top: 0.8em; 96 | } 97 | 98 | h1+h2, h1+div+h2 { 99 | border-top: none; 100 | padding-top: 0; 101 | margin-top: 0; 102 | } 103 | 104 | h3, h4 { 105 | @extend %header-font; 106 | font-size: 0.8em; 107 | margin-top: 1.5em; 108 | margin-bottom: 0.8em; 109 | text-transform: uppercase; 110 | } 111 | 112 | h5, h6 { 113 | text-transform: uppercase; 114 | } 115 | 116 | aside { 117 | padding: 1em; 118 | border: 1px solid $print-color-light; 119 | border-radius: 5px; 120 | margin-top: 1.5em; 121 | margin-bottom: 1.5em; 122 | line-height: 1.6; 123 | } 124 | 125 | aside:before { 126 | vertical-align: middle; 127 | padding-right: 0.5em; 128 | font-size: 14px; 129 | } 130 | 131 | aside.notice:before { 132 | @extend %icon-info-sign; 133 | } 134 | 135 | aside.warning:before { 136 | @extend %icon-exclamation-sign; 137 | } 138 | 139 | aside.success:before { 140 | @extend %icon-ok-sign; 141 | } 142 | } -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | activesupport (4.1.10) 5 | i18n (~> 0.6, >= 0.6.9) 6 | json (~> 1.7, >= 1.7.7) 7 | minitest (~> 5.1) 8 | thread_safe (~> 0.1) 9 | tzinfo (~> 1.1) 10 | celluloid (0.16.0) 11 | timers (~> 4.0.0) 12 | chunky_png (1.3.4) 13 | coffee-script (2.4.1) 14 | coffee-script-source 15 | execjs 16 | coffee-script-source (1.9.1.1) 17 | compass (1.0.3) 18 | chunky_png (~> 1.2) 19 | compass-core (~> 1.0.2) 20 | compass-import-once (~> 1.0.5) 21 | rb-fsevent (>= 0.9.3) 22 | rb-inotify (>= 0.9) 23 | sass (>= 3.3.13, < 3.5) 24 | compass-core (1.0.3) 25 | multi_json (~> 1.0) 26 | sass (>= 3.3.0, < 3.5) 27 | compass-import-once (1.0.5) 28 | sass (>= 3.2, < 3.5) 29 | erubis (2.7.0) 30 | execjs (2.5.2) 31 | ffi (1.9.8) 32 | haml (4.0.6) 33 | tilt 34 | hike (1.2.3) 35 | hitimes (1.2.2) 36 | hooks (0.4.0) 37 | uber (~> 0.0.4) 38 | i18n (0.7.0) 39 | json (1.8.2) 40 | kramdown (1.7.0) 41 | libv8 (3.16.14.7) 42 | listen (2.10.0) 43 | celluloid (~> 0.16.0) 44 | rb-fsevent (>= 0.9.3) 45 | rb-inotify (>= 0.9) 46 | middleman (3.3.11) 47 | coffee-script (~> 2.2) 48 | compass (>= 1.0.0, < 2.0.0) 49 | compass-import-once (= 1.0.5) 50 | execjs (~> 2.0) 51 | haml (>= 4.0.5) 52 | kramdown (~> 1.2) 53 | middleman-core (= 3.3.11) 54 | middleman-sprockets (>= 3.1.2) 55 | sass (>= 3.4.0, < 4.0) 56 | uglifier (~> 2.5) 57 | middleman-core (3.3.11) 58 | activesupport (~> 4.1.0) 59 | bundler (~> 1.1) 60 | erubis 61 | hooks (~> 0.3) 62 | i18n (~> 0.7.0) 63 | listen (>= 2.7.9, < 3.0) 64 | padrino-helpers (~> 0.12.3) 65 | rack (>= 1.4.5, < 2.0) 66 | rack-test (~> 0.6.2) 67 | thor (>= 0.15.2, < 2.0) 68 | tilt (~> 1.4.1, < 2.0) 69 | middleman-gh-pages (0.0.3) 70 | rake (> 0.9.3) 71 | middleman-sprockets (3.4.2) 72 | middleman-core (>= 3.3) 73 | sprockets (~> 2.12.1) 74 | sprockets-helpers (~> 1.1.0) 75 | sprockets-sass (~> 1.3.0) 76 | middleman-syntax (2.0.0) 77 | middleman-core (~> 3.2) 78 | rouge (~> 1.0) 79 | minitest (5.6.1) 80 | multi_json (1.11.0) 81 | padrino-helpers (0.12.5) 82 | i18n (~> 0.6, >= 0.6.7) 83 | padrino-support (= 0.12.5) 84 | tilt (~> 1.4.1) 85 | padrino-support (0.12.5) 86 | activesupport (>= 3.1) 87 | rack (1.6.0) 88 | rack-test (0.6.3) 89 | rack (>= 1.0) 90 | rake (10.4.2) 91 | rb-fsevent (0.9.4) 92 | rb-inotify (0.9.5) 93 | ffi (>= 0.5.0) 94 | redcarpet (3.2.3) 95 | ref (1.0.5) 96 | rouge (1.8.0) 97 | sass (3.4.13) 98 | sprockets (2.12.3) 99 | hike (~> 1.2) 100 | multi_json (~> 1.0) 101 | rack (~> 1.0) 102 | tilt (~> 1.1, != 1.3.0) 103 | sprockets-helpers (1.1.0) 104 | sprockets (~> 2.0) 105 | sprockets-sass (1.3.1) 106 | sprockets (~> 2.0) 107 | tilt (~> 1.1) 108 | therubyracer (0.12.2) 109 | libv8 (~> 3.16.14.0) 110 | ref 111 | thor (0.19.1) 112 | thread_safe (0.3.5) 113 | tilt (1.4.1) 114 | timers (4.0.1) 115 | hitimes 116 | tzinfo (1.2.2) 117 | thread_safe (~> 0.1) 118 | uber (0.0.13) 119 | uglifier (2.7.1) 120 | execjs (>= 0.3.0) 121 | json (>= 1.8.0) 122 | 123 | PLATFORMS 124 | ruby 125 | 126 | DEPENDENCIES 127 | middleman (~> 3.3.10) 128 | middleman-gh-pages (~> 0.0.3) 129 | middleman-syntax (~> 2.0.0) 130 | rake (~> 10.4.2) 131 | redcarpet (~> 3.2.2) 132 | rouge (~> 1.8.0) 133 | therubyracer (~> 0.12.1) 134 | -------------------------------------------------------------------------------- /source/layouts/layout.erb: -------------------------------------------------------------------------------- 1 | <%# 2 | Copyright 2008-2013 Concur Technologies, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | %> 16 | <% language_tabs = current_page.data.language_tabs %> 17 | 18 | 19 | 20 | 21 | 22 | 23 | <%= current_page.data.title || "API Documentation" %> 24 | 25 | <%= stylesheet_link_tag :screen, media: :screen %> 26 | <%= stylesheet_link_tag :print, media: :print %> 27 | 28 | 29 | 30 | <% if current_page.data.search %> 31 | <%= javascript_include_tag "all" %> 32 | <% else %> 33 | <%= javascript_include_tag "all_nosearch" %> 34 | <% end %> 35 | 36 | <% if language_tabs %> 37 | 42 | <% end %> 43 | 44 | 45 | 46 | 47 | 48 | NAV 49 | <%= image_tag('navbar.png') %> 50 | 51 | 52 |
    53 | 54 | <% if language_tabs %> 55 |
    56 | <% language_tabs.each do |lang| %> 57 | <% if lang.is_a? Hash %> 58 | <%= lang.values.first %> 59 | <% else %> 60 | <%= lang %> 61 | <% end %> 62 | <% end %> 63 |
    64 | <% end %> 65 | <% if current_page.data.search %> 66 | 69 | 70 | <% end %> 71 |
    72 |
    73 | <% if current_page.data.toc_footers %> 74 | 79 | <% end %> 80 |
    81 |
    82 |
    83 |
    84 | <%= yield %> 85 | <% current_page.data.includes && current_page.data.includes.each do |include| %> 86 | <%= partial "includes/#{include}" %> 87 | <% end %> 88 |
    89 |
    90 | <% if language_tabs %> 91 |
    92 | <% language_tabs.each do |lang| %> 93 | <% if lang.is_a? Hash %> 94 | <%= lang.values.first %> 95 | <% else %> 96 | <%= lang %> 97 | <% end %> 98 | <% end %> 99 |
    100 | <% end %> 101 |
    102 |
    103 | 104 | 105 | -------------------------------------------------------------------------------- /source/stylesheets/_variables.scss: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2008-2013 Concur Technologies, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | */ 16 | 17 | 18 | //////////////////////////////////////////////////////////////////////////////// 19 | // CUSTOMIZE SLATE 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // Use these settings to help adjust the appearance of Slate 22 | 23 | 24 | // BACKGROUND COLORS 25 | //////////////////// 26 | $nav-bg: #444b57; 27 | $examples-bg: #333a45; 28 | $code-bg: #292f37; 29 | $code-annotation-bg: rgba(0,0,0,0.2); 30 | $nav-subitem-bg: #333a45; 31 | $nav-active-bg: #238bb0; 32 | $lang-select-border: #000; 33 | $lang-select-bg: #222; 34 | $lang-select-active-bg: $examples-bg; // feel free to change this to blue or something 35 | $lang-select-pressed-bg: #111; // color of language tab bg when mouse is pressed 36 | $main-bg: #fff; 37 | $aside-notice-bg: #8fbcd4; 38 | $aside-warning-bg: #c97a7e; 39 | $aside-success-bg: #6ac174; 40 | $search-notice-bg: #c97a7e; 41 | 42 | 43 | // TEXT COLORS 44 | //////////////////// 45 | $main-text: #333; // main content text color 46 | $nav-text: #fff; 47 | $nav-active-text: #fff; 48 | $lang-select-text: #fff; // color of unselected language tab text 49 | $lang-select-active-text: #fff; // color of selected language tab text 50 | $lang-select-pressed-text: #fff; // color of language tab text when mouse is pressed 51 | $link-text: #238bb0; 52 | 53 | // SIZES 54 | //////////////////// 55 | $nav-width: 240px; // width of the navbar 56 | $examples-width: 50%; // portion of the screen taken up by code examples 57 | $logo-margin: 20px; // margin between nav items and logo, ignored if search is active 58 | $main-padding: 28px; // padding to left and right of content & examples 59 | $nav-padding: 15px; // padding to left and right of navbar 60 | $nav-v-padding: 10px; // padding used vertically around search boxes and results 61 | $nav-indent: 10px; // extra padding for ToC subitems 62 | $code-annotation-padding: 10px; // padding inside code annotations 63 | $h1-margin-bottom: 21px; // padding under the largest header tags 64 | $tablet-width: 930px; // min width before reverting to tablet size 65 | $phone-width: $tablet-width - $nav-width; // min width before reverting to mobile size 66 | 67 | 68 | // FONTS 69 | //////////////////// 70 | %default-font { 71 | font-family: "Open Sans","Helvetica Neue", Helvetica, Arial, sans-serif; 72 | font-size: 14px; 73 | line-height: 20px; 74 | } 75 | 76 | %header-font { 77 | @extend %default-font; 78 | font-weight: bold; 79 | } 80 | 81 | %code-font { 82 | font-family: Consolas, Menlo, Monaco, "Lucida Console", "Liberation Mono", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Courier New", monospace, serif; 83 | font-size: 13px; 84 | line-height: 1.5; 85 | } 86 | 87 | 88 | // OTHER 89 | //////////////////// 90 | $nav-active-shadow: #000; 91 | $nav-footer-border-color: #333a45; 92 | $nav-embossed-border-top: #000; 93 | $nav-embossed-border-bottom: #333a45; 94 | $main-embossed-text-shadow: 0px 1px 0px #fff; 95 | $search-box-border-color: #666; 96 | 97 | 98 | //////////////////////////////////////////////////////////////////////////////// 99 | // INTERNAL 100 | //////////////////////////////////////////////////////////////////////////////// 101 | // These settings are probably best left alone. 102 | 103 | %break-words { 104 | -ms-word-break: break-all; 105 | word-break: break-all; 106 | 107 | /* Non standard for webkit */ 108 | word-break: break-word; 109 | 110 | -webkit-hyphens: auto; 111 | -moz-hyphens: auto; 112 | hyphens: auto; 113 | } 114 | -------------------------------------------------------------------------------- /source/javascripts/lib/jquery.highlight.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery Highlight plugin 3 | * 4 | * Based on highlight v3 by Johann Burkard 5 | * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html 6 | * 7 | * Code a little bit refactored and cleaned (in my humble opinion). 8 | * Most important changes: 9 | * - has an option to highlight only entire words (wordsOnly - false by default), 10 | * - has an option to be case sensitive (caseSensitive - false by default) 11 | * - highlight element tag and class names can be specified in options 12 | * 13 | * Usage: 14 | * // wrap every occurrance of text 'lorem' in content 15 | * // with (default options) 16 | * $('#content').highlight('lorem'); 17 | * 18 | * // search for and highlight more terms at once 19 | * // so you can save some time on traversing DOM 20 | * $('#content').highlight(['lorem', 'ipsum']); 21 | * $('#content').highlight('lorem ipsum'); 22 | * 23 | * // search only for entire word 'lorem' 24 | * $('#content').highlight('lorem', { wordsOnly: true }); 25 | * 26 | * // don't ignore case during search of term 'lorem' 27 | * $('#content').highlight('lorem', { caseSensitive: true }); 28 | * 29 | * // wrap every occurrance of term 'ipsum' in content 30 | * // with 31 | * $('#content').highlight('ipsum', { element: 'em', className: 'important' }); 32 | * 33 | * // remove default highlight 34 | * $('#content').unhighlight(); 35 | * 36 | * // remove custom highlight 37 | * $('#content').unhighlight({ element: 'em', className: 'important' }); 38 | * 39 | * 40 | * Copyright (c) 2009 Bartek Szopka 41 | * 42 | * Licensed under MIT license. 43 | * 44 | */ 45 | 46 | jQuery.extend({ 47 | highlight: function (node, re, nodeName, className) { 48 | if (node.nodeType === 3) { 49 | var match = node.data.match(re); 50 | if (match) { 51 | var highlight = document.createElement(nodeName || 'span'); 52 | highlight.className = className || 'highlight'; 53 | var wordNode = node.splitText(match.index); 54 | wordNode.splitText(match[0].length); 55 | var wordClone = wordNode.cloneNode(true); 56 | highlight.appendChild(wordClone); 57 | wordNode.parentNode.replaceChild(highlight, wordNode); 58 | return 1; //skip added node in parent 59 | } 60 | } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children 61 | !/(script|style)/i.test(node.tagName) && // ignore script and style nodes 62 | !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted 63 | for (var i = 0; i < node.childNodes.length; i++) { 64 | i += jQuery.highlight(node.childNodes[i], re, nodeName, className); 65 | } 66 | } 67 | return 0; 68 | } 69 | }); 70 | 71 | jQuery.fn.unhighlight = function (options) { 72 | var settings = { className: 'highlight', element: 'span' }; 73 | jQuery.extend(settings, options); 74 | 75 | return this.find(settings.element + "." + settings.className).each(function () { 76 | var parent = this.parentNode; 77 | parent.replaceChild(this.firstChild, this); 78 | parent.normalize(); 79 | }).end(); 80 | }; 81 | 82 | jQuery.fn.highlight = function (words, options) { 83 | var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false }; 84 | jQuery.extend(settings, options); 85 | 86 | if (words.constructor === String) { 87 | words = [words]; 88 | } 89 | words = jQuery.grep(words, function(word, i){ 90 | return word != ''; 91 | }); 92 | words = jQuery.map(words, function(word, i) { 93 | return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); 94 | }); 95 | if (words.length == 0) { return this; }; 96 | 97 | var flag = settings.caseSensitive ? "" : "i"; 98 | var pattern = "(" + words.join("|") + ")"; 99 | if (settings.wordsOnly) { 100 | pattern = "\\b" + pattern + "\\b"; 101 | } 102 | var re = new RegExp(pattern, flag); 103 | 104 | return this.each(function () { 105 | jQuery.highlight(this, re, settings.element, settings.className); 106 | }); 107 | }; 108 | 109 | -------------------------------------------------------------------------------- /source/fonts/icomoon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /source/javascripts/lib/energize.js: -------------------------------------------------------------------------------- 1 | /** 2 | * energize.js v0.1.0 3 | * 4 | * Speeds up click events on mobile devices. 5 | * https://github.com/davidcalhoun/energize.js 6 | */ 7 | 8 | (function() { // Sandbox 9 | /** 10 | * Don't add to non-touch devices, which don't need to be sped up 11 | */ 12 | if(!('ontouchstart' in window)) return; 13 | 14 | var lastClick = {}, 15 | isThresholdReached, touchstart, touchmove, touchend, 16 | click, closest; 17 | 18 | /** 19 | * isThresholdReached 20 | * 21 | * Compare touchstart with touchend xy coordinates, 22 | * and only fire simulated click event if the coordinates 23 | * are nearby. (don't want clicking to be confused with a swipe) 24 | */ 25 | isThresholdReached = function(startXY, xy) { 26 | return Math.abs(startXY[0] - xy[0]) > 5 || Math.abs(startXY[1] - xy[1]) > 5; 27 | }; 28 | 29 | /** 30 | * touchstart 31 | * 32 | * Save xy coordinates when the user starts touching the screen 33 | */ 34 | touchstart = function(e) { 35 | this.startXY = [e.touches[0].clientX, e.touches[0].clientY]; 36 | this.threshold = false; 37 | }; 38 | 39 | /** 40 | * touchmove 41 | * 42 | * Check if the user is scrolling past the threshold. 43 | * Have to check here because touchend will not always fire 44 | * on some tested devices (Kindle Fire?) 45 | */ 46 | touchmove = function(e) { 47 | // NOOP if the threshold has already been reached 48 | if(this.threshold) return false; 49 | 50 | this.threshold = isThresholdReached(this.startXY, [e.touches[0].clientX, e.touches[0].clientY]); 51 | }; 52 | 53 | /** 54 | * touchend 55 | * 56 | * If the user didn't scroll past the threshold between 57 | * touchstart and touchend, fire a simulated click. 58 | * 59 | * (This will fire before a native click) 60 | */ 61 | touchend = function(e) { 62 | // Don't fire a click if the user scrolled past the threshold 63 | if(this.threshold || isThresholdReached(this.startXY, [e.changedTouches[0].clientX, e.changedTouches[0].clientY])) { 64 | return; 65 | } 66 | 67 | /** 68 | * Create and fire a click event on the target element 69 | * https://developer.mozilla.org/en/DOM/event.initMouseEvent 70 | */ 71 | var touch = e.changedTouches[0], 72 | evt = document.createEvent('MouseEvents'); 73 | evt.initMouseEvent('click', true, true, window, 0, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null); 74 | evt.simulated = true; // distinguish from a normal (nonsimulated) click 75 | e.target.dispatchEvent(evt); 76 | }; 77 | 78 | /** 79 | * click 80 | * 81 | * Because we've already fired a click event in touchend, 82 | * we need to listed for all native click events here 83 | * and suppress them as necessary. 84 | */ 85 | click = function(e) { 86 | /** 87 | * Prevent ghost clicks by only allowing clicks we created 88 | * in the click event we fired (look for e.simulated) 89 | */ 90 | var time = Date.now(), 91 | timeDiff = time - lastClick.time, 92 | x = e.clientX, 93 | y = e.clientY, 94 | xyDiff = [Math.abs(lastClick.x - x), Math.abs(lastClick.y - y)], 95 | target = closest(e.target, 'A') || e.target, // needed for standalone apps 96 | nodeName = target.nodeName, 97 | isLink = nodeName === 'A', 98 | standAlone = window.navigator.standalone && isLink && e.target.getAttribute("href"); 99 | 100 | lastClick.time = time; 101 | lastClick.x = x; 102 | lastClick.y = y; 103 | 104 | /** 105 | * Unfortunately Android sometimes fires click events without touch events (seen on Kindle Fire), 106 | * so we have to add more logic to determine the time of the last click. Not perfect... 107 | * 108 | * Older, simpler check: if((!e.simulated) || standAlone) 109 | */ 110 | if((!e.simulated && (timeDiff < 500 || (timeDiff < 1500 && xyDiff[0] < 50 && xyDiff[1] < 50))) || standAlone) { 111 | e.preventDefault(); 112 | e.stopPropagation(); 113 | if(!standAlone) return false; 114 | } 115 | 116 | /** 117 | * Special logic for standalone web apps 118 | * See http://stackoverflow.com/questions/2898740/iphone-safari-web-app-opens-links-in-new-window 119 | */ 120 | if(standAlone) { 121 | window.location = target.getAttribute("href"); 122 | } 123 | 124 | /** 125 | * Add an energize-focus class to the targeted link (mimics :focus behavior) 126 | * TODO: test and/or remove? Does this work? 127 | */ 128 | if(!target || !target.classList) return; 129 | target.classList.add("energize-focus"); 130 | window.setTimeout(function(){ 131 | target.classList.remove("energize-focus"); 132 | }, 150); 133 | }; 134 | 135 | /** 136 | * closest 137 | * @param {HTMLElement} node current node to start searching from. 138 | * @param {string} tagName the (uppercase) name of the tag you're looking for. 139 | * 140 | * Find the closest ancestor tag of a given node. 141 | * 142 | * Starts at node and goes up the DOM tree looking for a 143 | * matching nodeName, continuing until hitting document.body 144 | */ 145 | closest = function(node, tagName){ 146 | var curNode = node; 147 | 148 | while(curNode !== document.body) { // go up the dom until we find the tag we're after 149 | if(!curNode || curNode.nodeName === tagName) { return curNode; } // found 150 | curNode = curNode.parentNode; // not found, so keep going up 151 | } 152 | 153 | return null; // not found 154 | }; 155 | 156 | /** 157 | * Add all delegated event listeners 158 | * 159 | * All the events we care about bubble up to document, 160 | * so we can take advantage of event delegation. 161 | * 162 | * Note: no need to wait for DOMContentLoaded here 163 | */ 164 | document.addEventListener('touchstart', touchstart, false); 165 | document.addEventListener('touchmove', touchmove, false); 166 | document.addEventListener('touchend', touchend, false); 167 | document.addEventListener('click', click, true); // TODO: why does this use capture? 168 | 169 | })(); -------------------------------------------------------------------------------- /source/stylesheets/_normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.2 | MIT License | git.io/normalize */ 2 | 3 | /** 4 | * 1. Set default font family to sans-serif. 5 | * 2. Prevent iOS text size adjust after orientation change, without disabling 6 | * user zoom. 7 | */ 8 | 9 | html { 10 | font-family: sans-serif; /* 1 */ 11 | -ms-text-size-adjust: 100%; /* 2 */ 12 | -webkit-text-size-adjust: 100%; /* 2 */ 13 | } 14 | 15 | /** 16 | * Remove default margin. 17 | */ 18 | 19 | body { 20 | margin: 0; 21 | } 22 | 23 | /* HTML5 display definitions 24 | ========================================================================== */ 25 | 26 | /** 27 | * Correct `block` display not defined for any HTML5 element in IE 8/9. 28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11 29 | * and Firefox. 30 | * Correct `block` display not defined for `main` in IE 11. 31 | */ 32 | 33 | article, 34 | aside, 35 | details, 36 | figcaption, 37 | figure, 38 | footer, 39 | header, 40 | hgroup, 41 | main, 42 | menu, 43 | nav, 44 | section, 45 | summary { 46 | display: block; 47 | } 48 | 49 | /** 50 | * 1. Correct `inline-block` display not defined in IE 8/9. 51 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. 52 | */ 53 | 54 | audio, 55 | canvas, 56 | progress, 57 | video { 58 | display: inline-block; /* 1 */ 59 | vertical-align: baseline; /* 2 */ 60 | } 61 | 62 | /** 63 | * Prevent modern browsers from displaying `audio` without controls. 64 | * Remove excess height in iOS 5 devices. 65 | */ 66 | 67 | audio:not([controls]) { 68 | display: none; 69 | height: 0; 70 | } 71 | 72 | /** 73 | * Address `[hidden]` styling not present in IE 8/9/10. 74 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. 75 | */ 76 | 77 | [hidden], 78 | template { 79 | display: none; 80 | } 81 | 82 | /* Links 83 | ========================================================================== */ 84 | 85 | /** 86 | * Remove the gray background color from active links in IE 10. 87 | */ 88 | 89 | a { 90 | background-color: transparent; 91 | } 92 | 93 | /** 94 | * Improve readability when focused and also mouse hovered in all browsers. 95 | */ 96 | 97 | a:active, 98 | a:hover { 99 | outline: 0; 100 | } 101 | 102 | /* Text-level semantics 103 | ========================================================================== */ 104 | 105 | /** 106 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome. 107 | */ 108 | 109 | abbr[title] { 110 | border-bottom: 1px dotted; 111 | } 112 | 113 | /** 114 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. 115 | */ 116 | 117 | b, 118 | strong { 119 | font-weight: bold; 120 | } 121 | 122 | /** 123 | * Address styling not present in Safari and Chrome. 124 | */ 125 | 126 | dfn { 127 | font-style: italic; 128 | } 129 | 130 | /** 131 | * Address variable `h1` font-size and margin within `section` and `article` 132 | * contexts in Firefox 4+, Safari, and Chrome. 133 | */ 134 | 135 | h1 { 136 | font-size: 2em; 137 | margin: 0.67em 0; 138 | } 139 | 140 | /** 141 | * Address styling not present in IE 8/9. 142 | */ 143 | 144 | mark { 145 | background: #ff0; 146 | color: #000; 147 | } 148 | 149 | /** 150 | * Address inconsistent and variable font size in all browsers. 151 | */ 152 | 153 | small { 154 | font-size: 80%; 155 | } 156 | 157 | /** 158 | * Prevent `sub` and `sup` affecting `line-height` in all browsers. 159 | */ 160 | 161 | sub, 162 | sup { 163 | font-size: 75%; 164 | line-height: 0; 165 | position: relative; 166 | vertical-align: baseline; 167 | } 168 | 169 | sup { 170 | top: -0.5em; 171 | } 172 | 173 | sub { 174 | bottom: -0.25em; 175 | } 176 | 177 | /* Embedded content 178 | ========================================================================== */ 179 | 180 | /** 181 | * Remove border when inside `a` element in IE 8/9/10. 182 | */ 183 | 184 | img { 185 | border: 0; 186 | } 187 | 188 | /** 189 | * Correct overflow not hidden in IE 9/10/11. 190 | */ 191 | 192 | svg:not(:root) { 193 | overflow: hidden; 194 | } 195 | 196 | /* Grouping content 197 | ========================================================================== */ 198 | 199 | /** 200 | * Address margin not present in IE 8/9 and Safari. 201 | */ 202 | 203 | figure { 204 | margin: 1em 40px; 205 | } 206 | 207 | /** 208 | * Address differences between Firefox and other browsers. 209 | */ 210 | 211 | hr { 212 | -moz-box-sizing: content-box; 213 | box-sizing: content-box; 214 | height: 0; 215 | } 216 | 217 | /** 218 | * Contain overflow in all browsers. 219 | */ 220 | 221 | pre { 222 | overflow: auto; 223 | } 224 | 225 | /** 226 | * Address odd `em`-unit font size rendering in all browsers. 227 | */ 228 | 229 | code, 230 | kbd, 231 | pre, 232 | samp { 233 | font-family: monospace, monospace; 234 | font-size: 1em; 235 | } 236 | 237 | /* Forms 238 | ========================================================================== */ 239 | 240 | /** 241 | * Known limitation: by default, Chrome and Safari on OS X allow very limited 242 | * styling of `select`, unless a `border` property is set. 243 | */ 244 | 245 | /** 246 | * 1. Correct color not being inherited. 247 | * Known issue: affects color of disabled elements. 248 | * 2. Correct font properties not being inherited. 249 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. 250 | */ 251 | 252 | button, 253 | input, 254 | optgroup, 255 | select, 256 | textarea { 257 | color: inherit; /* 1 */ 258 | font: inherit; /* 2 */ 259 | margin: 0; /* 3 */ 260 | } 261 | 262 | /** 263 | * Address `overflow` set to `hidden` in IE 8/9/10/11. 264 | */ 265 | 266 | button { 267 | overflow: visible; 268 | } 269 | 270 | /** 271 | * Address inconsistent `text-transform` inheritance for `button` and `select`. 272 | * All other form control elements do not inherit `text-transform` values. 273 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. 274 | * Correct `select` style inheritance in Firefox. 275 | */ 276 | 277 | button, 278 | select { 279 | text-transform: none; 280 | } 281 | 282 | /** 283 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` 284 | * and `video` controls. 285 | * 2. Correct inability to style clickable `input` types in iOS. 286 | * 3. Improve usability and consistency of cursor style between image-type 287 | * `input` and others. 288 | */ 289 | 290 | button, 291 | html input[type="button"], /* 1 */ 292 | input[type="reset"], 293 | input[type="submit"] { 294 | -webkit-appearance: button; /* 2 */ 295 | cursor: pointer; /* 3 */ 296 | } 297 | 298 | /** 299 | * Re-set default cursor for disabled elements. 300 | */ 301 | 302 | button[disabled], 303 | html input[disabled] { 304 | cursor: default; 305 | } 306 | 307 | /** 308 | * Remove inner padding and border in Firefox 4+. 309 | */ 310 | 311 | button::-moz-focus-inner, 312 | input::-moz-focus-inner { 313 | border: 0; 314 | padding: 0; 315 | } 316 | 317 | /** 318 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in 319 | * the UA stylesheet. 320 | */ 321 | 322 | input { 323 | line-height: normal; 324 | } 325 | 326 | /** 327 | * It's recommended that you don't attempt to style these elements. 328 | * Firefox's implementation doesn't respect box-sizing, padding, or width. 329 | * 330 | * 1. Address box sizing set to `content-box` in IE 8/9/10. 331 | * 2. Remove excess padding in IE 8/9/10. 332 | */ 333 | 334 | input[type="checkbox"], 335 | input[type="radio"] { 336 | box-sizing: border-box; /* 1 */ 337 | padding: 0; /* 2 */ 338 | } 339 | 340 | /** 341 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain 342 | * `font-size` values of the `input`, it causes the cursor style of the 343 | * decrement button to change from `default` to `text`. 344 | */ 345 | 346 | input[type="number"]::-webkit-inner-spin-button, 347 | input[type="number"]::-webkit-outer-spin-button { 348 | height: auto; 349 | } 350 | 351 | /** 352 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome. 353 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome 354 | * (include `-moz` to future-proof). 355 | */ 356 | 357 | input[type="search"] { 358 | -webkit-appearance: textfield; /* 1 */ 359 | -moz-box-sizing: content-box; 360 | -webkit-box-sizing: content-box; /* 2 */ 361 | box-sizing: content-box; 362 | } 363 | 364 | /** 365 | * Remove inner padding and search cancel button in Safari and Chrome on OS X. 366 | * Safari (but not Chrome) clips the cancel button when the search input has 367 | * padding (and `textfield` appearance). 368 | */ 369 | 370 | input[type="search"]::-webkit-search-cancel-button, 371 | input[type="search"]::-webkit-search-decoration { 372 | -webkit-appearance: none; 373 | } 374 | 375 | /** 376 | * Define consistent border, margin, and padding. 377 | */ 378 | 379 | fieldset { 380 | border: 1px solid #c0c0c0; 381 | margin: 0 2px; 382 | padding: 0.35em 0.625em 0.75em; 383 | } 384 | 385 | /** 386 | * 1. Correct `color` not being inherited in IE 8/9/10/11. 387 | * 2. Remove padding so people aren't caught out if they zero out fieldsets. 388 | */ 389 | 390 | legend { 391 | border: 0; /* 1 */ 392 | padding: 0; /* 2 */ 393 | } 394 | 395 | /** 396 | * Remove default vertical scrollbar in IE 8/9/10/11. 397 | */ 398 | 399 | textarea { 400 | overflow: auto; 401 | } 402 | 403 | /** 404 | * Don't inherit the `font-weight` (applied by a rule above). 405 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. 406 | */ 407 | 408 | optgroup { 409 | font-weight: bold; 410 | } 411 | 412 | /* Tables 413 | ========================================================================== */ 414 | 415 | /** 416 | * Remove most spacing between table cells. 417 | */ 418 | 419 | table { 420 | border-collapse: collapse; 421 | border-spacing: 0; 422 | } 423 | 424 | td, 425 | th { 426 | padding: 0; 427 | } 428 | -------------------------------------------------------------------------------- /source/stylesheets/screen.css.scss: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | @import 'normalize'; 3 | @import 'compass'; 4 | @import 'variables'; 5 | @import 'syntax'; 6 | @import 'icon-font'; 7 | 8 | /* 9 | Copyright 2008-2013 Concur Technologies, Inc. 10 | 11 | Licensed under the Apache License, Version 2.0 (the "License"); you may 12 | not use this file except in compliance with the License. You may obtain 13 | a copy of the License at 14 | 15 | http://www.apache.org/licenses/LICENSE-2.0 16 | 17 | Unless required by applicable law or agreed to in writing, software 18 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 19 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 20 | License for the specific language governing permissions and limitations 21 | under the License. 22 | */ 23 | 24 | //////////////////////////////////////////////////////////////////////////////// 25 | // GENERAL STUFF 26 | //////////////////////////////////////////////////////////////////////////////// 27 | 28 | html, body { 29 | color: $main-text; 30 | padding: 0; 31 | margin: 0; 32 | -webkit-font-smoothing: antialiased; 33 | -moz-osx-font-smoothing: grayscale; 34 | @extend %default-font; 35 | background-color: $main-bg; 36 | height: 100%; 37 | -webkit-text-size-adjust: none; /* Never autoresize text */ 38 | } 39 | 40 | #logo { 41 | font-weight: 300; 42 | font-size: 32px; 43 | color:#fff; 44 | margin: 0 0; 45 | padding: 15px 15px; 46 | 47 | span { 48 | font-weight: 400; 49 | } 50 | } 51 | 52 | //////////////////////////////////////////////////////////////////////////////// 53 | // TABLE OF CONTENTS 54 | //////////////////////////////////////////////////////////////////////////////// 55 | 56 | #toc > ul > li > a > span { 57 | float: right; 58 | background-color: #2484FF; 59 | border-radius: 40px; 60 | width: 20px; 61 | } 62 | 63 | @mixin embossed-bg { 64 | @include background( 65 | linear-gradient(top, 66 | rgba(#000, 0.2), 67 | rgba(#000, 0) 8px), 68 | linear-gradient(bottom, 69 | rgba(#000, 0.2), 70 | rgba(#000, 0) 8px), 71 | linear-gradient(top, 72 | rgba($nav-embossed-border-top, 1), 73 | rgba($nav-embossed-border-top, 0) 1.5px), 74 | linear-gradient(bottom, 75 | rgba($nav-embossed-border-bottom, 1), 76 | rgba($nav-embossed-border-bottom, 0) 1.5px), 77 | $nav-subitem-bg 78 | ); 79 | } 80 | 81 | .tocify-wrapper { 82 | @include transition(left ease-in-out 0.3s); 83 | overflow-y: auto; 84 | overflow-x: hidden; 85 | position: fixed; 86 | z-index: 30; 87 | top: 0; 88 | left: 0; 89 | bottom: 0; 90 | width: $nav-width; 91 | background-color: $nav-bg; 92 | font-size: 13px; 93 | font-weight: bold; 94 | 95 | // language selector for mobile devices 96 | .lang-selector { 97 | display: none; 98 | a { 99 | padding-top: 0.5em; 100 | padding-bottom: 0.5em; 101 | font-weight: 300; 102 | } 103 | } 104 | 105 | // This is the logo at the top of the ToC 106 | &>img { 107 | display: block; 108 | } 109 | 110 | &>.search { 111 | position: relative; 112 | 113 | input { 114 | font-weight: 300; 115 | background: $nav-bg; 116 | border-width: 0 0 1px 0; 117 | border-color: $search-box-border-color; 118 | padding: 6px 0 6px 20px; 119 | @include box-sizing(border-box); 120 | margin: $nav-v-padding $nav-padding; 121 | width: $nav-width - 30; 122 | outline: none; 123 | color: $nav-text; 124 | border-radius: 0; /* ios has a default border radius */ 125 | } 126 | 127 | &:before { 128 | position: absolute; 129 | top: 17px; 130 | left: $nav-padding; 131 | color: $nav-text; 132 | @extend %icon-search; 133 | } 134 | } 135 | 136 | img+.tocify { 137 | margin-top: $logo-margin; 138 | } 139 | 140 | .search-results { 141 | margin-top: 0; 142 | @include box-sizing(border-box); 143 | height: 0; 144 | overflow-y: auto; 145 | overflow-x: hidden; 146 | @include transition-property(height margin); 147 | @include transition-duration(180ms); 148 | @include transition-timing-function(ease-in-out); 149 | &.visible { 150 | height: 30%; 151 | margin-bottom: 1em; 152 | } 153 | 154 | //@include embossed-bg; 155 | 156 | li { 157 | margin: 1em $nav-padding; 158 | line-height: 1; 159 | } 160 | 161 | a { 162 | color: $nav-text; 163 | text-decoration: none; 164 | 165 | &:hover { 166 | text-decoration: underline; 167 | } 168 | } 169 | } 170 | 171 | 172 | .tocify-item>a, .toc-footer li { 173 | padding: 0 $nav-padding 0 $nav-padding; 174 | display: block; 175 | overflow-x: hidden; 176 | white-space: nowrap; 177 | text-overflow: ellipsis; 178 | } 179 | 180 | // The Table of Contents is composed of multiple nested 181 | // unordered lists. These styles remove the default 182 | // styling of an unordered list because it is ugly. 183 | ul, li { 184 | list-style: none; 185 | margin: 0; 186 | padding: 0; 187 | line-height: 28px; 188 | } 189 | 190 | li { 191 | color: $nav-text; 192 | @include transition-property('background'); 193 | @include transition-timing-function('linear'); 194 | @include transition-duration(230ms); 195 | } 196 | 197 | // This is the currently selected ToC entry 198 | .tocify-focus { 199 | //@include box-shadow(0px 1px 0px $nav-active-shadow); 200 | background-color: $nav-active-bg; 201 | color: $nav-active-text; 202 | } 203 | 204 | // Subheaders are the submenus that slide open 205 | // in the table of contents. 206 | .tocify-subheader { 207 | display: none; // tocify will override this when needed 208 | background-color: $nav-subitem-bg; 209 | font-weight: 500; 210 | .tocify-item>a { 211 | padding-left: $nav-padding + $nav-indent; 212 | font-size: 12px; 213 | } 214 | 215 | // for embossed look: 216 | //@include embossed-bg; 217 | &>li:last-child { 218 | box-shadow: none; // otherwise it'll overflow out of the subheader 219 | } 220 | } 221 | 222 | .toc-footer { 223 | padding: 1em 0; 224 | margin-top: 1em; 225 | border-top: 1px dashed $nav-footer-border-color; 226 | 227 | li,a { 228 | color: $nav-text; 229 | text-decoration: none; 230 | } 231 | 232 | a:hover { 233 | text-decoration: underline; 234 | } 235 | 236 | li { 237 | font-size: 0.8em; 238 | line-height: 1.7; 239 | text-decoration: none; 240 | } 241 | } 242 | 243 | } 244 | 245 | // button to show navigation on mobile devices 246 | #nav-button { 247 | span { 248 | display: block; 249 | $side-pad: $main-padding / 2 - 8px; 250 | padding: $side-pad $side-pad $side-pad; 251 | background-color: rgba($main-bg, 0.7); 252 | @include transform-origin(0, 0); 253 | @include transform(rotate(-90deg) translate(-100%, 0)); 254 | border-radius: 0 0 0 5px; 255 | } 256 | padding: 0 1.5em 5em 0; // increase touch size area 257 | display: none; 258 | position: fixed; 259 | top: 0; 260 | left: 0; 261 | z-index: 100; 262 | color: #000; 263 | text-decoration: none; 264 | font-weight: bold; 265 | opacity: 0.7; 266 | line-height: 16px; 267 | img { 268 | height: 16px; 269 | vertical-align: bottom; 270 | } 271 | 272 | @include transition(left ease-in-out 0.3s); 273 | 274 | &:hover { opacity: 1; } 275 | &.open {left: $nav-width} 276 | } 277 | 278 | 279 | //////////////////////////////////////////////////////////////////////////////// 280 | // PAGE LAYOUT AND CODE SAMPLE BACKGROUND 281 | //////////////////////////////////////////////////////////////////////////////// 282 | 283 | .page-wrapper { 284 | margin-left: $nav-width; 285 | position: relative; 286 | z-index: 10; 287 | background-color: $main-bg; 288 | min-height: 100%; 289 | 290 | padding-bottom: 1px; // prevent margin overflow 291 | 292 | // The dark box is what gives the code samples their dark background. 293 | // It sits essentially under the actual content block, which has a 294 | // transparent background. 295 | // I know, it's hackish, but it's the simplist way to make the left 296 | // half of the content always this background color. 297 | .dark-box { 298 | width: $examples-width; 299 | background-color: $examples-bg; 300 | position: absolute; 301 | right: 0; 302 | top: 0; 303 | bottom: 0; 304 | } 305 | 306 | .lang-selector { 307 | position: fixed; 308 | z-index: 50; 309 | border-bottom: 5px solid $lang-select-active-bg; 310 | } 311 | } 312 | 313 | .lang-selector { 314 | background-color: $lang-select-bg; 315 | width: 100%; 316 | font-weight: bold; 317 | a { 318 | display: block; 319 | float:left; 320 | color: $lang-select-text; 321 | text-decoration: none; 322 | padding: 0 10px; 323 | line-height: 30px; 324 | font-weight: 300; 325 | outline: 0; 326 | 327 | &:active, &:focus { 328 | background-color: $lang-select-pressed-bg; 329 | color: $lang-select-pressed-text; 330 | } 331 | 332 | &.active { 333 | background-color: $lang-select-active-bg; 334 | color: $lang-select-active-text; 335 | } 336 | } 337 | 338 | &:after { 339 | content: ''; 340 | clear: both; 341 | display: block; 342 | } 343 | } 344 | 345 | //////////////////////////////////////////////////////////////////////////////// 346 | // CONTENT STYLES 347 | //////////////////////////////////////////////////////////////////////////////// 348 | // This is all the stuff with the light background in the left half of the page 349 | 350 | .content { 351 | // to place content above the dark box 352 | position: relative; 353 | z-index: 30; 354 | 355 | &:after { 356 | content: ''; 357 | display: block; 358 | clear: both; 359 | } 360 | 361 | &>h1, &>h2, &>h3, &>h4, &>h5, &>h6, &>p, &>table, &>ul, &>ol, &>aside, &>dl { 362 | margin-right: $examples-width; 363 | padding: 0 $main-padding; 364 | @include box-sizing(border-box); 365 | display: block; 366 | @include text-shadow($main-embossed-text-shadow); 367 | 368 | @extend %left-col; 369 | } 370 | 371 | &>ul, &>ol { 372 | padding-left: $main-padding + 15px; 373 | 374 | 375 | li { 376 | 377 | padding-left: 10px; 378 | margin-bottom: 8px; 379 | } 380 | } 381 | 382 | 383 | 384 | // the div is the tocify hidden div for placeholding stuff 385 | &>h1, &>h2, &>div { 386 | clear:both; 387 | } 388 | 389 | h1 { 390 | @extend %header-font; 391 | font-size: 30px; 392 | line-height: 38px; 393 | padding-top: 0.5em; 394 | padding-bottom: 0.5em; 395 | border-bottom: 3px solid #eff0f4; 396 | margin-bottom: $h1-margin-bottom; 397 | margin-top: 2em; 398 | border-top: 1px solid #eff0f4; 399 | background: #eff0f4; 400 | } 401 | 402 | h1:first-child, div:first-child + h1 { 403 | border-top-width: 0; 404 | margin-top: 0; 405 | } 406 | 407 | h2 { 408 | @extend %header-font; 409 | font-size: 20px; 410 | line-height: 24px; 411 | margin-top: 4em; 412 | margin-bottom: 0; 413 | border-top: 3px solid #eff0f4; 414 | padding-top: 1.2em; 415 | padding-bottom: 1.2em; 416 | @include background-image( 417 | linear-gradient(top, rgba(#fff,0.4), rgba(#fff, 0)) 418 | ); 419 | } 420 | 421 | // h2s right after h1s should bump right up 422 | // against the h1s. 423 | h1 + h2, h1 + div + h2 { 424 | margin-top: $h1-margin-bottom * -1; 425 | border-top: none; 426 | } 427 | 428 | h3, h4, h5, h6 { 429 | @extend %header-font; 430 | font-size: 12px; 431 | margin-top: 2.5em; 432 | margin-bottom: 0.8em; 433 | text-transform: uppercase; 434 | } 435 | 436 | h4, h5, h6 { 437 | font-size: 10px; 438 | } 439 | 440 | hr { 441 | margin: 2em 0; 442 | border-top: 2px solid $examples-bg; 443 | border-bottom: 2px solid $main-bg; 444 | } 445 | 446 | table { 447 | margin-bottom: 1em; 448 | overflow: auto; 449 | th,td { 450 | text-align: left; 451 | vertical-align: top; 452 | line-height: 1.6; 453 | } 454 | 455 | th { 456 | font-size: 14px; 457 | padding: 5px 10px; 458 | background: #eff0f4; 459 | vertical-align: bottom; 460 | } 461 | 462 | td { 463 | padding: 10px; 464 | } 465 | 466 | tr { 467 | border-bottom: 1px solid #eff0f4; 468 | } 469 | 470 | tr:nth-child(odd)>td { 471 | background-color: lighten($main-bg,4.2%); 472 | } 473 | 474 | tr:nth-child(even)>td { 475 | background-color: lighten($main-bg,2.4%); 476 | } 477 | } 478 | 479 | dt { 480 | font-weight: bold; 481 | } 482 | 483 | dd { 484 | margin-left: 15px; 485 | } 486 | 487 | p, li, dt, dd { 488 | line-height: 1.6; 489 | margin-top: 0; 490 | } 491 | 492 | img { 493 | max-width: 100%; 494 | } 495 | 496 | code { 497 | background-color: #eff0f4; 498 | padding: 3px; 499 | border-radius: 3px; 500 | @extend %break-words; 501 | @extend %code-font; 502 | } 503 | 504 | pre>code { 505 | background-color: transparent; 506 | padding: 0; 507 | white-space: pre-wrap; 508 | } 509 | 510 | aside { 511 | padding-top: 1em; 512 | padding-bottom: 1em; 513 | @include text-shadow(0 1px 0 lighten($aside-notice-bg, 15%)); 514 | margin-top: 1.5em; 515 | margin-bottom: 1.5em; 516 | background: $aside-notice-bg; 517 | line-height: 1.6; 518 | 519 | &.warning { 520 | background-color: $aside-warning-bg; 521 | @include text-shadow(0 1px 0 lighten($aside-warning-bg, 15%)); 522 | } 523 | 524 | &.success { 525 | background-color: $aside-success-bg; 526 | @include text-shadow(0 1px 0 lighten($aside-success-bg, 15%)); 527 | } 528 | } 529 | 530 | aside:before { 531 | vertical-align: middle; 532 | padding-right: 0.5em; 533 | font-size: 14px; 534 | } 535 | 536 | aside.notice:before { 537 | @extend %icon-info-sign; 538 | } 539 | 540 | aside.warning:before { 541 | @extend %icon-exclamation-sign; 542 | } 543 | 544 | aside.success:before { 545 | @extend %icon-ok-sign; 546 | } 547 | 548 | .search-highlight { 549 | padding: 2px; 550 | margin: -2px; 551 | border-radius: 4px; 552 | border: 1px solid #F7E633; 553 | //@include text-shadow(1px 1px 0 #666); 554 | @include background(linear-gradient(bottom right, #F7E633 0%, #F1D32F 100%)); 555 | } 556 | } 557 | 558 | //////////////////////////////////////////////////////////////////////////////// 559 | // CODE SAMPLE STYLES 560 | //////////////////////////////////////////////////////////////////////////////// 561 | // This is all the stuff that appears in the right half of the page 562 | 563 | .content { 564 | pre { 565 | background-color: $code-bg; 566 | color: #fff; 567 | 568 | padding: 1em $main-padding; 569 | margin: 0; 570 | width: $examples-width; 571 | 572 | float:right; 573 | clear:right; 574 | 575 | @include box-sizing(border-box); 576 | @include text-shadow(0px 1px 2px rgba(0,0,0,0.4)); 577 | 578 | @extend %right-col; 579 | 580 | &>p { margin: 0; } 581 | 582 | a { 583 | color: #fff; 584 | text-decoration: none; 585 | border-bottom: dashed 1px #ccc; 586 | } 587 | } 588 | 589 | h1 + blockquote, h2 + blockquote { 590 | padding-top: 0; 591 | } 592 | 593 | blockquote { 594 | background-color: $code-bg; 595 | color: #fff; 596 | 597 | padding: 1em 0; 598 | margin: 0; 599 | width: $examples-width; 600 | 601 | float:right; 602 | clear:right; 603 | 604 | @include box-sizing(border-box); 605 | @include text-shadow(0px 1px 2px rgba(0,0,0,0.4)); 606 | 607 | @extend %right-col; 608 | 609 | &>p { margin: 0; } 610 | 611 | code { 612 | background: $code-bg; 613 | color: #fff; 614 | } 615 | } 616 | 617 | pre { 618 | @extend %code-font; 619 | } 620 | 621 | blockquote { 622 | &>p { 623 | background-color: $code-annotation-bg; 624 | border-radius: 0px; 625 | padding: $code-annotation-padding $main-padding; 626 | color: #ccc; 627 | //border-top: 1px solid #000; 628 | //border-bottom: 1px solid #404040; 629 | } 630 | } 631 | 632 | a { 633 | font-weight: bold; 634 | color: $link-text; 635 | } 636 | } 637 | 638 | //////////////////////////////////////////////////////////////////////////////// 639 | // RESPONSIVE DESIGN 640 | //////////////////////////////////////////////////////////////////////////////// 641 | // These are the styles for phones and tablets 642 | // There are also a couple styles disperesed 643 | 644 | @media (max-width: $tablet-width) { 645 | .tocify-wrapper { 646 | left: -$nav-width; 647 | 648 | &.open { 649 | left: 0; 650 | } 651 | } 652 | 653 | .page-wrapper { 654 | margin-left: 0; 655 | } 656 | 657 | #nav-button { 658 | display: block; 659 | } 660 | 661 | .tocify-wrapper .tocify-item > a { 662 | padding-top: 0.3em; 663 | padding-bottom: 0.3em; 664 | } 665 | } 666 | 667 | @media (max-width: $phone-width) { 668 | .dark-box { 669 | display: none; 670 | } 671 | 672 | %left-col { 673 | margin-right: 0; 674 | } 675 | 676 | .tocify-wrapper .lang-selector { 677 | display: block; 678 | } 679 | 680 | .page-wrapper .lang-selector { 681 | display: none; 682 | } 683 | 684 | %right-col { 685 | width: auto; 686 | float: none; 687 | } 688 | 689 | %right-col + %left-col { 690 | margin-top: $main-padding; 691 | } 692 | 693 | .content { 694 | h1 { 695 | font-size: 26px; 696 | line-height: 30px; 697 | } 698 | } 699 | } 700 | -------------------------------------------------------------------------------- /source/javascripts/lib/jquery_ui.js: -------------------------------------------------------------------------------- 1 | /*! jQuery UI - v1.11.3 - 2015-02-12 2 | * http://jqueryui.com 3 | * Includes: widget.js 4 | * Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */ 5 | 6 | (function( factory ) { 7 | if ( typeof define === "function" && define.amd ) { 8 | 9 | // AMD. Register as an anonymous module. 10 | define([ "jquery" ], factory ); 11 | } else { 12 | 13 | // Browser globals 14 | factory( jQuery ); 15 | } 16 | }(function( $ ) { 17 | /*! 18 | * jQuery UI Widget 1.11.3 19 | * http://jqueryui.com 20 | * 21 | * Copyright jQuery Foundation and other contributors 22 | * Released under the MIT license. 23 | * http://jquery.org/license 24 | * 25 | * http://api.jqueryui.com/jQuery.widget/ 26 | */ 27 | 28 | 29 | var widget_uuid = 0, 30 | widget_slice = Array.prototype.slice; 31 | 32 | $.cleanData = (function( orig ) { 33 | return function( elems ) { 34 | var events, elem, i; 35 | for ( i = 0; (elem = elems[i]) != null; i++ ) { 36 | try { 37 | 38 | // Only trigger remove when necessary to save time 39 | events = $._data( elem, "events" ); 40 | if ( events && events.remove ) { 41 | $( elem ).triggerHandler( "remove" ); 42 | } 43 | 44 | // http://bugs.jquery.com/ticket/8235 45 | } catch ( e ) {} 46 | } 47 | orig( elems ); 48 | }; 49 | })( $.cleanData ); 50 | 51 | $.widget = function( name, base, prototype ) { 52 | var fullName, existingConstructor, constructor, basePrototype, 53 | // proxiedPrototype allows the provided prototype to remain unmodified 54 | // so that it can be used as a mixin for multiple widgets (#8876) 55 | proxiedPrototype = {}, 56 | namespace = name.split( "." )[ 0 ]; 57 | 58 | name = name.split( "." )[ 1 ]; 59 | fullName = namespace + "-" + name; 60 | 61 | if ( !prototype ) { 62 | prototype = base; 63 | base = $.Widget; 64 | } 65 | 66 | // create selector for plugin 67 | $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { 68 | return !!$.data( elem, fullName ); 69 | }; 70 | 71 | $[ namespace ] = $[ namespace ] || {}; 72 | existingConstructor = $[ namespace ][ name ]; 73 | constructor = $[ namespace ][ name ] = function( options, element ) { 74 | // allow instantiation without "new" keyword 75 | if ( !this._createWidget ) { 76 | return new constructor( options, element ); 77 | } 78 | 79 | // allow instantiation without initializing for simple inheritance 80 | // must use "new" keyword (the code above always passes args) 81 | if ( arguments.length ) { 82 | this._createWidget( options, element ); 83 | } 84 | }; 85 | // extend with the existing constructor to carry over any static properties 86 | $.extend( constructor, existingConstructor, { 87 | version: prototype.version, 88 | // copy the object used to create the prototype in case we need to 89 | // redefine the widget later 90 | _proto: $.extend( {}, prototype ), 91 | // track widgets that inherit from this widget in case this widget is 92 | // redefined after a widget inherits from it 93 | _childConstructors: [] 94 | }); 95 | 96 | basePrototype = new base(); 97 | // we need to make the options hash a property directly on the new instance 98 | // otherwise we'll modify the options hash on the prototype that we're 99 | // inheriting from 100 | basePrototype.options = $.widget.extend( {}, basePrototype.options ); 101 | $.each( prototype, function( prop, value ) { 102 | if ( !$.isFunction( value ) ) { 103 | proxiedPrototype[ prop ] = value; 104 | return; 105 | } 106 | proxiedPrototype[ prop ] = (function() { 107 | var _super = function() { 108 | return base.prototype[ prop ].apply( this, arguments ); 109 | }, 110 | _superApply = function( args ) { 111 | return base.prototype[ prop ].apply( this, args ); 112 | }; 113 | return function() { 114 | var __super = this._super, 115 | __superApply = this._superApply, 116 | returnValue; 117 | 118 | this._super = _super; 119 | this._superApply = _superApply; 120 | 121 | returnValue = value.apply( this, arguments ); 122 | 123 | this._super = __super; 124 | this._superApply = __superApply; 125 | 126 | return returnValue; 127 | }; 128 | })(); 129 | }); 130 | constructor.prototype = $.widget.extend( basePrototype, { 131 | // TODO: remove support for widgetEventPrefix 132 | // always use the name + a colon as the prefix, e.g., draggable:start 133 | // don't prefix for widgets that aren't DOM-based 134 | widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name 135 | }, proxiedPrototype, { 136 | constructor: constructor, 137 | namespace: namespace, 138 | widgetName: name, 139 | widgetFullName: fullName 140 | }); 141 | 142 | // If this widget is being redefined then we need to find all widgets that 143 | // are inheriting from it and redefine all of them so that they inherit from 144 | // the new version of this widget. We're essentially trying to replace one 145 | // level in the prototype chain. 146 | if ( existingConstructor ) { 147 | $.each( existingConstructor._childConstructors, function( i, child ) { 148 | var childPrototype = child.prototype; 149 | 150 | // redefine the child widget using the same prototype that was 151 | // originally used, but inherit from the new version of the base 152 | $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); 153 | }); 154 | // remove the list of existing child constructors from the old constructor 155 | // so the old child constructors can be garbage collected 156 | delete existingConstructor._childConstructors; 157 | } else { 158 | base._childConstructors.push( constructor ); 159 | } 160 | 161 | $.widget.bridge( name, constructor ); 162 | 163 | return constructor; 164 | }; 165 | 166 | $.widget.extend = function( target ) { 167 | var input = widget_slice.call( arguments, 1 ), 168 | inputIndex = 0, 169 | inputLength = input.length, 170 | key, 171 | value; 172 | for ( ; inputIndex < inputLength; inputIndex++ ) { 173 | for ( key in input[ inputIndex ] ) { 174 | value = input[ inputIndex ][ key ]; 175 | if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { 176 | // Clone objects 177 | if ( $.isPlainObject( value ) ) { 178 | target[ key ] = $.isPlainObject( target[ key ] ) ? 179 | $.widget.extend( {}, target[ key ], value ) : 180 | // Don't extend strings, arrays, etc. with objects 181 | $.widget.extend( {}, value ); 182 | // Copy everything else by reference 183 | } else { 184 | target[ key ] = value; 185 | } 186 | } 187 | } 188 | } 189 | return target; 190 | }; 191 | 192 | $.widget.bridge = function( name, object ) { 193 | var fullName = object.prototype.widgetFullName || name; 194 | $.fn[ name ] = function( options ) { 195 | var isMethodCall = typeof options === "string", 196 | args = widget_slice.call( arguments, 1 ), 197 | returnValue = this; 198 | 199 | if ( isMethodCall ) { 200 | this.each(function() { 201 | var methodValue, 202 | instance = $.data( this, fullName ); 203 | if ( options === "instance" ) { 204 | returnValue = instance; 205 | return false; 206 | } 207 | if ( !instance ) { 208 | return $.error( "cannot call methods on " + name + " prior to initialization; " + 209 | "attempted to call method '" + options + "'" ); 210 | } 211 | if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { 212 | return $.error( "no such method '" + options + "' for " + name + " widget instance" ); 213 | } 214 | methodValue = instance[ options ].apply( instance, args ); 215 | if ( methodValue !== instance && methodValue !== undefined ) { 216 | returnValue = methodValue && methodValue.jquery ? 217 | returnValue.pushStack( methodValue.get() ) : 218 | methodValue; 219 | return false; 220 | } 221 | }); 222 | } else { 223 | 224 | // Allow multiple hashes to be passed on init 225 | if ( args.length ) { 226 | options = $.widget.extend.apply( null, [ options ].concat(args) ); 227 | } 228 | 229 | this.each(function() { 230 | var instance = $.data( this, fullName ); 231 | if ( instance ) { 232 | instance.option( options || {} ); 233 | if ( instance._init ) { 234 | instance._init(); 235 | } 236 | } else { 237 | $.data( this, fullName, new object( options, this ) ); 238 | } 239 | }); 240 | } 241 | 242 | return returnValue; 243 | }; 244 | }; 245 | 246 | $.Widget = function( /* options, element */ ) {}; 247 | $.Widget._childConstructors = []; 248 | 249 | $.Widget.prototype = { 250 | widgetName: "widget", 251 | widgetEventPrefix: "", 252 | defaultElement: "
    ", 253 | options: { 254 | disabled: false, 255 | 256 | // callbacks 257 | create: null 258 | }, 259 | _createWidget: function( options, element ) { 260 | element = $( element || this.defaultElement || this )[ 0 ]; 261 | this.element = $( element ); 262 | this.uuid = widget_uuid++; 263 | this.eventNamespace = "." + this.widgetName + this.uuid; 264 | 265 | this.bindings = $(); 266 | this.hoverable = $(); 267 | this.focusable = $(); 268 | 269 | if ( element !== this ) { 270 | $.data( element, this.widgetFullName, this ); 271 | this._on( true, this.element, { 272 | remove: function( event ) { 273 | if ( event.target === element ) { 274 | this.destroy(); 275 | } 276 | } 277 | }); 278 | this.document = $( element.style ? 279 | // element within the document 280 | element.ownerDocument : 281 | // element is window or document 282 | element.document || element ); 283 | this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); 284 | } 285 | 286 | this.options = $.widget.extend( {}, 287 | this.options, 288 | this._getCreateOptions(), 289 | options ); 290 | 291 | this._create(); 292 | this._trigger( "create", null, this._getCreateEventData() ); 293 | this._init(); 294 | }, 295 | _getCreateOptions: $.noop, 296 | _getCreateEventData: $.noop, 297 | _create: $.noop, 298 | _init: $.noop, 299 | 300 | destroy: function() { 301 | this._destroy(); 302 | // we can probably remove the unbind calls in 2.0 303 | // all event bindings should go through this._on() 304 | this.element 305 | .unbind( this.eventNamespace ) 306 | .removeData( this.widgetFullName ) 307 | // support: jquery <1.6.3 308 | // http://bugs.jquery.com/ticket/9413 309 | .removeData( $.camelCase( this.widgetFullName ) ); 310 | this.widget() 311 | .unbind( this.eventNamespace ) 312 | .removeAttr( "aria-disabled" ) 313 | .removeClass( 314 | this.widgetFullName + "-disabled " + 315 | "ui-state-disabled" ); 316 | 317 | // clean up events and states 318 | this.bindings.unbind( this.eventNamespace ); 319 | this.hoverable.removeClass( "ui-state-hover" ); 320 | this.focusable.removeClass( "ui-state-focus" ); 321 | }, 322 | _destroy: $.noop, 323 | 324 | widget: function() { 325 | return this.element; 326 | }, 327 | 328 | option: function( key, value ) { 329 | var options = key, 330 | parts, 331 | curOption, 332 | i; 333 | 334 | if ( arguments.length === 0 ) { 335 | // don't return a reference to the internal hash 336 | return $.widget.extend( {}, this.options ); 337 | } 338 | 339 | if ( typeof key === "string" ) { 340 | // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 341 | options = {}; 342 | parts = key.split( "." ); 343 | key = parts.shift(); 344 | if ( parts.length ) { 345 | curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 346 | for ( i = 0; i < parts.length - 1; i++ ) { 347 | curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 348 | curOption = curOption[ parts[ i ] ]; 349 | } 350 | key = parts.pop(); 351 | if ( arguments.length === 1 ) { 352 | return curOption[ key ] === undefined ? null : curOption[ key ]; 353 | } 354 | curOption[ key ] = value; 355 | } else { 356 | if ( arguments.length === 1 ) { 357 | return this.options[ key ] === undefined ? null : this.options[ key ]; 358 | } 359 | options[ key ] = value; 360 | } 361 | } 362 | 363 | this._setOptions( options ); 364 | 365 | return this; 366 | }, 367 | _setOptions: function( options ) { 368 | var key; 369 | 370 | for ( key in options ) { 371 | this._setOption( key, options[ key ] ); 372 | } 373 | 374 | return this; 375 | }, 376 | _setOption: function( key, value ) { 377 | this.options[ key ] = value; 378 | 379 | if ( key === "disabled" ) { 380 | this.widget() 381 | .toggleClass( this.widgetFullName + "-disabled", !!value ); 382 | 383 | // If the widget is becoming disabled, then nothing is interactive 384 | if ( value ) { 385 | this.hoverable.removeClass( "ui-state-hover" ); 386 | this.focusable.removeClass( "ui-state-focus" ); 387 | } 388 | } 389 | 390 | return this; 391 | }, 392 | 393 | enable: function() { 394 | return this._setOptions({ disabled: false }); 395 | }, 396 | disable: function() { 397 | return this._setOptions({ disabled: true }); 398 | }, 399 | 400 | _on: function( suppressDisabledCheck, element, handlers ) { 401 | var delegateElement, 402 | instance = this; 403 | 404 | // no suppressDisabledCheck flag, shuffle arguments 405 | if ( typeof suppressDisabledCheck !== "boolean" ) { 406 | handlers = element; 407 | element = suppressDisabledCheck; 408 | suppressDisabledCheck = false; 409 | } 410 | 411 | // no element argument, shuffle and use this.element 412 | if ( !handlers ) { 413 | handlers = element; 414 | element = this.element; 415 | delegateElement = this.widget(); 416 | } else { 417 | element = delegateElement = $( element ); 418 | this.bindings = this.bindings.add( element ); 419 | } 420 | 421 | $.each( handlers, function( event, handler ) { 422 | function handlerProxy() { 423 | // allow widgets to customize the disabled handling 424 | // - disabled as an array instead of boolean 425 | // - disabled class as method for disabling individual parts 426 | if ( !suppressDisabledCheck && 427 | ( instance.options.disabled === true || 428 | $( this ).hasClass( "ui-state-disabled" ) ) ) { 429 | return; 430 | } 431 | return ( typeof handler === "string" ? instance[ handler ] : handler ) 432 | .apply( instance, arguments ); 433 | } 434 | 435 | // copy the guid so direct unbinding works 436 | if ( typeof handler !== "string" ) { 437 | handlerProxy.guid = handler.guid = 438 | handler.guid || handlerProxy.guid || $.guid++; 439 | } 440 | 441 | var match = event.match( /^([\w:-]*)\s*(.*)$/ ), 442 | eventName = match[1] + instance.eventNamespace, 443 | selector = match[2]; 444 | if ( selector ) { 445 | delegateElement.delegate( selector, eventName, handlerProxy ); 446 | } else { 447 | element.bind( eventName, handlerProxy ); 448 | } 449 | }); 450 | }, 451 | 452 | _off: function( element, eventName ) { 453 | eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + 454 | this.eventNamespace; 455 | element.unbind( eventName ).undelegate( eventName ); 456 | 457 | // Clear the stack to avoid memory leaks (#10056) 458 | this.bindings = $( this.bindings.not( element ).get() ); 459 | this.focusable = $( this.focusable.not( element ).get() ); 460 | this.hoverable = $( this.hoverable.not( element ).get() ); 461 | }, 462 | 463 | _delay: function( handler, delay ) { 464 | function handlerProxy() { 465 | return ( typeof handler === "string" ? instance[ handler ] : handler ) 466 | .apply( instance, arguments ); 467 | } 468 | var instance = this; 469 | return setTimeout( handlerProxy, delay || 0 ); 470 | }, 471 | 472 | _hoverable: function( element ) { 473 | this.hoverable = this.hoverable.add( element ); 474 | this._on( element, { 475 | mouseenter: function( event ) { 476 | $( event.currentTarget ).addClass( "ui-state-hover" ); 477 | }, 478 | mouseleave: function( event ) { 479 | $( event.currentTarget ).removeClass( "ui-state-hover" ); 480 | } 481 | }); 482 | }, 483 | 484 | _focusable: function( element ) { 485 | this.focusable = this.focusable.add( element ); 486 | this._on( element, { 487 | focusin: function( event ) { 488 | $( event.currentTarget ).addClass( "ui-state-focus" ); 489 | }, 490 | focusout: function( event ) { 491 | $( event.currentTarget ).removeClass( "ui-state-focus" ); 492 | } 493 | }); 494 | }, 495 | 496 | _trigger: function( type, event, data ) { 497 | var prop, orig, 498 | callback = this.options[ type ]; 499 | 500 | data = data || {}; 501 | event = $.Event( event ); 502 | event.type = ( type === this.widgetEventPrefix ? 503 | type : 504 | this.widgetEventPrefix + type ).toLowerCase(); 505 | // the original event may come from any element 506 | // so we need to reset the target on the new event 507 | event.target = this.element[ 0 ]; 508 | 509 | // copy original event properties over to the new event 510 | orig = event.originalEvent; 511 | if ( orig ) { 512 | for ( prop in orig ) { 513 | if ( !( prop in event ) ) { 514 | event[ prop ] = orig[ prop ]; 515 | } 516 | } 517 | } 518 | 519 | this.element.trigger( event, data ); 520 | return !( $.isFunction( callback ) && 521 | callback.apply( this.element[0], [ event ].concat( data ) ) === false || 522 | event.isDefaultPrevented() ); 523 | } 524 | }; 525 | 526 | $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 527 | $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 528 | if ( typeof options === "string" ) { 529 | options = { effect: options }; 530 | } 531 | var hasOptions, 532 | effectName = !options ? 533 | method : 534 | options === true || typeof options === "number" ? 535 | defaultEffect : 536 | options.effect || defaultEffect; 537 | options = options || {}; 538 | if ( typeof options === "number" ) { 539 | options = { duration: options }; 540 | } 541 | hasOptions = !$.isEmptyObject( options ); 542 | options.complete = callback; 543 | if ( options.delay ) { 544 | element.delay( options.delay ); 545 | } 546 | if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 547 | element[ method ]( options ); 548 | } else if ( effectName !== method && element[ effectName ] ) { 549 | element[ effectName ]( options.duration, options.easing, callback ); 550 | } else { 551 | element.queue(function( next ) { 552 | $( this )[ method ](); 553 | if ( callback ) { 554 | callback.call( element[ 0 ] ); 555 | } 556 | next(); 557 | }); 558 | } 559 | }; 560 | }); 561 | 562 | var widget = $.widget; 563 | 564 | 565 | 566 | })); 567 | -------------------------------------------------------------------------------- /source/javascripts/lib/jquery.tocify.js: -------------------------------------------------------------------------------- 1 | //= require ./jquery_ui 2 | /* jquery Tocify - v1.8.0 - 2013-09-16 3 | * http://www.gregfranko.com/jquery.tocify.js/ 4 | * Copyright (c) 2013 Greg Franko; Licensed MIT 5 | * Modified lightly by Robert Lord to fix a bug I found, 6 | * and also so it adds ids to headers 7 | * also because I want height caching, since the 8 | * height lookup for h1s and h2s was causing serious 9 | * lag spikes below 30 fps */ 10 | 11 | // Immediately-Invoked Function Expression (IIFE) [Ben Alman Blog Post](http://benalman.com/news/2010/11/immediately-invoked-function-expression/) that calls another IIFE that contains all of the plugin logic. I used this pattern so that anyone viewing this code would not have to scroll to the bottom of the page to view the local parameters that were passed to the main IIFE. 12 | (function(tocify) { 13 | 14 | // ECMAScript 5 Strict Mode: [John Resig Blog Post](http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/) 15 | "use strict"; 16 | 17 | // Calls the second IIFE and locally passes in the global jQuery, window, and document objects 18 | tocify(window.jQuery, window, document); 19 | 20 | } 21 | 22 | // Locally passes in `jQuery`, the `window` object, the `document` object, and an `undefined` variable. The `jQuery`, `window` and `document` objects are passed in locally, to improve performance, since javascript first searches for a variable match within the local variables set before searching the global variables set. All of the global variables are also passed in locally to be minifier friendly. `undefined` can be passed in locally, because it is not a reserved word in JavaScript. 23 | (function($, window, document, undefined) { 24 | 25 | // ECMAScript 5 Strict Mode: [John Resig Blog Post](http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/) 26 | "use strict"; 27 | 28 | var tocClassName = "tocify", 29 | tocClass = "." + tocClassName, 30 | tocFocusClassName = "tocify-focus", 31 | tocHoverClassName = "tocify-hover", 32 | hideTocClassName = "tocify-hide", 33 | hideTocClass = "." + hideTocClassName, 34 | headerClassName = "tocify-header", 35 | headerClass = "." + headerClassName, 36 | subheaderClassName = "tocify-subheader", 37 | subheaderClass = "." + subheaderClassName, 38 | itemClassName = "tocify-item", 39 | itemClass = "." + itemClassName, 40 | extendPageClassName = "tocify-extend-page", 41 | extendPageClass = "." + extendPageClassName; 42 | 43 | // Calling the jQueryUI Widget Factory Method 44 | $.widget("toc.tocify", { 45 | 46 | //Plugin version 47 | version: "1.8.0", 48 | 49 | // These options will be used as defaults 50 | options: { 51 | 52 | // **context**: Accepts String: Any jQuery selector 53 | // The container element that holds all of the elements used to generate the table of contents 54 | context: "body", 55 | 56 | // **ignoreSelector**: Accepts String: Any jQuery selector 57 | // A selector to any element that would be matched by selectors that you wish to be ignored 58 | ignoreSelector: null, 59 | 60 | // **selectors**: Accepts an Array of Strings: Any jQuery selectors 61 | // The element's used to generate the table of contents. The order is very important since it will determine the table of content's nesting structure 62 | selectors: "h1, h2, h3", 63 | 64 | // **showAndHide**: Accepts a boolean: true or false 65 | // Used to determine if elements should be shown and hidden 66 | showAndHide: true, 67 | 68 | // **showEffect**: Accepts String: "none", "fadeIn", "show", or "slideDown" 69 | // Used to display any of the table of contents nested items 70 | showEffect: "slideDown", 71 | 72 | // **showEffectSpeed**: Accepts Number (milliseconds) or String: "slow", "medium", or "fast" 73 | // The time duration of the show animation 74 | showEffectSpeed: "medium", 75 | 76 | // **hideEffect**: Accepts String: "none", "fadeOut", "hide", or "slideUp" 77 | // Used to hide any of the table of contents nested items 78 | hideEffect: "slideUp", 79 | 80 | // **hideEffectSpeed**: Accepts Number (milliseconds) or String: "slow", "medium", or "fast" 81 | // The time duration of the hide animation 82 | hideEffectSpeed: "medium", 83 | 84 | // **smoothScroll**: Accepts a boolean: true or false 85 | // Determines if a jQuery animation should be used to scroll to specific table of contents items on the page 86 | smoothScroll: true, 87 | 88 | // **smoothScrollSpeed**: Accepts Number (milliseconds) or String: "slow", "medium", or "fast" 89 | // The time duration of the smoothScroll animation 90 | smoothScrollSpeed: "medium", 91 | 92 | // **scrollTo**: Accepts Number (pixels) 93 | // The amount of space between the top of page and the selected table of contents item after the page has been scrolled 94 | scrollTo: 0, 95 | 96 | // **showAndHideOnScroll**: Accepts a boolean: true or false 97 | // Determines if table of contents nested items should be shown and hidden while scrolling 98 | showAndHideOnScroll: true, 99 | 100 | // **highlightOnScroll**: Accepts a boolean: true or false 101 | // Determines if table of contents nested items should be highlighted (set to a different color) while scrolling 102 | highlightOnScroll: true, 103 | 104 | // **highlightOffset**: Accepts a number 105 | // The offset distance in pixels to trigger the next active table of contents item 106 | highlightOffset: 40, 107 | 108 | // **theme**: Accepts a string: "bootstrap", "jqueryui", or "none" 109 | // Determines if Twitter Bootstrap, jQueryUI, or Tocify classes should be added to the table of contents 110 | theme: "bootstrap", 111 | 112 | // **extendPage**: Accepts a boolean: true or false 113 | // If a user scrolls to the bottom of the page and the page is not tall enough to scroll to the last table of contents item, then the page height is increased 114 | extendPage: true, 115 | 116 | // **extendPageOffset**: Accepts a number: pixels 117 | // How close to the bottom of the page a user must scroll before the page is extended 118 | extendPageOffset: 100, 119 | 120 | // **history**: Accepts a boolean: true or false 121 | // Adds a hash to the page url to maintain history 122 | history: true, 123 | 124 | // **scrollHistory**: Accepts a boolean: true or false 125 | // Adds a hash to the page url, to maintain history, when scrolling to a TOC item 126 | scrollHistory: false, 127 | 128 | // **hashGenerator**: How the hash value (the anchor segment of the URL, following the 129 | // # character) will be generated. 130 | // 131 | // "compact" (default) - #CompressesEverythingTogether 132 | // "pretty" - #looks-like-a-nice-url-and-is-easily-readable 133 | // function(text, element){} - Your own hash generation function that accepts the text as an 134 | // argument, and returns the hash value. 135 | hashGenerator: "compact", 136 | 137 | // **highlightDefault**: Accepts a boolean: true or false 138 | // Set's the first TOC item as active if no other TOC item is active. 139 | highlightDefault: true 140 | 141 | }, 142 | 143 | // _Create 144 | // ------- 145 | // Constructs the plugin. Only called once. 146 | _create: function() { 147 | 148 | var self = this; 149 | 150 | self.tocifyWrapper = $('.tocify-wrapper'); 151 | self.extendPageScroll = true; 152 | 153 | // Internal array that keeps track of all TOC items (Helps to recognize if there are duplicate TOC item strings) 154 | self.items = []; 155 | 156 | // Generates the HTML for the dynamic table of contents 157 | self._generateToc(); 158 | 159 | // Caches heights and anchors 160 | self.cachedHeights = [], 161 | self.cachedAnchors = []; 162 | 163 | // Adds CSS classes to the newly generated table of contents HTML 164 | self._addCSSClasses(); 165 | 166 | self.webkit = (function() { 167 | 168 | for(var prop in window) { 169 | 170 | if(prop) { 171 | 172 | if(prop.toLowerCase().indexOf("webkit") !== -1) { 173 | 174 | return true; 175 | 176 | } 177 | 178 | } 179 | 180 | } 181 | 182 | return false; 183 | 184 | }()); 185 | 186 | // Adds jQuery event handlers to the newly generated table of contents 187 | self._setEventHandlers(); 188 | 189 | // Binding to the Window load event to make sure the correct scrollTop is calculated 190 | $(window).load(function() { 191 | 192 | // Sets the active TOC item 193 | self._setActiveElement(true); 194 | 195 | // Once all animations on the page are complete, this callback function will be called 196 | $("html, body").promise().done(function() { 197 | 198 | setTimeout(function() { 199 | 200 | self.extendPageScroll = false; 201 | 202 | },0); 203 | 204 | }); 205 | 206 | }); 207 | 208 | }, 209 | 210 | // _generateToc 211 | // ------------ 212 | // Generates the HTML for the dynamic table of contents 213 | _generateToc: function() { 214 | 215 | // _Local variables_ 216 | 217 | // Stores the plugin context in the self variable 218 | var self = this, 219 | 220 | // All of the HTML tags found within the context provided (i.e. body) that match the top level jQuery selector above 221 | firstElem, 222 | 223 | // Instantiated variable that will store the top level newly created unordered list DOM element 224 | ul, 225 | ignoreSelector = self.options.ignoreSelector; 226 | 227 | // If the selectors option has a comma within the string 228 | if(this.options.selectors.indexOf(",") !== -1) { 229 | 230 | // Grabs the first selector from the string 231 | firstElem = $(this.options.context).find(this.options.selectors.replace(/ /g,"").substr(0, this.options.selectors.indexOf(","))); 232 | 233 | } 234 | 235 | // If the selectors option does not have a comman within the string 236 | else { 237 | 238 | // Grabs the first selector from the string and makes sure there are no spaces 239 | firstElem = $(this.options.context).find(this.options.selectors.replace(/ /g,"")); 240 | 241 | } 242 | 243 | if(!firstElem.length) { 244 | 245 | self.element.addClass(hideTocClassName); 246 | 247 | return; 248 | 249 | } 250 | 251 | self.element.addClass(tocClassName); 252 | 253 | // Loops through each top level selector 254 | firstElem.each(function(index) { 255 | 256 | //If the element matches the ignoreSelector then we skip it 257 | if($(this).is(ignoreSelector)) { 258 | return; 259 | } 260 | 261 | // Creates an unordered list HTML element and adds a dynamic ID and standard class name 262 | ul = $("