Repository: topheman/vanilla-es6-jspm Branch: master Commit: 5813b1e211e7 Files: 86 Total size: 247.0 KB Directory structure: gitextract_r5mb_8xo/ ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .htmlhintrc ├── .jshintrc ├── .travis.yml ├── LICENSE ├── README.md ├── bin/ │ └── test-build.sh ├── extras/ │ └── yuidoc-theme-topheman/ │ ├── README.md │ ├── assets/ │ │ ├── css/ │ │ │ ├── main.css │ │ │ └── main.deprecated.less │ │ ├── index.html │ │ ├── js/ │ │ │ ├── api-filter.js │ │ │ ├── api-list.js │ │ │ ├── api-search.js │ │ │ ├── apidocs.js │ │ │ └── yui-prettify.js │ │ └── vendor/ │ │ └── prettify/ │ │ ├── CHANGES.html │ │ ├── COPYING │ │ ├── README.html │ │ ├── prettify-min.css │ │ └── prettify-min.js │ ├── layouts/ │ │ ├── main.handlebars │ │ └── xhr.handlebars │ ├── partials/ │ │ ├── attrs.handlebars │ │ ├── classes.handlebars │ │ ├── events.handlebars │ │ ├── exampleurl.handlebars │ │ ├── files.handlebars │ │ ├── index.handlebars │ │ ├── method.handlebars │ │ ├── module.handlebars │ │ ├── options.handlebars │ │ ├── props.handlebars │ │ └── sidebar.handlebars │ └── theme.json ├── gulp/ │ ├── const.js │ ├── paths.js │ ├── tasks/ │ │ ├── build.js │ │ ├── docs.js │ │ ├── html.js │ │ ├── images.js │ │ ├── scripts.js │ │ ├── server.js │ │ ├── styles.js │ │ └── watch.js │ └── utils.js ├── gulpfile.js ├── jspm.config.js ├── karma.conf.js ├── package.json ├── protractor.config.js ├── src/ │ ├── 404.html │ ├── analytics.snippet.html │ ├── app/ │ │ ├── bootstrap.js │ │ ├── components/ │ │ │ ├── Component/ │ │ │ │ └── Component.js │ │ │ ├── Geolocation/ │ │ │ │ ├── Geolocation.html │ │ │ │ └── Geolocation.js │ │ │ └── Spinner/ │ │ │ ├── Spinner.css │ │ │ ├── Spinner.html │ │ │ └── Spinner.js │ │ ├── main.js │ │ └── services/ │ │ └── geolocation/ │ │ └── geolocation.js │ ├── index.html │ └── styles/ │ ├── _footer.scss │ ├── _header.scss │ ├── _index.scss │ ├── _networks-headers.scss │ ├── _variables.scss │ └── main.scss └── test/ ├── e2e/ │ ├── spec/ │ │ ├── docs.specs.conditional.js │ │ └── home.spec.js │ └── utils.js ├── fixtures/ │ ├── bs.snippet.html │ └── components/ │ └── simple-wrapper.html ├── forever.gulp.serve.dist.json ├── forever.gulp.serve.test.json ├── jspm.override.json ├── stubs/ │ └── app/ │ └── services/ │ └── geolocation/ │ ├── geolocation.js │ └── geolocation.json └── unit/ ├── spec/ │ ├── components/ │ │ ├── Component.spec.js │ │ ├── Geolocation.spec.js │ │ └── Spinner.spec.js │ └── services/ │ └── geolocation.spec.js └── utils.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ # http://editorconfig.org root = true [*] # change these settings to your own preference indent_style = space indent_size = 2 # it's recommend to keep these unchanged end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [*.md] trim_trailing_whitespace = false [{package,bower}.json] indent_style = space indent_size = 2 ================================================ FILE: .gitattributes ================================================ extras/* linguist-vendored ================================================ FILE: .gitignore ================================================ # General .DS_Store # dependency directories npm-debug.log node_modules jspm_packages node_modules.bak jspm_packages.bak # ide nbproject .idea # Coverage directory used by tools like istanbul coverage # Build and tmp folders for production build/ .tmp/ ================================================ FILE: .htmlhintrc ================================================ { "doctype-first": false } ================================================ FILE: .jshintrc ================================================ { "node": true, "browser": true, "esnext": true, "bitwise": true, "camelcase": false, "curly": true, "eqeqeq": true, "immed": true, "indent": 2, "latedef": "nofunc", "newcap": true, "noarg": true, "quotmark": false, "undef": true, "unused": false, "strict": true, "trailing": true, "smarttabs": true, "jquery": false, "globals": { "System": false, "isAngularSite": false, "ApplicationConfiguration": false, "angular": false, "after": false, "afterEach": false, "before": false, "beforeEach": false, "browser": false, "describe": false, "expect": false, "inject": false, "it": false, "by": false, "element": false, "goToUrl": false, "jasmine": false, "spyOn": false, "protractor": false } } ================================================ FILE: .travis.yml ================================================ language: node_js node_js: - '6' addons: sauce_connect: true env: global: #You don't need the WITH_DOCS variable (this is only for me to launch the e2e tests of the generated doc internally) - WITH_DOCS=true - secure: lVqaKzskSfk4RQRYWhb/9eF9iY/18+ZDD3+85tCZVQP/SNRybvAUm9TgCJP8T1JYU4xjmKeXsglg6XHabjbTOqHDo76vKk47rtFD8MOz5/GjGaC0fPNbHgjrXcinMquv1P1tJRle31kLf+BBtrj1LAl/PgoGTTm63OhXDiO6ijVoIVgSLHXWHJVSDu2FsEgAn+rO0nQkMUHgAHs1V1ocy+kZjRf+rIMSn7K6Va/sY0dN7r/efB3yQCBDxCKarORCU+ixDtwEApplWr+8p/IXsb4P3NQ80dmIBzYOd++cAVe1GfmMYcqBgZMg7+EjY14RoL+XwPimu7fQ2GhhQbzFrvJYb73a/CSfaMbtvO2oCCLAbfiPuijt7DhuuWJbhtKHTaJ+HHiEExVk6DA9VrQz1dIBgFD8FtblRskxkTRFsIyQGxdqnpoU/gCNL2MoluBtYTMai6TrcDNxZ+U1zlCTGyWbHr8hy/WUW7nW48KS2LlHbNjBlCw6G+WKy2IotyMOahqS+Fnksk0/QeHNAjUYy8lIpG/hZvdalJW8GsMszyeOrw3Pt6pXkjf7U74oLTmimhkHB8WjjV/FtXS70VG0aI3ALRJLSVJlGj1t0NCYI5Lf6CpkpwK0f7/OTs6R5WVpxuo9f4rhJngNPkyEj8HWp2wquihuS1VAvxtvHOPZOd4= - secure: fVv0ZWvXcF83t7nLsBYKaXqwMQ3UXlXh/kQ+IHSVifsGlHFZ5bVVghKirpGli1XlvpymGJAhCup3ZdpSeeMMXw4DvjIyAo5LCdElqpYR69w1bW4Bplx1/usYwaRq266i1srlYaXq3mDMg1CBfZ55co7b7PACvDS2IHaq8SY7rAcO3G4C6wHLgbcfB2+TVsIplAz6ntj/2PoqQv60Slsyg0K+8CMaBs/d7f4ckaCUww2TNGyArm1Qiam5+3fvmk+BrJHwX8B3jZwXguh+MaWGi/7Kb2nocT62HijDI0BcZCTjwLcEomZI68ha4T9qjiFOYkrks+fPQZHa8aLfr+LbOW7eSaBf9+ljEoKTx/Gq/NTOoXhvcT2JgJ+nF22RStxN2mehZi/FKHw3IkrNPqpyRsIkNC2seAuAkUHzwJfEuhPq/nraDePi1o3E58c8YYC7SVi+uZGrLG0md1SlQl0iITK16yZYHS/yJAIwGMzrcatQH/2r/WmYCiVox/OZCOhL/vX1CKAXn+b1KlEoesMHuwewq0cPFs94brUQIdDCltRzqCjxzSjKM6z3zKg5cu+8AAglm62RQkD2HdTJIzT/Kf6HLVn0zgGRCoF7f7uAkLO0j4efYgbMnyIUYSWfn8Gr6Xo53tgNzjVdpFmXQ0p6Vpmj/KqHJ1bxC13Wd8l6vS0= - secure: rLqLeX4/4gYjXPFmLiAdcy8l2v9WbBvq5EajLtFNkUaAxrqlgZQtwNXdGNrzW7ZI7R86eoknVX9WMRNGQhXOafTNXJ70i3SMtcaQCVvsmwOS+Tz67MTnsLs4tHEivTe5TflU1VpeeF3cZE7/c3H7XxbHDjo7gZR/3C/THBobHjEOk/wuClA97YN9cGwgnc9krki96n/o7MCeDfptsfUNacdGgl77ZLl+2xWzspr2CwYpltPVCT9nmKesLc7cLd5nVw4FVCcTeRV0cXaoQ4ZDfqz3fZIFc3FcNwXbdVqO9E4u8pW68MD/uUGmJXNGDGmLmx8Pwd/fx6cjlIUHOqZYWd8mMBoOXzScQrMosajPKrVVyCo0pn9sohoqIK11+5rDnKjcJ1ZvlEd8hv4Cg5RfQ89Y5fWMyTYk046uHB+jrJ4Clf3n/inZL+h8eh55IyxBOFDmNOBn3qBMIW2WX+siJ2uScCPf2BQQrpVt3GtnKA/dAz4cSfYWPcwVw3vnPC99Rxj4sI9tC0r0kSEXGWpJruUUk3lZvHaFDYoqbZywoDNlAgCMB0149MGa/M9l/5YICIJB3q6UQwHDBNoXJFp7AG0T9f2XOQQ8nEbJvs39F4uSWaFLwdd2W4alJjXpe8ABUO/HofedvPlrrJHOgQNx/zYZj9ZK5y0skJsikaRBBQM= before_install: - npm install jspm - ./node_modules/.bin/jspm config registries.github.auth $JSPM_GITHUB_AUTH_TOKEN before_script: - gulp build - gulp clean - gulp build --env test - '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && npm run forever-start-dist || true' script: - npm test - '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && npm run test-e2e || true' ================================================ FILE: LICENSE ================================================ The MIT License (MIT) Copyright (C) 2015 Christophe Rosset Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ vanilla-es6-jspm ================ [![Build Status](https://travis-ci.org/topheman/vanilla-es6-jspm.svg?branch=master)](https://travis-ci.org/topheman/vanilla-es6-jspm) [![Sauce Test Status](https://saucelabs.com/buildstatus/vanilla-es6-jspm)](https://saucelabs.com/u/vanilla-es6-jspm) [![devDependency Status](https://david-dm.org/topheman/vanilla-es6-jspm/dev-status.svg)](https://david-dm.org/topheman/vanilla-es6-jspm#info=devDependencies) **ES6** is here and you can't avoid it. We have great tools to make it work, one of them is **jspm**. jspm is great but all-in-one yeoman generators or seed projects (with build/sass/livereload/sourcemaps/unit-tests ...) are still lacking, so I decided to make my own angular/ES6/jspm stack. This project is the first step: a **vanillaJS/ES6/jspm boilerplate** ([more infos on the Wiki](https://github.com/topheman/vanilla-es6-jspm/wiki)). * [Requirements](#requirements) / [Installation](#installation) / [Launch](#launch) * [Build](#build) / [Test](#test) * [Git workflow & Continuous Integration](#git-workflow--continuous-integration) * [Generate Docs](#generate-docs) * [Deployment](#deployment) / [Folder organization](#folder-organization) ## Features * Simple ES6 app using basic **ES6 features** * so that you won't have to struggle to understand the code base * but advanced enough to be used as an example * Use **ES6 Modules** via [SystemJS module loader](https://github.com/systemjs/systemjs) (built on top of [ES6 Module Loader Polyfill](https://github.com/ModuleLoader/es6-module-loader)) * Manage development and production workflow with [jspm](http://jspm.io/), [SystemJS Builder](https://github.com/systemjs/builder) and [Gulp](http://gulpjs.com/). * Backend mocking / stubs / overriding of the module loader * **Karma unit tests** (using mocks and stubs) * **e2e testing** with protractor * Produce optimized, production ready code for deployment * **Continuous Integration** ready (tests via [Travis CI](https://travis-ci.org/topheman/vanilla-es6-jspm) with [SauceLabs](https://saucelabs.com/u/vanilla-es6-jspm) integration for e2e tests) * Automated documentation generation ## TL;DR Want to get started right now and bother about all the great features later ? ```shell $ npm install -g jspm $ git clone https://github.com/topheman/vanilla-es6-jspm.git $ cd vanilla-es6-jspm $ npm install $ gulp serve ``` You're ready to develop in ES6 the project in the `src` folder! ## Requirements * node/npm (tested on both node v4, v5 & v6 - [see tests](https://travis-ci.org/topheman/vanilla-es6-jspm)) * gulp `npm install -g gulp-cli` * jspm `npm install -g jspm` [Why all dependencies in local (see wiki) ?](https://github.com/topheman/vanilla-es6-jspm/wiki/FAQ#dependencies) ## Installation All you need is to run `npm install` * `npm install`: install all npm dependencies + will **automatically** triggers the following at postinstall (so **you don't need to run those**): * `jspm install`: installs front dependencies via jspm * `npm run webdriver-manager-update` installs necessary binaries for Selenium (for e2e testing) ## Launch You can launch your app in different modes (dev/dist/test): * `gulp serve` : **will launch a dev server** * `gulp serve --env dist` : will launch the version of the site built in `build/dist` folder (need to `gulp build` before) - *usefull to check your site before deploying it*. * `gulp serve --env test` : will launch a dev server with test configuration - *usefull to debug / create unit tests*: * jspm configuration overridden by the `test/jspm.override.json` file * the app will appear with "TEST" in background, thanks to `test/fixtures/bs.snippet.html` injected on the the fly (containing specific css) You can pass the following flags to the `gulp serve` command: * `--env`: accepts `dev`, `dist`, `test` (`dev` by default) * `--port`: overrides the port of the server you'll launch * `--disable-watch`: disables watching/reloading * `--open false`: won't open the site in the browser ## Build * `gulp build` : builds a production ready version of the site in `build/dist` folder * `gulp build --env test` : same as `gulp build`, but bundles a test version of your website (using `test/jspm.override.json`) * can be usefull if you want to do end-to-end testing on a built version of your website You can also pass the following flags to `gulp build`: * `--with-docs`: will generate the documentation from source code in `build/dist/docs` ([see generate docs section](#generate-docs)) ## Test ### Unit The unit tests are in `test/unit/spec`. You can see exactly which commands match the following npm tasks in the [package.json](https://github.com/topheman/vanilla-es6-jspm/blob/master/package.json#L6). * `npm test`: runs all the tests (will be triggered on `git-pre-commit`) * `npm run test-unit`: runs the unit tests through `karma` * `npm run test-build`: tests the `gulp build` task (will be triggered on `git-pre-push`) * if `build/dist` folder is under git management ([see deployment section](#deployment)), this task will git stash/unstash before and after testing. ### e2e The e2e tests are in `test/e2e/spec`. It's using [protractor](http://www.protractortest.org/) - an end-to-end test framework for AngularJS applications, based on [Selenium Webdriver](http://www.seleniumhq.org/). It can also be used on non-angular websites ([more on wiki](https://github.com/topheman/vanilla-es6-jspm/wiki/FAQ#protractor)). You can run the e2e tests two ways (either way, they need a server in order to run): * standalone (no need to have a server launched / **make sure you don't**) - launch : `npm run test-e2e-standalone`: this will: * start a test server * run the e2e tests * stop the test server * if you want to run them against your current server (this should be a server launched in test mode with `gulp serve --env test`), open a new terminal tab and run `npm run test-e2e` ## Git workflow & Continuous Integration ### Git hooks To prevent you from sending broken code, some client-side git hooks are enabled: * pre-commit: will run `npm test` (checks jshint, htmlhint and karma unit tests) * pre-push: will run `npm run test-build` (checks if the build runs smoothly) * I decided to put this check on pre-push because: it takes time and git stash/unstash `build/dist` folder repo - it could be put on pre-commit ... You can bypass those checks by adding to your git command the flag `--no-verify` (but know that the Travis CI build will fail). ### Travis CI On each push, [Travis CI](https://travis-ci.org/topheman/vanilla-es6-jspm) will run the following tests/builds (see complete steps in [.travis.yml](https://github.com/topheman/vanilla-es6-jspm/blob/master/.travis.yml)): * `gulp build`: runs the build routine (to make sure it works fine) * `gulp build --env test`: builds a test version of the app (to be served for e2e tests) * `npm test`: runs unit tests * `npm run test-e2e`: runs end to end tests via [SauceLabs](https://saucelabs.com/u/vanilla-es6-jspm) If either one of them fails, the build will be flagged as failed. * [Travis CI setup](https://github.com/topheman/vanilla-es6-jspm/wiki/FAQ#travis-ci-setup) * The `WITH_DOCS=true` env var is exported at the beginning so that the doc generation should also be tested on the `gulp build` task (without changing the commands) * As you'll see e2e tests don't run on pull requests. [See explanation on the FAQ](https://github.com/topheman/vanilla-es6-jspm/wiki/FAQ#continuous-integration). ### SauceLabs *You can skip this if e2e testing isn't part of your Continuous Integration workflow.* SauceLabs is a cross-browser automation tool built on top of Selenium WebDriver (Protractor uses Selenium WebDriver). It lets you run e2e tests accross multiple devices and is well integrated to Travis CI. If you want to set it up for your own project, [read this post](http://dev.topheman.com/setup-travis-ci-saucelabs-for-protractor). To avoid traffic on the Sauce Connect tunnel that could lead to timeouts, SauceLabs tests are run against a server serving the `build/dist` folder, containing a bundled version of the site in `test` mode (to benefit from the stubs and mocks) which was created thanks to `gulp build --env test`. More infos on this commit: [#7898239](https://github.com/topheman/vanilla-es6-jspm/commit/7898239ea252b9163e3e02b77aef2d6e13c0fa5a) [See the SauceLabs Report](https://saucelabs.com/u/vanilla-es6-jspm) (much like Travis but for e2e tests) ## Generate Docs Documentation generation is currently based on [YUIDoc](http://yui.github.io/yuidoc/). A set of tasks is at your disposal: * `npm run yuidoc`: Will generate documentation in `build/docs` * `gulp build --with-docs`: Same as above, but will also copy the generated documentation to `build/dist/docs` (can be usefull if you have an opensource project and want to share docs) The configuration of YUIDoc is specified in the `package.json`, in the `yuidoc` entry - you can override this config (the theme for example). [Here is an example of the output](http://topheman.github.io/vanilla-es6-jspm/docs/). Notes: * I'm still looking for a replacement for yuidoc, feel free to use your own doc generator - if you have one more suited for ES6, please let me know. * I opened an [issue here](https://github.com/topheman/vanilla-es6-jspm/issues/1), for the moment, the doc doesn't display well when served over https. ## Deployment ### On github pages You can host your project on github pages like this ([source](https://help.github.com/articles/creating-project-pages-manually/)), pushing to the github pages the `dist` folder where the project is built. ```shell $ gulp build $ cd build/dist $ git init $ git remote add origin https://github.com/username/vanilla-es6-jspm $ git fetch origin $ git checkout --orphan gh-pages $ gulp build $ git add . $ git commit -m "first push to production" $ git push -u origin gh-pages ``` Next time, you'll only have to do the last 4 steps ... ## Folder Organization ### Development ``` src ├── 404.html ├── analytics.snippet.html --> analytics snippet (only added at build) ├── app --> folder containing app js files │   ├── bootstrap.js --> js module entry point │   ├── components │   ├── main.js │   └── services ├── favicon-128x128.png ├── favicon-32x32.png ├── favicon.ico ├── images --> images files ├── index.html --> app main file └── styles --> styles folder (.scss) ``` ### Production ``` build ├── dist --> distribution source code that goes to production │   ├── 404.html │   ├── docs --> generate doc with "gulp build --with-docs" │ ├── favicon-128x128.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── images --> images files │ ├── index.html --> app main file │ ├── scripts --> js files │ │   └── app.bootstrap.build-597baeaa0a.js --> concat, minify, reved app js files and cached templates │ └── styles --> css files │ └── main.min-b8451af87d.css --> concat & minify app css files └── docs --> generate doc with "npm run yuidoc" ``` ### Test ``` test ├── e2e │   ├── spec --> e2e tests run by protractor with jasmine │   └── utils.js ├── fixtures │   └── bs.snippet.html --> html snippet added on gulp serve:test ├── forever.gulp.serve.dist.json ├── forever.gulp.serve.test.json ├── jspm.override.json --> file to override jspm.config.js in test mode ├── stubs --> replacements for existing modules, injected in test mode (configured in jspm.override.json) │   └── app │   └── services └── unit └── spec --> unit tests run by karma with jasmine ├── components └── services ``` ## Changelog See [releases section](https://github.com/topheman/vanilla-es6-jspm/releases). ## Contributing *This section is in progress*, you can still take a look at the [public trello board](https://trello.com/c/tCihMVXM/46-introduction). ## FAQ [See Wiki](https://github.com/topheman/vanilla-es6-jspm/wiki/FAQ) ## Resources [See Wiki](https://github.com/topheman/vanilla-es6-jspm/wiki/Resources) ================================================ FILE: bin/test-build.sh ================================================ #!/usr/bin/env bash # This script will launch the gulp build task # # If your build/dist is under git management, # it will git stash your modifications before doing anything and restore them # at the end of the test (wether it passed or not) # don't put this flag, we need to go through # always stop on errors # set -e GULP_PATH="$(npm bin)/gulp" BUILD_DIST_IS_GIT=0 BUILD_DIST_IS_GIT_DIRTY=0 # vars retrieving the exit codes of the commands run GULP_BUILD_EXIT_CODE=0 GULP_CLEAN_EXIT_CODE=0 echo "###### TEST gulp build" # If build/dist is under git, stash modification - fail if can't stash if [ -d $(dirname $0)/../build/dist/.git ] then BUILD_DIST_IS_GIT=1 echo "[INFO] build/dist is under git management" cd $(dirname $0)/../build/dist echo "[INFO] $(pwd)" if [[ -n $(git status --porcelain) ]] then BUILD_DIST_IS_GIT_DIRTY=1 echo "[INFO] build/dist has un-committed changes, stashing them" cmd="git stash save -u" echo "[RUN] $cmd" eval $cmd if [ $? -gt 0 ] then echo "[WARN] Couldn't stash modifications please commit your files in build/dist before proceeding" exit 1 fi else echo "[INFO] build/dist repo is clean, nothing to stash" fi fi cmd="$GULP_PATH build" echo "[RUN] $cmd" eval $cmd GULP_BUILD_EXIT_CODE=$? echo "[DEBUG] gulp build exit code : $GULP_BUILD_EXIT_CODE"; cmd="$GULP_PATH clean" echo "[RUN] $cmd" eval $cmd GULP_CLEAN_EXIT_CODE=$? echo "[DEBUG] gulp clean exit code : $GULP_CLEAN_EXIT_CODE"; if [ $GULP_CLEAN_EXIT_CODE -gt 0 ] && [ $BUILD_DIST_IS_GIT_DIRTY -gt 0 ] then echo "[WARN] Couldn't clean the build/dist repo before git unstash" echo "[WARN] Run the following commands manually to get back your repo in build/dist" echo "[INFO] gulp clean" echo "[INFO] git reset --hard HEAD" echo "[INFO] git stash pop --index" exit 1 fi # After cleaning build/dist, if it is a git repo, point it back to the HEAD if [ $BUILD_DIST_IS_GIT -gt 0 ] then echo "[INFO] build/dist is under git management, pointing back to HEAD" cmd="git reset --hard HEAD" echo "[RUN] $cmd" eval $cmd if [ $? -gt 0 ] then echo "[WARN] Couldn't reset --hard HEAD build/dist repo" echo "[WARN] Run the following command manually to get back your repo in build/dist" echo "[INFO] git reset --hard HEAD" echo "[INFO] git stash pop --index" exit 1 fi fi # If build/dist is a git repo and was dirty, retrieve the stash if [ $BUILD_DIST_IS_GIT_DIRTY -gt 0 ] then echo "[INFO] build/dist is under git management & has stashed files, retrieving stash" cmd="git stash pop --index" echo "[RUN] $cmd" eval $cmd if [ $? -gt 0 ] then echo "[WARN] Couldn't unstash build/dist repo" echo "[WARN] Run the following command manually to get back your repo in build/dist" echo "[INFO] git stash pop --index" exit 1 fi else if [ $BUILD_DIST_IS_GIT -gt 0 ] then echo "[INFO] build/dist is under git management but directory was clean at start, nothing to unstash" fi fi #finally return an exit code according to the gulp build task if [ $GULP_BUILD_EXIT_CODE -gt 0 ] then echo "[FAILED] gulp build failed. Exiting with code $GULP_BUILD_EXIT_CODE" echo "###### END TEST gulp build" exit $GULP_BUILD_EXIT_CODE else echo "[PASSED] gulp build passed" echo "###### END TEST gulp build" exit 0 fi ================================================ FILE: extras/yuidoc-theme-topheman/README.md ================================================ yuidoc-theme-topheman ===================== My yuidoc theme, inspired by [royriojas/yuidoc-theme-blue](https://github.com/royriojas/yuidoc-theme-blue) Usage ===== ###Install yuidoc Globally ````` npm install -g yuidocjs ````` Or locally ````` npm install yuidocjs --save-dev ````` ###Configure ####With yuidoc.json `yuidoc.json` example: ``` { "name": "twitter-stream-channels", "description": "Manage multiple channel search on the same Twitter Stream", "url": "http://labs.topheman.com/", "options": { "linkNatives": "true", "attributesEmit": "false", "selleck": "false", "paths": [ "./lib", "./mocks" ], "outdir": "./yuidoc", "themedir" : "./extras/yuidoc-theme-topheman" } } ``` ####Inside package.json You can put yuidoc's configuration metadata directly inside your `package.json`, so that yuidoc will have directly access to your version, description and name. Just add a `yuidoc` entry in your `package.json`, like that: ``` "yuidoc":{ "options": { "linkNatives": "true", "attributesEmit": "false", "selleck": "false", "paths": [ "./lib", "./mocks" ], "outdir": "./yuidoc", "themedir" : "./extras/yuidoc-theme-topheman" } } ``` ###Command ####Using yuidoc.json From global yuidoc ``` yuidoc -c yuidoc.json --project-version 0.2.4 ``` From local yuidoc ``` node_modules/.bin/yuidoc -c yuidoc.json --project-version 0.2.4 ``` ####Using package.json From global yuidoc ``` yuidoc ``` From local yuidoc ``` node_modules/.bin/yuidoc ``` ================================================ FILE: extras/yuidoc-theme-topheman/assets/css/main.css ================================================ util.print: Use console.log instead /* Font sizes for all selectors other than the body are given in percentages, with 100% equal to 13px. To calculate a font size percentage, multiply the desired size in pixels by 7.6923076923. Here's a quick lookup table: 10px - 76.923% 11px - 84.615% 12px - 92.308% 13px - 100% 14px - 107.692% 15px - 115.385% 16px - 123.077% 17px - 130.769% 18px - 138.462% 19px - 146.154% 20px - 153.846% */ html { background: #fff; color: #333; overflow-y: scroll; } body { font: 14px/1.4 'Source Sans Pro', 'Helvetica Neue', 'Helvetica', Arial, sans-serif; margin: 0; padding: 0; color: #666; } /* -- Links ----------------------------------------------------------------- */ a { color: #900000; text-decoration: none; } .hidden { display: none; } a:hover { text-decoration: underline; } /* "Jump to Table of Contents" link is shown to assistive tools, but hidden from sight until it's focused. */ .jump { position: absolute; padding: 3px 6px; left: -99999px; top: 0; } .jump:focus { left: 40%; } /* -- Paragraphs ------------------------------------------------------------ */ p { margin: 0.8em 0; font-size: 15px; } dd p, td p { margin-bottom: 0; } dd p:first-child, td p:first-child { margin-top: 0; } /* -- Headings -------------------------------------------------------------- */ h1, h2, h3, h4, h5, h6 { line-height: 1.1; margin: 1.1em 0 0.5em; border: none; color: #900000; font-weight: 300; text-decoration: none; } h1 { font-size: 36px; margin: 0.75em 0 0.5em; } h2 { font-size: 32px; margin: 16px 0 10px 0; } h3 { font-size: 138.462%; } h4 { border-bottom: 1px solid #DBDFEA; font-size: 115.385%; font-weight: normal; padding-bottom: 2px; } h5, h6 { font-size: 107.692%; } /* -- Code and examples ----------------------------------------------------- */ code, kbd, pre, samp { font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; font-size: 92.308%; line-height: 1.35; } p code, p kbd, p samp, li code { margin: 0 2px; padding: 3px 8px; border: 1px solid rgba(0, 0, 0, 0); background-color: #f8f8f8; border-radius: 3px; } pre.code, pre.terminal, pre.cmd { overflow-x: auto; *overflow-x: scroll; padding: 1em 0.6em; } pre.code { background: #FCFBFA; border: 1px solid #EFEEED; border-left-width: 5px; } pre.terminal, pre.cmd { background: #F0EFFC; border: 1px solid #D0CBFB; border-left: 5px solid #D0CBFB; } /* Don't reduce the font size of // elements inside
   blocks. */
pre code,
pre kbd,
pre samp {
  font-size: 100%;
  line-height: 1.7em;
}
/* Used to denote text that shouldn't be selectable, such as line numbers or
   shell prompts. Guess which browser this doesn't work in. */
.noselect {
  -moz-user-select: -moz-none;
  -khtml-user-select: none;
  -webkit-user-select: none;
  -o-user-select: none;
  user-select: none;
}
/* -- Lists ----------------------------------------------------------------- */
dd {
  margin: 0.2em 0 0.7em 1em;
}
dl {
  margin: 1em 0;
}
dt {
  font-weight: bold;
}
/* -- Tables ---------------------------------------------------------------- */
caption,
th {
  text-align: left;
}
table {
  border-collapse: collapse;
  width: 100%;
}
td,
th {
  border: 1px solid #fff;
  padding: 5px 12px;
  vertical-align: top;
}
td {
  background: #E6E9F5;
}
td dl {
  margin: 0;
}
td dl dl {
  margin: 1em 0;
}
td pre:first-child {
  margin-top: 0;
}
th {
  background: #D2D7E6;
  /*#97A0BF*/
  border-bottom: none;
  border-top: none;
  color: #000;
  /*#FFF1D5*/
  font-family: 'Trebuchet MS', sans-serif;
  font-weight: bold;
  line-height: 1.3;
  white-space: nowrap;
}
/* -- Layout and Content ---------------------------------------------------- */
#doc {
  margin: auto;
  min-width: 1024px;
}
.content {
  padding: 0 20px 0 25px;
}
.sidebar {
  padding: 0 15px 0 20px;
}
#bd {
  padding: 7px 0 60px;
  position: relative;
  width: 99%;
  padding-top: 0px;
}
/* -- Table of Contents ----------------------------------------------------- */
/* The #toc id refers to the single global table of contents, while the .toc
   class refers to generic TOC lists that could be used throughout the page. */
.toc code,
.toc kbd,
.toc samp {
  font-size: 100%;
}
.toc li {
  font-weight: bold;
}
.toc li li {
  font-weight: normal;
}
/* -- Intro and Example Boxes ----------------------------------------------- */
/*
.intro, .example { margin-bottom: 2em; }
.example {
    -moz-border-radius: 4px;
    -webkit-border-radius: 4px;
    border-radius: 4px;
    -moz-box-shadow: 0 0 5px #bfbfbf;
    -webkit-box-shadow: 0 0 5px #bfbfbf;
    box-shadow: 0 0 5px #bfbfbf;
    padding: 1em;
}
.intro {
    background: none repeat scroll 0 0 #F0F1F8; border: 1px solid #D4D8EB; padding: 0 1em;
}
*/
/* -- Other Styles ---------------------------------------------------------- */
/* These are probably YUI-specific, and should be moved out of Selleck's default
   theme. */
.button {
  border: 1px solid #dadada;
  -moz-border-radius: 3px;
  -webkit-border-radius: 3px;
  border-radius: 3px;
  color: #444;
  display: inline-block;
  font-family: Helvetica, Arial, sans-serif;
  font-size: 92.308%;
  font-weight: bold;
  padding: 4px 13px 3px;
  -moz-text-shadow: 1px 1px 0 #fff;
  -webkit-text-shadow: 1px 1px 0 #fff;
  text-shadow: 1px 1px 0 #fff;
  white-space: nowrap;
  background: #EFEFEF;
  /* old browsers */
  background: -moz-linear-gradient(top, #f5f5f5 0%, #efefef 50%, #e5e5e5 51%, #dfdfdf 100%);
  /* firefox */
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f5f5f5), color-stop(50%, #efefef), color-stop(51%, #e5e5e5), color-stop(100%, #dfdfdf));
  /* webkit */
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f5f5f5', endColorstr='#dfdfdf', GradientType=0);
  /* ie */
}
.button:hover {
  border-color: #466899;
  color: #fff;
  text-decoration: none;
  -moz-text-shadow: 1px 1px 0 #222;
  -webkit-text-shadow: 1px 1px 0 #222;
  text-shadow: 1px 1px 0 #222;
  background: #6396D8;
  /* old browsers */
  background: -moz-linear-gradient(top, #6396d8 0%, #5a83bc 50%, #547ab7 51%, #466899 100%);
  /* firefox */
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #6396d8), color-stop(50%, #5a83bc), color-stop(51%, #547ab7), color-stop(100%, #466899));
  /* webkit */
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#6396D8', endColorstr='#466899', GradientType=0);
  /* ie */
}
.newwindow {
  text-align: center;
}
.header .version em {
  display: block;
  text-align: right;
}
#classdocs .item {
  border-bottom: 1px dashed rgba(70, 104, 153, 0.29);
  margin: 1em 0;
  padding: 0 1.5em 1.8em 1.5em;
}
#classdocs .item:last-of-type {
  border-bottom: none;
}
#classdocs .item .params p,
#classdocs .item .returns p {
  display: inline;
}
#classdocs .item em code,
#classdocs .item em.comment {
  color: green;
}
#classdocs .item em.comment a {
  color: green;
  text-decoration: underline;
}
#classdocs .foundat {
  font-size: 11px;
  font-style: normal;
}
.attrs .emits {
  margin-left: 2em;
  padding: .5em;
  border-left: 1px dashed #ccc;
}
abbr {
  border-bottom: 1px dashed #ccc;
  font-size: 80%;
  cursor: help;
}
.prettyprint li.L0,
.prettyprint li.L1,
.prettyprint li.L2,
.prettyprint li.L3,
.prettyprint li.L5,
.prettyprint li.L6,
.prettyprint li.L7,
.prettyprint li.L8 {
  list-style: decimal;
}
ul li p {
  margin-top: 0;
}
.method .name,
.property .name,
.events .name {
  font-size: 110%;
  margin: 0;
}
.apidocs .methods .extends .method,
.apidocs .properties .extends .property,
.apidocs .attrs .extends .attr,
.apidocs .events .extends .event {
  font-weight: bold;
}
.apidocs .methods .extends .inherited,
.apidocs .properties .extends .inherited,
.apidocs .attrs .extends .inherited,
.apidocs .events .extends .inherited {
  font-weight: normal;
}
#hd {
  background: rgba(0, 0, 0, 0.5) url(../img/bgscreen.png);
  border-bottom: 1px solid #DFDFDF;
  padding: 0 15px 1px 20px;
  margin-bottom: 15px;
  box-shadow: 0 1px 20px #333;
  /*position: fixed;*/
  width: 100%;
  box-sizing: border-box;
  z-index: 10;
  cursor: pointer;
}
/* -- API Docs CSS ---------------------------------------------------------- */
/*
This file is organized so that more generic styles are nearer the top, and more
specific styles are nearer the bottom of the file. This allows us to take full
advantage of the cascade to avoid redundant style rules. Please respect this
convention when making changes.
*/
/* -- Generic TabView styles ------------------------------------------------ */
/*
These styles apply to all API doc tabviews. To change styles only for a
specific tabview, see the other sections below.
*/
.yui3-js-enabled .apidocs .tabview {
  visibility: hidden;
  /* Hide until the TabView finishes rendering. */
  _visibility: visible;
}
.apidocs .tabview.yui3-tabview-content {
  visibility: visible;
}
.apidocs .tabview .yui3-tabview-panel {
  background: #fff;
}
/* -- Generic Content Styles ------------------------------------------------ */
/* Headings */
.link-docs {
  float: right;
  font-size: 15px;
  margin: 4px 4px 6px;
  padding: 6px 30px 5px;
}
.apidocs {
  zoom: 1;
}
/* Generic box styles. */
.apidocs .box {
  border: 1px solid;
  margin: 0 0 2em 0;
  padding: 0 1em;
}
/* A flag is a compact, capsule-like indicator of some kind. It's used to
   indicate private and protected items, item return types, etc. in an
   attractive and unobtrusive way. */
.apidocs .flag {
  background: #bababa;
  border-radius: 3px;
  color: #fff;
  font-size: 11px;
  margin: 0 0.5em;
  padding: 2px 4px 1px;
}
/* Class/module metadata such as "Uses", "Extends", "Defined in", etc. */
.apidocs .meta {
  background: #f9f9f9;
  border-color: #efefef;
  color: #555;
  padding: 6px 12px;
}
.apidocs .meta p {
  margin: 0;
  font-size: 14px;
}
/* Deprecation warning. */
.apidocs .box.deprecated,
.apidocs .flag.deprecated {
  background: #fdac9f;
  border: 1px solid #fd7775;
}
.apidocs .box.deprecated p {
  margin: 0.5em 0;
}
.apidocs .flag.deprecated {
  color: #333;
}
/* Module/Class intro description. */
.apidocs .intro {
  background: #f9f9f9;
  border-color: rgba(0, 0, 0, 0);
  border-left: 5px solid #900000;
  padding: 1px 15px;
  margin-bottom: 20px;
}
/* Loading spinners. */
#bd.loading .apidocs,
#api-list.loading .yui3-tabview-panel {
  background: #ffffff url(../img/spinner.gif) no-repeat center 70px;
  min-height: 150px;
}
#bd.loading .apidocs .content,
#api-list.loading .yui3-tabview-panel .apis {
  display: none;
}
.apidocs .no-visible-items {
  color: #666;
}
/* Generic inline list. */
.apidocs ul.inline {
  display: inline;
  list-style: none;
  margin: 0;
  padding: 0;
}
.apidocs ul.inline li {
  display: inline;
}
/* Comma-separated list. */
.apidocs ul.commas li:after {
  content: ',';
}
.apidocs ul.commas li:last-child:after {
  content: '';
}
/* Keyboard shortcuts. */
kbd .cmd {
  font-family: Monaco, Helvetica;
}
/* -- Generic Access Level styles ------------------------------------------- */
.apidocs .item.protected,
.apidocs .item.private,
.apidocs .index-item.protected,
.apidocs .index-item.deprecated,
.apidocs .index-item.private {
  display: none;
}
.show-deprecated .item.deprecated,
.show-deprecated .index-item.deprecated,
.show-protected .item.protected,
.show-protected .index-item.protected,
.show-private .item.private,
.show-private .index-item.private {
  display: block;
}
.hide-inherited .item.inherited,
.hide-inherited .index-item.inherited {
  display: none;
}
/* -- Generic Item Index styles --------------------------------------------- */
.apidocs .index {
  margin: 1.5em 0 3em;
}
.apidocs .index h3 {
  border-bottom: 1px solid #efefef;
  color: #333;
  margin: 1em 0 0.6em;
  padding-bottom: 2px;
  font-size: 28px;
}
.apidocs .index .no-visible-items {
  margin-top: 2em;
}
.apidocs .index-list {
  border-color: #efefef;
  list-style: none;
  margin: 0;
  padding: 0;
  -moz-column-count: 4;
  -moz-column-gap: 10px;
  -moz-column-width: 170px;
  -ms-column-count: 4;
  -ms-column-gap: 10px;
  -ms-column-width: 170px;
  -o-column-count: 4;
  -o-column-gap: 10px;
  -o-column-width: 170px;
  -webkit-column-count: 4;
  -webkit-column-gap: 10px;
  -webkit-column-width: 170px;
  column-count: 4;
  column-gap: 10px;
  column-width: 170px;
}
.apidocs .no-columns .index-list {
  -moz-column-count: 1;
  -ms-column-count: 1;
  -o-column-count: 1;
  -webkit-column-count: 1;
  column-count: 1;
}
.apidocs .index-item {
  white-space: nowrap;
  font-size: 18px;
}
.apidocs .index-item .flag {
  background: none;
  border: none;
  color: #afafaf;
  display: inline;
  margin: 0 0 0 0.2em;
  padding: 0;
}
/* -- Generic API item styles ----------------------------------------------- */
.apidocs .args {
  display: inline;
  margin: 0 0.5em;
}
.apidocs .flag.chainable {
  background: #46ca3b;
}
.apidocs .flag.protected {
  background: #9b86fc;
}
.apidocs .flag.private {
  background: #fd6b1b;
}
.apidocs .flag.async {
  background: #356de4;
}
.apidocs .flag.required {
  background: #e60923;
}
.apidocs .item {
  border-bottom: 1px solid #efefef;
  margin: 1.5em 0 2em;
  padding-bottom: 2em;
}
.apidocs .item h4,
.apidocs .item h5,
.apidocs .item h6 {
  color: #333;
  font-family: inherit;
  font-size: 100%;
}
.apidocs .item .description p,
.apidocs .item pre.code {
  margin: 1em 0 0;
}
.apidocs .item .meta {
  margin-top: 8px;
}
.apidocs .item .name {
  display: inline-block;
}
.apidocs .item .type,
.apidocs .item .type a,
.apidocs .returns-inline {
  color: #555;
}
.apidocs .item .type,
.apidocs .returns-inline {
  margin: 0 0 0 0;
}
.apidocs .item .type a {
  border-bottom: 1px dotted #afafaf;
}
.apidocs .item .type a:hover {
  border: none;
}
/* -- Item Parameter List --------------------------------------------------- */
.apidocs .params-list {
  list-style: square;
  margin: 1em 0 0 2em;
  padding: 0;
}
.apidocs .param {
  margin-bottom: 1em;
}
.apidocs .param .type,
.apidocs .param .type a {
  color: #666;
}
.apidocs .param .type {
  margin: 0 0 0 0.5em;
  *margin-left: 0.5em;
}
.apidocs .param-name {
  font-weight: bold;
}
/* -- Item "Emits" block ---------------------------------------------------- */
.apidocs .item .emits {
  background: #f9f9f9;
  border-color: #eaeaea;
}
/* -- Item "Returns" block -------------------------------------------------- */
.apidocs .item .returns .type,
.apidocs .item .returns .type a {
  font-size: 100%;
  margin: 0;
}
/* -- Class Constructor block ----------------------------------------------- */
.apidocs .constructor .item {
  border: none;
  padding-bottom: 0;
}
/* -- File Source View ------------------------------------------------------ */
.apidocs .file pre.code,
#doc .apidocs .file pre.prettyprint {
  background: inherit;
  border: none;
  overflow: visible;
  padding: 0;
}
.apidocs .L0,
.apidocs .L1,
.apidocs .L2,
.apidocs .L3,
.apidocs .L4,
.apidocs .L5,
.apidocs .L6,
.apidocs .L7,
.apidocs .L8,
.apidocs .L9 {
  background: inherit;
}
/* -- Submodule List -------------------------------------------------------- */
.apidocs .module-submodule-description {
  font-size: 12px;
  margin: 0.3em 0 1em;
}
.apidocs .module-submodule-description p:first-child {
  margin-top: 0;
}
/* -- Sidebar TabView ------------------------------------------------------- */
#api-tabview {
  margin-top: 0.6em;
}
#api-tabview-filter,
#api-tabview-panel {
  border: 1px solid #dfdfdf;
}
#api-tabview-filter {
  border-bottom: none;
  border-top: none;
  padding: 0.6em 10px 0 10px;
}
#api-tabview-panel {
  border-top: none;
}
#api-filter {
  width: 100%;
  -webkit-appearance: none;
  -moz-appearance: none;
  -ms-appearance: none;
  line-height: 40px;
  font-size: 18px;
  font-weight: 300;
  font-family: 'Source Sans Pro', 'Helvetica Neue', 'Helvetica', Arial, sans-serif;
  border: none;
  border-bottom: 1px solid #DFDFDF;
  padding-left: 2px;
  color: #444;
}
#api-filter:focus {
  outline: 0;
  border-bottom: 1px solid #ccc;
}
/* -- Content TabView ------------------------------------------------------- */
#classdocs .yui3-tabview-panel {
  border: none;
}
/* -- Source File Contents -------------------------------------------------- */
.prettyprint li.L0,
.prettyprint li.L1,
.prettyprint li.L2,
.prettyprint li.L3,
.prettyprint li.L5,
.prettyprint li.L6,
.prettyprint li.L7,
.prettyprint li.L8 {
  list-style: decimal;
}
/* -- API options ----------------------------------------------------------- */
#api-options {
  /*margin-top: 2.2em;*/
  position: absolute;
  right: 1.5em;
}
/*#api-options label { margin-right: 0.6em; }*/
/* -- API list -------------------------------------------------------------- */
#api-list {
  margin-top: 1.5em;
  *zoom: 1;
}
.apis {
  line-height: 1.4;
  list-style: none;
  margin: 0;
  padding: 0.5em 0 0.5em 0.4em;
}
.apis a {
  border: 1px solid transparent;
  display: block;
  margin: 0 0 0 -4px;
  padding: 2px 10px;
  text-decoration: none;
  line-height: 22px;
}
.apis a:hover,
.apis a:focus {
  background: #900000;
  border-color: #dfdfdf;
  color: #fff;
  outline: none;
}
.api-list-item a:hover,
.api-list-item a:focus {
  text-shadow: none;
}
.apis .message {
  color: #888;
}
.apis .result a {
  padding: 3px 5px 2px;
}
.apis .result .type {
  right: 4px;
  top: 7px;
}
.api-list-item .yui3-highlight {
  font-weight: bold;
}
.blue-method-syntax {
  background: #F3F2F2;
  border-left: 5px solid #900000;
  /*border-left-width: 5px;*/
  padding: 0.5em 1em;
}
.blue-method-syntax li code {
  padding: 0;
  border: 0;
  background: none;
}
.param-description {
  padding: 1px;
}
.params ul li p {
  margin-top: 10px;
  margin-bottom: 10px;
}
.params ul li p:first-of-type {
  margin-top: 5px;
}
.param-name.optional {
  background: #eaf0e4;
  border: 1px solid #eaf0e4;
}
h3.blue-method-name {
  font-size: 28px;
  margin-bottom: 5px;
  padding: 5px 0px 7px;
  border-bottom: 1px solid #5490c7;
}
.apidocs .item .meta.method-meta {
  margin-top: 0;
  margin-bottom: 10px;
}
.blue-return-desc {
  padding-left: 20px;
}
h1.blue-main-title {
  margin: 0;
  color: #fff;
  font-size: 20px;
  line-height: 50px;
}
.project-version {
  color: #fff;
  line-height: 20px;
  padding: 5px 10px;
  position: absolute;
  text-align: right;
  right: 0;
}
.yui-overrride .yui3-skin-sam .yui3-tab-label:hover,
.yui-overrride .yui3-skin-sam .yui3-tab-label:focus {
  background: #FFF4F4;
  outline: 0;
}
.yui-overrride .yui3-skin-sam .yui3-tab-label {
  border: none;
  background: #ececec;
  font-size: 15px;
  font-weight: 300;
}
.yui-overrride .yui3-skin-sam .yui3-tab-selected .yui3-tab-label,
.yui-overrride .yui3-skin-sam .yui3-tab-selected .yui3-tab-label:focus,
.yui-overrride .yui3-skin-sam .yui3-tab-selected .yui3-tab-label:hover {
  background: #900000;
  color: #fff;
}
.yui-overrride .yui3-skin-sam .yui3-tabview-list {
  border-bottom: solid #900000;
}
footer.copyright{
  color: #62686A;
  text-align: center;
  font-size: 90%;
  margin-bottom: 20px;
}


================================================
FILE: extras/yuidoc-theme-topheman/assets/css/main.deprecated.less
================================================
/*
Font sizes for all selectors other than the body are given in percentages,
with 100% equal to 13px. To calculate a font size percentage, multiply the
desired size in pixels by 7.6923076923.

Here's a quick lookup table:

10px - 76.923%
11px - 84.615%
12px - 92.308%
13px - 100%
14px - 107.692%
15px - 115.385%
16px - 123.077%
17px - 130.769%
18px - 138.462%
19px - 146.154%
20px - 153.846%
*/

@font-family:'Source Sans Pro', 'Helvetica Neue', 'Helvetica', Arial, sans-serif;
html {
  background: #fff;
  color: #333;
  overflow-y: scroll;
}

body {
  font: 14px/1.4 @font-family;
  margin: 0;
  padding: 0;
  color:#666;
}

/* -- Links ----------------------------------------------------------------- */
a {
  color: #4085CF;
  text-decoration: none;
}

.hidden {
  display: none;
}

a:hover { text-decoration: underline; }

/* "Jump to Table of Contents" link is shown to assistive tools, but hidden from
   sight until it's focused. */
.jump {
  position: absolute;
  padding: 3px 6px;
  left: -99999px;
  top: 0;
}

.jump:focus { left: 40%; }

/* -- Paragraphs ------------------------------------------------------------ */
p {
  margin: 0.8em 0;
  font-size:15px;
}

dd p, td p { margin-bottom: 0; }
dd p:first-child, td p:first-child { margin-top: 0; }

/* -- Headings -------------------------------------------------------------- */
h1, h2, h3, h4, h5, h6 {
  line-height: 1.1;
  margin: 1.1em 0 0.5em;
  border: none;
  color: #3570BD;
  font-weight: 300;
  text-decoration: none;
}

h1 {
  font-size: 46px;
  margin: 0.75em 0 0.5em;
}

h2 {
  font-size: 32px;
  margin: 16px 0 10px 0;
}

h3 { font-size: 138.462%; }

h4 {
  border-bottom: 1px solid #DBDFEA;
  font-size: 115.385%;
  font-weight: normal;
  padding-bottom: 2px;
}

h5, h6 { font-size: 107.692%; }

/* -- Code and examples ----------------------------------------------------- */
code, kbd, pre, samp {
  font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;
  font-size: 92.308%;
  line-height: 1.35;
}

p code, p kbd, p samp, li code {

  margin: 0 2px;
  padding: 3px 8px;
  border: 1px solid rgba(0,0,0,0);
  background-color: #f8f8f8;
  border-radius: 3px;
}

a code, a kbd, a samp,
pre code, pre kbd, pre samp,
table code, table kbd, table samp,
.intro code, .intro kbd, .intro samp,
.toc code, .toc kbd, .toc samp {

}

pre.code, pre.terminal, pre.cmd {
  overflow-x: auto;
  *overflow-x: scroll;
  padding: 1em 0.6em;
}

pre.code {
  background: #FCFBFA;
  border: 1px solid #EFEEED;
  border-left-width: 5px;
}

pre.terminal, pre.cmd {
  background: #F0EFFC;
  border: 1px solid #D0CBFB;
  border-left: 5px solid #D0CBFB;
}

/* Don't reduce the font size of // elements inside 
   blocks. */
pre code, pre kbd, pre samp {
  font-size: 100%;
  line-height: 1.7em;
}

/* Used to denote text that shouldn't be selectable, such as line numbers or
   shell prompts. Guess which browser this doesn't work in. */
.noselect {
  -moz-user-select: -moz-none;
  -khtml-user-select: none;
  -webkit-user-select: none;
  -o-user-select: none;
  user-select: none;
}

/* -- Lists ----------------------------------------------------------------- */
dd { margin: 0.2em 0 0.7em 1em; }
dl { margin: 1em 0; }
dt { font-weight: bold; }

/* -- Tables ---------------------------------------------------------------- */
caption, th { text-align: left; }

table {
  border-collapse: collapse;
  width: 100%;
}

td, th {
  border: 1px solid #fff;
  padding: 5px 12px;
  vertical-align: top;
}

td { background: #E6E9F5; }
td dl { margin: 0; }
td dl dl { margin: 1em 0; }
td pre:first-child { margin-top: 0; }

th {
  background: #D2D7E6;/*#97A0BF*/
  border-bottom: none;
  border-top: none;
  color: #000;/*#FFF1D5*/
  font-family: 'Trebuchet MS', sans-serif;
  font-weight: bold;
  line-height: 1.3;
  white-space: nowrap;
}


/* -- Layout and Content ---------------------------------------------------- */
#doc {
  margin: auto;
  min-width: 1024px;
}

.content { padding: 0 20px 0 25px; }

.sidebar {
  padding: 0 15px 0 20px;
}
#bd {
  padding: 7px 0 130px;
  position: relative;
  width: 99%;
  padding-top: 50px;
}

/* -- Table of Contents ----------------------------------------------------- */

/* The #toc id refers to the single global table of contents, while the .toc
   class refers to generic TOC lists that could be used throughout the page. */

.toc code, .toc kbd, .toc samp { font-size: 100%; }
.toc li { font-weight: bold; }
.toc li li { font-weight: normal; }

/* -- Intro and Example Boxes ----------------------------------------------- */
/*
.intro, .example { margin-bottom: 2em; }
.example {
    -moz-border-radius: 4px;
    -webkit-border-radius: 4px;
    border-radius: 4px;
    -moz-box-shadow: 0 0 5px #bfbfbf;
    -webkit-box-shadow: 0 0 5px #bfbfbf;
    box-shadow: 0 0 5px #bfbfbf;
    padding: 1em;
}
.intro {
    background: none repeat scroll 0 0 #F0F1F8; border: 1px solid #D4D8EB; padding: 0 1em;
}
*/

/* -- Other Styles ---------------------------------------------------------- */

/* These are probably YUI-specific, and should be moved out of Selleck's default
   theme. */

.button {
  border: 1px solid #dadada;
  -moz-border-radius: 3px;
  -webkit-border-radius: 3px;
  border-radius: 3px;
  color: #444;
  display: inline-block;
  font-family: Helvetica, Arial, sans-serif;
  font-size: 92.308%;
  font-weight: bold;
  padding: 4px 13px 3px;
  -moz-text-shadow: 1px 1px 0 #fff;
  -webkit-text-shadow: 1px 1px 0 #fff;
  text-shadow: 1px 1px 0 #fff;
  white-space: nowrap;

  background: #EFEFEF; /* old browsers */
  background: -moz-linear-gradient(top, #f5f5f5 0%, #efefef 50%, #e5e5e5 51%, #dfdfdf 100%); /* firefox */
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f5f5f5), color-stop(50%,#efefef), color-stop(51%,#e5e5e5), color-stop(100%,#dfdfdf)); /* webkit */
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f5f5f5', endColorstr='#dfdfdf',GradientType=0 ); /* ie */
}

.button:hover {
  border-color: #466899;
  color: #fff;
  text-decoration: none;
  -moz-text-shadow: 1px 1px 0 #222;
  -webkit-text-shadow: 1px 1px 0 #222;
  text-shadow: 1px 1px 0 #222;

  background: #6396D8; /* old browsers */
  background: -moz-linear-gradient(top, #6396D8 0%, #5A83BC 50%, #547AB7 51%, #466899 100%); /* firefox */
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#6396D8), color-stop(50%,#5A83BC), color-stop(51%,#547AB7), color-stop(100%,#466899)); /* webkit */
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#6396D8', endColorstr='#466899',GradientType=0 ); /* ie */
}

.newwindow { text-align: center; }

.header .version em {
  display: block;
  text-align: right;
}


#classdocs .item {
  border-bottom: 1px dashed rgba(70, 104, 153, 0.29);
  margin: 1em 0;
  padding: 0 1.5em 1.8em 1.5em;
  &:last-of-type {
    border-bottom: none;
  }
}

#classdocs .item .params p,
#classdocs .item .returns p,{
  display: inline;
}

#classdocs .item em code, #classdocs .item em.comment {
  color: green;
}

#classdocs .item em.comment a {
  color: green;
  text-decoration: underline;
}

#classdocs .foundat {
  font-size: 11px;
  font-style: normal;
}

.attrs .emits {
  margin-left: 2em;
  padding: .5em;
  border-left: 1px dashed #ccc;
}

abbr {
  border-bottom: 1px dashed #ccc;
  font-size: 80%;
  cursor: help;
}

.prettyprint li.L0,
.prettyprint li.L1,
.prettyprint li.L2,
.prettyprint li.L3,
.prettyprint li.L5,
.prettyprint li.L6,
.prettyprint li.L7,
.prettyprint li.L8 {
  list-style: decimal;
}

ul li p {
  margin-top: 0;
}

.method .name, .property .name, .events .name {
  font-size: 110%;
  margin:0;
}

.apidocs .methods .extends .method,
.apidocs .properties .extends .property,
.apidocs .attrs .extends .attr,
.apidocs .events .extends .event {
  font-weight: bold;
}

.apidocs .methods .extends .inherited,
.apidocs .properties .extends .inherited,
.apidocs .attrs .extends .inherited,
.apidocs .events .extends .inherited {
  font-weight: normal;
}

#hd {
  background: rgba(0, 0, 0, 0.5) url(../img/bgscreen.png);
  border-bottom: 1px solid #DFDFDF;
  padding: 0 15px 1px 20px;
  margin-bottom: 15px;
  box-shadow: 0 1px 20px #333;
  position: fixed;
  width: 100%;
  box-sizing: border-box;
  z-index: 10;
}

/* -- API Docs CSS ---------------------------------------------------------- */

/*
This file is organized so that more generic styles are nearer the top, and more
specific styles are nearer the bottom of the file. This allows us to take full
advantage of the cascade to avoid redundant style rules. Please respect this
convention when making changes.
*/

/* -- Generic TabView styles ------------------------------------------------ */

/*
These styles apply to all API doc tabviews. To change styles only for a
specific tabview, see the other sections below.
*/

.yui3-js-enabled .apidocs .tabview {
  visibility: hidden; /* Hide until the TabView finishes rendering. */
  _visibility: visible;
}

.apidocs .tabview.yui3-tabview-content { visibility: visible; }
.apidocs .tabview .yui3-tabview-panel { background: #fff; }

/* -- Generic Content Styles ------------------------------------------------ */

/* Headings */

.link-docs {
  float: right;
  font-size: 15px;
  margin: 4px 4px 6px;
  padding: 6px 30px 5px;
}

.apidocs { zoom: 1; }

/* Generic box styles. */
.apidocs .box {
  border: 1px solid;
  margin: 0 0 2em 0;
  padding: 0 1em;
}

/* A flag is a compact, capsule-like indicator of some kind. It's used to
   indicate private and protected items, item return types, etc. in an
   attractive and unobtrusive way. */
.apidocs .flag {
  background: #bababa;
  border-radius: 3px;
  color: #fff;
  font-size: 11px;
  margin: 0 0.5em;
  padding: 2px 4px 1px;
}

/* Class/module metadata such as "Uses", "Extends", "Defined in", etc. */
.apidocs .meta {
  background: #f9f9f9;
  border-color: #efefef;
  color: #555;
  padding: 6px 12px;
}

.apidocs .meta p {
  margin: 0;
  font-size:14px;
}

/* Deprecation warning. */
.apidocs .box.deprecated,
.apidocs .flag.deprecated {
  background: #fdac9f;
  border: 1px solid #fd7775;
}

.apidocs .box.deprecated p { margin: 0.5em 0; }
.apidocs .flag.deprecated { color: #333; }

/* Module/Class intro description. */
.apidocs .intro {
  background: #f9f9f9;
  border-color: rgba(0, 0, 0, 0);
  border-left: 5px solid #69b2ec;
  padding: 1px 15px;
  margin-bottom: 20px;
}

/* Loading spinners. */
#bd.loading .apidocs,
#api-list.loading .yui3-tabview-panel {
  background: #fff url(../img/spinner.gif) no-repeat center 70px;
  min-height: 150px;
}

#bd.loading .apidocs .content,
#api-list.loading .yui3-tabview-panel .apis {
  display: none;
}

.apidocs .no-visible-items { color: #666; }

/* Generic inline list. */
.apidocs ul.inline {
  display: inline;
  list-style: none;
  margin: 0;
  padding: 0;
}

.apidocs ul.inline li { display: inline; }

/* Comma-separated list. */
.apidocs ul.commas li:after { content: ','; }
.apidocs ul.commas li:last-child:after { content: ''; }

/* Keyboard shortcuts. */
kbd .cmd { font-family: Monaco, Helvetica; }

/* -- Generic Access Level styles ------------------------------------------- */
.apidocs .item.protected,
.apidocs .item.private,
.apidocs .index-item.protected,
.apidocs .index-item.deprecated,
.apidocs .index-item.private {
  display: none;
}

.show-deprecated .item.deprecated,
.show-deprecated .index-item.deprecated,
.show-protected .item.protected,
.show-protected .index-item.protected,
.show-private .item.private,
.show-private .index-item.private {
  display: block;
}

.hide-inherited .item.inherited,
.hide-inherited .index-item.inherited {
  display: none;
}

/* -- Generic Item Index styles --------------------------------------------- */
.apidocs .index { margin: 1.5em 0 3em; }

.apidocs .index h3 {
  border-bottom: 1px solid #efefef;
  color: #333;
  margin: 1em 0 0.6em;
  padding-bottom: 2px;
  font-size: 28px;
}

.apidocs .index .no-visible-items { margin-top: 2em; }

.apidocs .index-list {
  border-color: #efefef;

  list-style: none;
  margin: 0;
  padding: 0;
  -moz-column-count: 4;
  -moz-column-gap: 10px;
  -moz-column-width: 170px;
  -ms-column-count: 4;
  -ms-column-gap: 10px;
  -ms-column-width: 170px;
  -o-column-count: 4;
  -o-column-gap: 10px;
  -o-column-width: 170px;
  -webkit-column-count: 4;
  -webkit-column-gap: 10px;
  -webkit-column-width: 170px;
  column-count: 4;
  column-gap: 10px;
  column-width: 170px;
}

.apidocs .no-columns .index-list {
  -moz-column-count: 1;
  -ms-column-count: 1;
  -o-column-count: 1;
  -webkit-column-count: 1;
  column-count: 1;
}

.apidocs .index-item {
  white-space: nowrap;
  font-size:18px;
}

.apidocs .index-item .flag {
  background: none;
  border: none;
  color: #afafaf;
  display: inline;
  margin: 0 0 0 0.2em;
  padding: 0;
}

/* -- Generic API item styles ----------------------------------------------- */
.apidocs .args {
  display: inline;
  margin: 0 0.5em;
}

.apidocs .flag.chainable { background: #46ca3b; }
.apidocs .flag.protected { background: #9b86fc; }
.apidocs .flag.private { background: #fd6b1b; }
.apidocs .flag.async { background: #356de4; }
.apidocs .flag.required { background: #e60923; }

.apidocs .item {
  border-bottom: 1px solid #efefef;
  margin: 1.5em 0 2em;
  padding-bottom: 2em;
}

.apidocs .item:nth-of-type(2n+1) {

}

.apidocs .item h4,
.apidocs .item h5,
.apidocs .item h6 {
  color: #333;
  font-family: inherit;
  font-size: 100%;
}

.apidocs .item .description p,
.apidocs .item pre.code {
  margin: 1em 0 0;
}

.apidocs .item .meta {
  margin-top: 8px;
}

.apidocs .item .name {
  display: inline-block;
}

.apidocs .item .type,
.apidocs .item .type a,
.apidocs .returns-inline {
  color: #555;
}

.apidocs .item .type,
.apidocs .returns-inline {

  margin: 0 0 0 0;
}

.apidocs .item .type a { border-bottom: 1px dotted #afafaf; }
.apidocs .item .type a:hover { border: none; }

/* -- Item Parameter List --------------------------------------------------- */
.apidocs .params-list {
  list-style: square;
  margin: 1em 0 0 2em;
  padding: 0;
}

.apidocs .param { margin-bottom: 1em; }

.apidocs .param .type,
.apidocs .param .type a {
  color: #666;
}

.apidocs .param .type {
  margin: 0 0 0 0.5em;
  *margin-left: 0.5em;
}

.apidocs .param-name { font-weight: bold; }

/* -- Item "Emits" block ---------------------------------------------------- */
.apidocs .item .emits {
  background: #f9f9f9;
  border-color: #eaeaea;
}

/* -- Item "Returns" block -------------------------------------------------- */
.apidocs .item .returns .type,
.apidocs .item .returns .type a {
  font-size: 100%;
  margin: 0;
}

/* -- Class Constructor block ----------------------------------------------- */
.apidocs .constructor .item {
  border: none;
  padding-bottom: 0;
}

/* -- File Source View ------------------------------------------------------ */
.apidocs .file pre.code,
#doc .apidocs .file pre.prettyprint {
  background: inherit;
  border: none;
  overflow: visible;
  padding: 0;
}

.apidocs .L0,
.apidocs .L1,
.apidocs .L2,
.apidocs .L3,
.apidocs .L4,
.apidocs .L5,
.apidocs .L6,
.apidocs .L7,
.apidocs .L8,
.apidocs .L9 {
  background: inherit;
}

/* -- Submodule List -------------------------------------------------------- */
.apidocs .module-submodule-description {
  font-size: 12px;
  margin: 0.3em 0 1em;
}

.apidocs .module-submodule-description p:first-child { margin-top: 0; }

/* -- Sidebar TabView ------------------------------------------------------- */
#api-tabview { margin-top: 0.6em; }

#api-tabview-filter,
#api-tabview-panel {
  border: 1px solid #dfdfdf;
}

#api-tabview-filter {
  border-bottom: none;
  border-top: none;
  padding: 0.6em 10px 0 10px;
}

#api-tabview-panel { border-top: none; }
#api-filter {
  width: 100%;
  -webkit-appearance: none;
  -moz-appearance:none;
  -ms-appearance:none;
  line-height: 40px;
  font-size: 18px;
  font-weight: 300;
  font-family: @font-family;
  border: none;
  border-bottom: 1px solid #DFDFDF;
  padding-left: 2px;
  color: #444;

  &:focus {
    outline: 0;
    border-bottom: 1px solid #ccc;
  }

}

/* -- Content TabView ------------------------------------------------------- */
#classdocs .yui3-tabview-panel { border: none; }

/* -- Source File Contents -------------------------------------------------- */
.prettyprint li.L0,
.prettyprint li.L1,
.prettyprint li.L2,
.prettyprint li.L3,
.prettyprint li.L5,
.prettyprint li.L6,
.prettyprint li.L7,
.prettyprint li.L8 {
  list-style: decimal;
}

/* -- API options ----------------------------------------------------------- */
#api-options {

  margin-top: 2.2em;
  position: absolute;
  right: 1.5em;
}

/*#api-options label { margin-right: 0.6em; }*/

/* -- API list -------------------------------------------------------------- */
#api-list {
  margin-top: 1.5em;
  *zoom: 1;
}

.apis {
  line-height: 1.4;
  list-style: none;
  margin: 0;
  padding: 0.5em 0 0.5em 0.4em;
}

.apis a {
  border: 1px solid transparent;
  display: block;
  margin: 0 0 0 -4px;
  padding: 2px 10px;
  text-decoration: none;
  line-height: 22px;
}

.apis a:hover,
.apis a:focus {
  background: #69b2ec;
  border-color: #AAC0FA;
  color: #fff;
  outline: none;
}

.api-list-item a:hover,
.api-list-item a:focus {
  text-shadow: none;
}

.apis .message { color: #888; }
.apis .result a { padding: 3px 5px 2px; }

.apis .result .type {
  right: 4px;
  top: 7px;
}

.api-list-item .yui3-highlight {
  font-weight: bold;
}


.blue-method-syntax {
  background: #F3F2F2;
  border-left: 5px solid #69b2ec;
  /*border-left-width: 5px;*/
  padding: 0.5em 1em;
}

.blue-method-syntax li code {
  padding:0;
  border:0;
  background:none;
}
.param-description {
  padding: 1px;
}

.params ul li p {
  margin-top: 10px;
  margin-bottom: 10px;
}
.params ul li p:first-of-type {
  margin-top:5px;
}

.param-name.optional{
  background: rgb(234, 240, 228);
  border: 1px solid rgb(234, 240, 228);
}

h3.blue-method-name {
  font-size: 28px;
  margin-bottom: 5px;
  padding: 5px 0px 7px;
  border-bottom:1px solid #5490c7;
}

.apidocs .item .meta.method-meta {
  margin-top: 0;
  margin-bottom: 10px;
}

.meta.method-meta {

}

.blue-return-desc {
  padding-left:20px;
}

h1.blue-main-title {
  margin: 0;
  color: #fff;
  font-size:20px;
  line-height: 50px;
}

.project-version {
  color: #fff;
  line-height: 20px;
  padding: 5px 10px;
  position: absolute;
  text-align: right;
  right: 0;
}


.yui-overrride{
  .yui3-skin-sam .yui3-tab-label:hover, .yui3-skin-sam .yui3-tab-label:focus {
    background: #D9EAF5;
    outline: 0;
  }

  .yui3-skin-sam .yui3-tab-label {
    border:none;
    background: rgb(236, 236, 236);
    font-size: 15px;
    font-weight: 300;
  }

  .yui3-skin-sam .yui3-tab-selected .yui3-tab-label, .yui3-skin-sam .yui3-tab-selected .yui3-tab-label:focus, .yui3-skin-sam .yui3-tab-selected .yui3-tab-label:hover {
    background: rgb(105, 178, 236);
    color: #fff;
  }

  .yui3-skin-sam .yui3-tabview-list {
    border-bottom:solid rgb(105, 178, 236);
  }
}



================================================
FILE: extras/yuidoc-theme-topheman/assets/index.html
================================================


    
        Redirector
        
    
    
        Click here to redirect
    



================================================
FILE: extras/yuidoc-theme-topheman/assets/js/api-filter.js
================================================
YUI.add('api-filter', function (Y) {

Y.APIFilter = Y.Base.create('apiFilter', Y.Base, [Y.AutoCompleteBase], {
    // -- Initializer ----------------------------------------------------------
    initializer: function () {
        this._bindUIACBase();
        this._syncUIACBase();
    },
    getDisplayName: function(name) {

        Y.each(Y.YUIDoc.meta.allModules, function(i) {
            if (i.name === name && i.displayName) {
                name = i.displayName;
            }
        });

        return name;
    }

}, {
    // -- Attributes -----------------------------------------------------------
    ATTRS: {
        resultHighlighter: {
            value: 'phraseMatch'
        },

        // May be set to "classes" or "modules".
        queryType: {
            value: 'classes'
        },

        source: {
            valueFn: function() {
                var self = this;
                return function(q) {
                    var data = Y.YUIDoc.meta[self.get('queryType')],
                        out = [];
                    Y.each(data, function(v) {
                        if (v.toLowerCase().indexOf(q.toLowerCase()) > -1) {
                            out.push(v);
                        }
                    });
                    return out;
                };
            }
        }
    }
});

}, '3.4.0', {requires: [
    'autocomplete-base', 'autocomplete-highlighters', 'autocomplete-sources'
]});


================================================
FILE: extras/yuidoc-theme-topheman/assets/js/api-list.js
================================================
YUI.add('api-list', function (Y) {

var Lang   = Y.Lang,
    YArray = Y.Array,

    APIList = Y.namespace('APIList'),

    classesNode    = Y.one('#api-classes'),
    inputNode      = Y.one('#api-filter'),
    modulesNode    = Y.one('#api-modules'),
    tabviewNode    = Y.one('#api-tabview'),

    tabs = APIList.tabs = {},

    filter = APIList.filter = new Y.APIFilter({
        inputNode : inputNode,
        maxResults: 1000,

        on: {
            results: onFilterResults
        }
    }),

    search = APIList.search = new Y.APISearch({
        inputNode : inputNode,
        maxResults: 100,

        on: {
            clear  : onSearchClear,
            results: onSearchResults
        }
    }),

    tabview = APIList.tabview = new Y.TabView({
        srcNode  : tabviewNode,
        panelNode: '#api-tabview-panel',
        render   : true,

        on: {
            selectionChange: onTabSelectionChange
        }
    }),

    focusManager = APIList.focusManager = tabviewNode.plug(Y.Plugin.NodeFocusManager, {
        circular   : true,
        descendants: '#api-filter, .yui3-tab-panel-selected .api-list-item a, .yui3-tab-panel-selected .result a',
        keys       : {next: 'down:40', previous: 'down:38'}
    }).focusManager,

    LIST_ITEM_TEMPLATE =
        '
  • ' + '{displayName}' + '
  • '; // -- Init --------------------------------------------------------------------- // Duckpunch FocusManager's key event handling to prevent it from handling key // events when a modifier is pressed. Y.before(function (e, activeDescendant) { if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return new Y.Do.Prevent(); } }, focusManager, '_focusPrevious', focusManager); Y.before(function (e, activeDescendant) { if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return new Y.Do.Prevent(); } }, focusManager, '_focusNext', focusManager); // Create a mapping of tabs in the tabview so we can refer to them easily later. tabview.each(function (tab, index) { var name = tab.get('label').toLowerCase(); tabs[name] = { index: index, name : name, tab : tab }; }); // Switch tabs on Ctrl/Cmd-Left/Right arrows. tabviewNode.on('key', onTabSwitchKey, 'down:37,39'); // Focus the filter input when the `/` key is pressed. Y.one(Y.config.doc).on('key', onSearchKey, 'down:83'); // Keep the Focus Manager up to date. inputNode.on('focus', function () { focusManager.set('activeDescendant', inputNode); }); // Update all tabview links to resolved URLs. tabview.get('panelNode').all('a').each(function (link) { link.setAttribute('href', link.get('href')); }); // -- Private Functions -------------------------------------------------------- function getFilterResultNode() { return filter.get('queryType') === 'classes' ? classesNode : modulesNode; } // -- Event Handlers ----------------------------------------------------------- function onFilterResults(e) { var frag = Y.one(Y.config.doc.createDocumentFragment()), resultNode = getFilterResultNode(), typePlural = filter.get('queryType'), typeSingular = typePlural === 'classes' ? 'class' : 'module'; if (e.results.length) { YArray.each(e.results, function (result) { frag.append(Lang.sub(LIST_ITEM_TEMPLATE, { rootPath : APIList.rootPath, displayName : filter.getDisplayName(result.highlighted), name : result.text, typePlural : typePlural, typeSingular: typeSingular })); }); } else { frag.append( '
  • ' + 'No ' + typePlural + ' found.' + '
  • ' ); } resultNode.empty(true); resultNode.append(frag); focusManager.refresh(); } function onSearchClear(e) { focusManager.refresh(); } function onSearchKey(e) { var target = e.target; if (target.test('input,select,textarea') || target.get('isContentEditable')) { return; } e.preventDefault(); inputNode.focus(); focusManager.refresh(); } function onSearchResults(e) { var frag = Y.one(Y.config.doc.createDocumentFragment()); if (e.results.length) { YArray.each(e.results, function (result) { frag.append(result.display); }); } else { frag.append( '
  • ' + 'No results found. Maybe you\'ll have better luck with a ' + 'different query?' + '
  • ' ); } focusManager.refresh(); } function onTabSelectionChange(e) { var tab = e.newVal, name = tab.get('label').toLowerCase(); tabs.selected = { index: tab.get('index'), name : name, tab : tab }; switch (name) { case 'classes': // fallthru case 'modules': filter.setAttrs({ minQueryLength: 0, queryType : name }); search.set('minQueryLength', -1); // Only send a request if this isn't the initially-selected tab. if (e.prevVal) { filter.sendRequest(filter.get('value')); } break; case 'everything': filter.set('minQueryLength', -1); search.set('minQueryLength', 1); if (search.get('value')) { search.sendRequest(search.get('value')); } else { inputNode.focus(); } break; default: // WTF? We shouldn't be here! filter.set('minQueryLength', -1); search.set('minQueryLength', -1); } if (focusManager) { setTimeout(function () { focusManager.refresh(); }, 1); } } function onTabSwitchKey(e) { var currentTabIndex = tabs.selected.index; if (!(e.ctrlKey || e.metaKey)) { return; } e.preventDefault(); switch (e.keyCode) { case 37: // left arrow if (currentTabIndex > 0) { tabview.selectChild(currentTabIndex - 1); inputNode.focus(); } break; case 39: // right arrow if (currentTabIndex < (Y.Object.size(tabs) - 2)) { tabview.selectChild(currentTabIndex + 1); inputNode.focus(); } break; } } }, '3.4.0', {requires: [ 'api-filter', 'api-search', 'event-key', 'node-focusmanager', 'tabview' ]}); ================================================ FILE: extras/yuidoc-theme-topheman/assets/js/api-search.js ================================================ YUI.add('api-search', function (Y) { var Lang = Y.Lang, Node = Y.Node, YArray = Y.Array; Y.APISearch = Y.Base.create('apiSearch', Y.Base, [Y.AutoCompleteBase], { // -- Public Properties ---------------------------------------------------- RESULT_TEMPLATE: '
  • ' + '' + '

    {name}

    ' + '{resultType}' + '
    {description}
    ' + '{class}' + '
    ' + '
  • ', // -- Initializer ---------------------------------------------------------- initializer: function () { this._bindUIACBase(); this._syncUIACBase(); }, // -- Protected Methods ---------------------------------------------------- _apiResultFilter: function (query, results) { // Filter components out of the results. return YArray.filter(results, function (result) { return result.raw.resultType === 'component' ? false : result; }); }, _apiResultFormatter: function (query, results) { return YArray.map(results, function (result) { var raw = Y.merge(result.raw), // create a copy desc = raw.description || ''; // Convert description to text and truncate it if necessary. desc = Node.create('
    ' + desc + '
    ').get('text'); if (desc.length > 65) { desc = Y.Escape.html(desc.substr(0, 65)) + ' …'; } else { desc = Y.Escape.html(desc); } raw['class'] || (raw['class'] = ''); raw.description = desc; // Use the highlighted result name. raw.name = result.highlighted; return Lang.sub(this.RESULT_TEMPLATE, raw); }, this); }, _apiTextLocator: function (result) { return result.displayName || result.name; } }, { // -- Attributes ----------------------------------------------------------- ATTRS: { resultFormatter: { valueFn: function () { return this._apiResultFormatter; } }, resultFilters: { valueFn: function () { return this._apiResultFilter; } }, resultHighlighter: { value: 'phraseMatch' }, resultListLocator: { value: 'data.results' }, resultTextLocator: { valueFn: function () { return this._apiTextLocator; } }, source: { value: '/api/v1/search?q={query}&count={maxResults}' } } }); }, '3.4.0', {requires: [ 'autocomplete-base', 'autocomplete-highlighters', 'autocomplete-sources', 'escape' ]}); ================================================ FILE: extras/yuidoc-theme-topheman/assets/js/apidocs.js ================================================ YUI().use( 'yuidoc-meta', 'api-list', 'history-hash', 'node-screen', 'node-style', 'pjax', function (Y) { var win = Y.config.win, localStorage = win.localStorage, bdNode = Y.one('#bd'), pjax, defaultRoute, classTabView, selectedTab; // Kill pjax functionality unless serving over HTTP. if (!Y.getLocation().protocol.match(/^https?\:/)) { Y.Router.html5 = false; } // Create the default route with middleware which enables syntax highlighting // on the loaded content. defaultRoute = Y.Pjax.defaultRoute.concat(function (req, res, next) { prettyPrint(); bdNode.removeClass('loading'); next(); }); pjax = new Y.Pjax({ container : '#docs-main', contentSelector: '#docs-main > .content', linkSelector : '#bd a', titleSelector : '#xhr-title', navigateOnHash: true, root : '/', routes : [ // -- / ---------------------------------------------------------------- { path : '/(index.html)?', callbacks: defaultRoute }, // -- /classes/* ------------------------------------------------------- { path : '/classes/:class.html*', callbacks: [defaultRoute, 'handleClasses'] }, // -- /files/* --------------------------------------------------------- { path : '/files/*file', callbacks: [defaultRoute, 'handleFiles'] }, // -- /modules/* ------------------------------------------------------- { path : '/modules/:module.html*', callbacks: defaultRoute } ] }); // -- Utility Functions -------------------------------------------------------- pjax.checkVisibility = function (tab) { tab || (tab = selectedTab); if (!tab) { return; } var panelNode = tab.get('panelNode'), visibleItems; // If no items are visible in the tab panel due to the current visibility // settings, display a message to that effect. visibleItems = panelNode.all('.item,.index-item').some(function (itemNode) { if (itemNode.getComputedStyle('display') !== 'none') { return true; } }); panelNode.all('.no-visible-items').remove(); if (!visibleItems) { if (Y.one('#index .index-item')) { panelNode.append( '
    ' + '

    ' + 'Some items are not shown due to the current visibility ' + 'settings. Use the checkboxes at the upper right of this ' + 'page to change the visibility settings.' + '

    ' + '
    ' ); } else { panelNode.append( '
    ' + '

    ' + 'This class doesn\'t provide any methods, properties, ' + 'attributes, or events.' + '

    ' + '
    ' ); } } // Hide index sections without any visible items. Y.all('.index-section').each(function (section) { var items = 0, visibleItems = 0; section.all('.index-item').each(function (itemNode) { items += 1; if (itemNode.getComputedStyle('display') !== 'none') { visibleItems += 1; } }); section.toggleClass('hidden', !visibleItems); section.toggleClass('no-columns', visibleItems < 4); }); }; pjax.initClassTabView = function () { if (!Y.all('#classdocs .api-class-tab').size()) { return; } if (classTabView) { classTabView.destroy(); selectedTab = null; } classTabView = new Y.TabView({ srcNode: '#classdocs', on: { selectionChange: pjax.onTabSelectionChange } }); pjax.updateTabState(); classTabView.render(); }; pjax.initLineNumbers = function () { var hash = win.location.hash.substring(1), container = pjax.get('container'), hasLines, node; // Add ids for each line number in the file source view. container.all('.linenums>li').each(function (lineNode, index) { lineNode.set('id', 'l' + (index + 1)); lineNode.addClass('file-line'); hasLines = true; }); // Scroll to the desired line. if (hasLines && /^l\d+$/.test(hash)) { if ((node = container.getById(hash))) { win.scroll(0, node.getY()); } } }; pjax.initRoot = function () { var terminators = /^(?:classes|files|modules)$/, parts = pjax._getPathRoot().split('/'), root = [], i, len, part; for (i = 0, len = parts.length; i < len; i += 1) { part = parts[i]; if (part.match(terminators)) { // Makes sure the path will end with a "/". root.push(''); break; } root.push(part); } pjax.set('root', root.join('/')); }; pjax.updateTabState = function (src) { var hash = win.location.hash.substring(1), defaultTab, node, tab, tabPanel; function scrollToNode() { if (node.hasClass('protected')) { Y.one('#api-show-protected').set('checked', true); pjax.updateVisibility(); } if (node.hasClass('private')) { Y.one('#api-show-private').set('checked', true); pjax.updateVisibility(); } setTimeout(function () { // For some reason, unless we re-get the node instance here, // getY() always returns 0. var node = Y.one('#classdocs').getById(hash); win.scrollTo(0, node.getY() - 70); }, 1); } if (!classTabView) { return; } if (src === 'hashchange' && !hash) { defaultTab = 'index'; } else { if (localStorage) { defaultTab = localStorage.getItem('tab_' + pjax.getPath()) || 'index'; } else { defaultTab = 'index'; } } if (hash && (node = Y.one('#classdocs').getById(hash))) { if ((tabPanel = node.ancestor('.api-class-tabpanel', true))) { if ((tab = Y.one('#classdocs .api-class-tab.' + tabPanel.get('id')))) { if (classTabView.get('rendered')) { Y.Widget.getByNode(tab).set('selected', 1); } else { tab.addClass('yui3-tab-selected'); } } } // Scroll to the desired element if this is a hash URL. if (node) { if (classTabView.get('rendered')) { scrollToNode(); } else { classTabView.once('renderedChange', scrollToNode); } } } else { tab = Y.one('#classdocs .api-class-tab.' + defaultTab); // When the `defaultTab` node isn't found, `localStorage` is stale. if (!tab && defaultTab !== 'index') { tab = Y.one('#classdocs .api-class-tab.index'); } if (classTabView.get('rendered')) { Y.Widget.getByNode(tab).set('selected', 1); } else { tab.addClass('yui3-tab-selected'); } } }; pjax.updateVisibility = function () { var container = pjax.get('container'); container.toggleClass('hide-inherited', !Y.one('#api-show-inherited').get('checked')); container.toggleClass('show-deprecated', Y.one('#api-show-deprecated').get('checked')); container.toggleClass('show-protected', Y.one('#api-show-protected').get('checked')); container.toggleClass('show-private', Y.one('#api-show-private').get('checked')); pjax.checkVisibility(); }; // -- Route Handlers ----------------------------------------------------------- pjax.handleClasses = function (req, res, next) { var status = res.ioResponse.status; // Handles success and local filesystem XHRs. if (!status || (status >= 200 && status < 300)) { pjax.initClassTabView(); } next(); }; pjax.handleFiles = function (req, res, next) { var status = res.ioResponse.status; // Handles success and local filesystem XHRs. if (!status || (status >= 200 && status < 300)) { pjax.initLineNumbers(); } next(); }; // -- Event Handlers ----------------------------------------------------------- pjax.onNavigate = function (e) { var hash = e.hash, originTarget = e.originEvent && e.originEvent.target, tab; if (hash) { tab = originTarget && originTarget.ancestor('.yui3-tab', true); if (hash === win.location.hash) { pjax.updateTabState('hashchange'); } else if (!tab) { win.location.hash = hash; } e.preventDefault(); return; } // Only scroll to the top of the page when the URL doesn't have a hash. this.set('scrollToTop', !e.url.match(/#.+$/)); bdNode.addClass('loading'); }; pjax.onOptionClick = function (e) { pjax.updateVisibility(); }; pjax.onTabSelectionChange = function (e) { var tab = e.newVal, tabId = tab.get('contentBox').getAttribute('href').substring(1); selectedTab = tab; // If switching from a previous tab (i.e., this is not the default tab), // replace the history entry with a hash URL that will cause this tab to // be selected if the user navigates away and then returns using the back // or forward buttons. if (e.prevVal && localStorage) { localStorage.setItem('tab_' + pjax.getPath(), tabId); } pjax.checkVisibility(tab); }; // -- Init --------------------------------------------------------------------- pjax.on('navigate', pjax.onNavigate); pjax.initRoot(); pjax.upgrade(); pjax.initClassTabView(); pjax.initLineNumbers(); pjax.updateVisibility(); Y.APIList.rootPath = pjax.get('root'); Y.one('#api-options').delegate('click', pjax.onOptionClick, 'input'); Y.on('hashchange', function (e) { pjax.updateTabState('hashchange'); }, win); }); ================================================ FILE: extras/yuidoc-theme-topheman/assets/js/yui-prettify.js ================================================ YUI().use('node', function(Y) { var code = Y.all('.prettyprint.linenums'); if (code.size()) { code.each(function(c) { var lis = c.all('ol li'), l = 1; lis.each(function(n) { n.prepend(''); l++; }); }); var h = location.hash; location.hash = ''; h = h.replace('LINE_', 'LINENUM_'); location.hash = h; } }); ================================================ FILE: extras/yuidoc-theme-topheman/assets/vendor/prettify/CHANGES.html ================================================ Change Log README

    Known Issues

    • Perl formatting is really crappy. Partly because the author is lazy and partly because Perl is hard to parse.
    • On some browsers, <code> elements with newlines in the text which use CSS to specify white-space:pre will have the newlines improperly stripped if the element is not attached to the document at the time the stripping is done. Also, on IE 6, all newlines will be stripped from <code> elements because of the way IE6 produces innerHTML. Workaround: use <pre> for code with newlines.

    Change Log

    29 March 2007

    • Added tests for PHP support to address issue 3.
    • Fixed bug: prettyPrintOne was not halting. This was not reachable through the normal entry point.
    • Fixed bug: recursing into a script block or PHP tag that was not properly closed would not silently drop the content. (test)
    • Fixed bug: was eating tabs (test)
    • Fixed entity handling so that the caveat

      Caveats: please properly escape less-thans. x&lt;y instead of x<y, and use " instead of &quot; for string delimiters.

      is no longer applicable.
    • Added noisefree's C# patch
    • Added a distribution that has comments and whitespace removed to reduce download size from 45.5kB to 12.8kB.

    4 Jul 2008

    • Added language specific formatters that are triggered by the presence of a lang-<language-file-extension>
    • Fixed bug: python handling of '''string'''
    • Fixed bug: / in regex [charsets] should not end regex

    5 Jul 2008

    • Defined language extensions for Lisp and Lua

    14 Jul 2008

    • Language handlers for F#, OCAML, SQL
    • Support for nocode spans to allow embedding of line numbers and code annotations which should not be styled or otherwise affect the tokenization of prettified code. See the issue 22 testcase.

    6 Jan 2009

    • Language handlers for Visual Basic, Haskell, CSS, and WikiText
    • Added .mxml extension to the markup style handler for Flex MXML files. See issue 37.
    • Added .m extension to the C style handler so that Objective C source files properly highlight. See issue 58.
    • Changed HTML lexer to use the same embedded source mechanism as the wiki language handler, and changed to use the registered CSS handler for STYLE element content.

    21 May 2009

    • Rewrote to improve performance on large files. See benchmarks.
    • Fixed bugs with highlighting of Haskell line comments, Lisp number literals, Lua strings, C preprocessor directives, newlines in Wiki code on Windows, and newlines in IE6.

    14 August 2009

    • Fixed prettifying of <code> blocks with embedded newlines.

    3 October 2009

    • Fixed prettifying of XML/HTML tags that contain uppercase letters.

    19 July 2010

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

    Javascript code prettifier

    Setup

    1. Download a distribution
    2. Include the script and stylesheets in your document (you will need to make sure the css and js file are on your server, and adjust the paths in the script and link tag)
      <link href="prettify.css" type="text/css" rel="stylesheet" />
      <script type="text/javascript" src="prettify.js"></script>
    3. Add onload="prettyPrint()" to your document's body tag.
    4. Modify the stylesheet to get the coloring you prefer

    Usage

    Put code snippets in <pre class="prettyprint">...</pre> or <code class="prettyprint">...</code> and it will automatically be pretty printed.
    The original Prettier
    class Voila {
    public:
      // Voila
      static const string VOILA = "Voila";
    
      // will not interfere with embedded tags.
    }
    class Voila {
    public:
      // Voila
      static const string VOILA = "Voila";
    
      // will not interfere with embedded tags.
    }

    FAQ

    Which languages does it work for?

    The comments in prettify.js are authoritative but the lexer should work on a number of languages including C and friends, Java, Python, Bash, SQL, HTML, XML, CSS, Javascript, and Makefiles. It works passably on Ruby, PHP, VB, and Awk and a decent subset of Perl and Ruby, but, because of commenting conventions, doesn't work on Smalltalk, or CAML-like languages.

    LISPy languages are supported via an extension: lang-lisp.js.

    And similarly for CSS, Haskell, Lua, OCAML, SML, F#, Visual Basic, SQL, Protocol Buffers, and WikiText..

    If you'd like to add an extension for your favorite language, please look at src/lang-lisp.js and file an issue including your language extension, and a testcase.

    How do I specify which language my code is in?

    You don't need to specify the language since prettyprint() will guess. You can specify a language by specifying the language extension along with the prettyprint class like so:

    <pre class="prettyprint lang-html">
      The lang-* class specifies the language file extensions.
      File extensions supported by default include
        "bsh", "c", "cc", "cpp", "cs", "csh", "cyc", "cv", "htm", "html",
        "java", "js", "m", "mxml", "perl", "pl", "pm", "py", "rb", "sh",
        "xhtml", "xml", "xsl".
    </pre>

    It doesn't work on <obfuscated code sample>?

    Yes. Prettifying obfuscated code is like putting lipstick on a pig — i.e. outside the scope of this tool.

    Which browsers does it work with?

    It's been tested with IE 6, Firefox 1.5 & 2, and Safari 2.0.4. Look at the test page to see if it works in your browser.

    What's changed?

    See the change log

    Why doesn't Prettyprinting of strings work on WordPress?

    Apparently wordpress does "smart quoting" which changes close quotes. This causes end quotes to not match up with open quotes.

    This breaks prettifying as well as copying and pasting of code samples. See WordPress's help center for info on how to stop smart quoting of code snippets.

    How do I put line numbers in my code?

    You can use the linenums class to turn on line numbering. If your code doesn't start at line number 1, you can add a colon and a line number to the end of that class as in linenums:52.

    For example

    <pre class="prettyprint linenums:4"
    >// This is line 4.
    foo();
    bar();
    baz();
    boo();
    far();
    faz();
    <pre>
    produces
    // This is line 4.
    foo();
    bar();
    baz();
    boo();
    far();
    faz();
    

    How do I prevent a portion of markup from being marked as code?

    You can use the nocode class to identify a span of markup that is not code.

    <pre class=prettyprint>
    int x = foo();  /* This is a comment  <span class="nocode">This is not code</span>
      Continuation of comment */
    int y = bar();
    </pre>
    produces
    int x = foo();  /* This is a comment  This is not code
      Continuation of comment */
    int y = bar();
    

    For a more complete example see the issue22 testcase.

    I get an error message "a is not a function" or "opt_whenDone is not a function"

    If you are calling prettyPrint via an event handler, wrap it in a function. Instead of doing

    addEventListener('load', prettyPrint, false);
    wrap it in a closure like
    addEventListener('load', function (event) { prettyPrint() }, false);
    so that the browser does not pass an event object to prettyPrint which will confuse it.


    ================================================ FILE: extras/yuidoc-theme-topheman/assets/vendor/prettify/prettify-min.css ================================================ .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} ================================================ FILE: extras/yuidoc-theme-topheman/assets/vendor/prettify/prettify-min.js ================================================ window.PR_SHOULD_USE_CONTINUATION=true;var prettyPrintOne;var prettyPrint;(function(){var O=window;var j=["break,continue,do,else,for,if,return,while"];var v=[j,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var q=[v,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var m=[q,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var y=[q,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var T=[y,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,let,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var,virtual,where"];var s="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,throw,true,try,unless,until,when,while,yes";var x=[q,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var t="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var J=[j,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var g=[j,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var I=[j,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var B=[m,T,x,t+J,g,I];var f=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)\b/;var D="str";var A="kwd";var k="com";var Q="typ";var H="lit";var M="pun";var G="pln";var n="tag";var F="dec";var K="src";var R="atn";var o="atv";var P="nocode";var N="(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function l(ab){var af=0;var U=false;var ae=false;for(var X=0,W=ab.length;X122)){if(!(am<65||ai>90)){ah.push([Math.max(65,ai)|32,Math.min(am,90)|32])}if(!(am<97||ai>122)){ah.push([Math.max(97,ai)&~32,Math.min(am,122)&~32])}}}}ah.sort(function(aw,av){return(aw[0]-av[0])||(av[1]-aw[1])});var ak=[];var aq=[];for(var at=0;atau[0]){if(au[1]+1>au[0]){ao.push("-")}ao.push(V(au[1]))}}ao.push("]");return ao.join("")}function Y(an){var al=an.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var aj=al.length;var ap=[];for(var am=0,ao=0;am=2&&ak==="["){al[am]=Z(ai)}else{if(ak!=="\\"){al[am]=ai.replace(/[a-zA-Z]/g,function(aq){var ar=aq.charCodeAt(0);return"["+String.fromCharCode(ar&~32,ar|32)+"]"})}}}}return al.join("")}var ac=[];for(var X=0,W=ab.length;X=0;){U[ae.charAt(ag)]=aa}}var ah=aa[1];var ac=""+ah;if(!ai.hasOwnProperty(ac)){aj.push(ah);ai[ac]=null}}aj.push(/[\0-\uffff]/);X=l(aj)})();var Z=V.length;var Y=function(aj){var ab=aj.sourceCode,aa=aj.basePos;var af=[aa,G];var ah=0;var ap=ab.match(X)||[];var al={};for(var ag=0,at=ap.length;ag=5&&"lang-"===ar.substring(0,5);if(ao&&!(ak&&typeof ak[1]==="string")){ao=false;ar=K}if(!ao){al[ai]=ar}}var ad=ah;ah+=ai.length;if(!ao){af.push(aa+ad,ar)}else{var an=ak[1];var am=ai.indexOf(an);var ae=am+an.length;if(ak[2]){ae=ai.length-ak[2].length;am=ae-an.length}var au=ar.substring(5);C(aa+ad,ai.substring(0,am),Y,af);C(aa+ad+am,an,r(au,an),af);C(aa+ad+ae,ai.substring(ae),Y,af)}}aj.decorations=af};return Y}function i(V){var Y=[],U=[];if(V.tripleQuotedStrings){Y.push([D,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(V.multiLineStrings){Y.push([D,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{Y.push([D,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(V.verbatimStrings){U.push([D,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var ab=V.hashComments;if(ab){if(V.cStyleComments){if(ab>1){Y.push([k,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{Y.push([k,/^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}U.push([D,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,null])}else{Y.push([k,/^#[^\r\n]*/,null,"#"])}}if(V.cStyleComments){U.push([k,/^\/\/[^\r\n]*/,null]);U.push([k,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(V.regexLiterals){var aa=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");U.push(["lang-regex",new RegExp("^"+N+"("+aa+")")])}var X=V.types;if(X){U.push([Q,X])}var W=(""+V.keywords).replace(/^ | $/g,"");if(W.length){U.push([A,new RegExp("^(?:"+W.replace(/[\s,]+/g,"|")+")\\b"),null])}Y.push([G,/^\s+/,null," \r\n\t\xA0"]);var Z=/^.[^\s\w\.$@\'\"\`\/\\]*/;U.push([H,/^@[a-z_$][a-z_$@0-9]*/i,null],[Q,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[G,/^[a-z_$][a-z_$@0-9]*/i,null],[H,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[G,/^\\[\s\S]?/,null],[M,Z,null]);return h(Y,U)}var L=i({keywords:B,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function S(W,ah,aa){var V=/(?:^|\s)nocode(?:\s|$)/;var ac=/\r\n?|\n/;var ad=W.ownerDocument;var ag=ad.createElement("li");while(W.firstChild){ag.appendChild(W.firstChild)}var X=[ag];function af(am){switch(am.nodeType){case 1:if(V.test(am.className)){break}if("br"===am.nodeName){ae(am);if(am.parentNode){am.parentNode.removeChild(am)}}else{for(var ao=am.firstChild;ao;ao=ao.nextSibling){af(ao)}}break;case 3:case 4:if(aa){var an=am.nodeValue;var ak=an.match(ac);if(ak){var aj=an.substring(0,ak.index);am.nodeValue=aj;var ai=an.substring(ak.index+ak[0].length);if(ai){var al=am.parentNode;al.insertBefore(ad.createTextNode(ai),am.nextSibling)}ae(am);if(!aj){am.parentNode.removeChild(am)}}}break}}function ae(al){while(!al.nextSibling){al=al.parentNode;if(!al){return}}function aj(am,at){var ar=at?am.cloneNode(false):am;var ap=am.parentNode;if(ap){var aq=aj(ap,1);var ao=am.nextSibling;aq.appendChild(ar);for(var an=ao;an;an=ao){ao=an.nextSibling;aq.appendChild(an)}}return ar}var ai=aj(al.nextSibling,0);for(var ak;(ak=ai.parentNode)&&ak.nodeType===1;){ai=ak}X.push(ai)}for(var Z=0;Z=U){aj+=2}if(Y>=ar){ac+=2}}}finally{if(au){au.style.display=ak}}}var u={};function d(W,X){for(var U=X.length;--U>=0;){var V=X[U];if(!u.hasOwnProperty(V)){u[V]=W}else{if(O.console){console.warn("cannot override language handler %s",V)}}}}function r(V,U){if(!(V&&u.hasOwnProperty(V))){V=/^\s*]*(?:>|$)/],[k,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[M,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);d(h([[G,/^[\s]+/,null," \t\r\n"],[o,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[n,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[R,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[M,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);d(h([],[[o,/^[\s\S]+/]]),["uq.val"]);d(i({keywords:m,hashComments:true,cStyleComments:true,types:f}),["c","cc","cpp","cxx","cyc","m"]);d(i({keywords:"null,true,false"}),["json"]);d(i({keywords:T,hashComments:true,cStyleComments:true,verbatimStrings:true,types:f}),["cs"]);d(i({keywords:y,cStyleComments:true}),["java"]);d(i({keywords:I,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);d(i({keywords:J,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);d(i({keywords:t,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);d(i({keywords:g,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);d(i({keywords:x,cStyleComments:true,regexLiterals:true}),["js"]);d(i({keywords:s,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);d(h([],[[D,/^[\s\S]+/]]),["regex"]);function e(X){var W=X.langExtension;try{var U=b(X.sourceNode,X.pre);var V=U.sourceCode;X.sourceCode=V;X.spans=U.spans;X.basePos=0;r(W,V)(X);E(X)}catch(Y){if(O.console){console.log(Y&&Y.stack?Y.stack:Y)}}}function z(Y,X,W){var U=document.createElement("pre");U.innerHTML=Y;if(W){S(U,W,true)}var V={langExtension:X,numberLines:W,sourceNode:U,pre:1};e(V);return U.innerHTML}function c(aj){function ab(al){return document.getElementsByTagName(al)}var ah=[ab("pre"),ab("code"),ab("xmp")];var V=[];for(var ae=0;ae]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); ================================================ FILE: extras/yuidoc-theme-topheman/layouts/main.handlebars ================================================ {{htmlTitle}}

    {{projectName}}

    API Docs for: {{projectVersion}}
    {{>options}}
    {{>layout_content}}
    ©2015 labs.topheman.com - Christophe Rosset
    ================================================ FILE: extras/yuidoc-theme-topheman/layouts/xhr.handlebars ================================================
    {{>layout_content}}
    ================================================ FILE: extras/yuidoc-theme-topheman/partials/attrs.handlebars ================================================
    {{! For backwards compatibility }}

    {{name}}

    {{#crossLink type}}{{/crossLink}} {{#if deprecated}} deprecated {{/if}} {{#if access}} {{access}} {{/if}} {{#if final}} final {{/if}} {{#if static}} static {{/if}} {{#if optional}} optional {{/if}} {{#if required}} required {{/if}} {{#if readonly}} readonly {{/if}}
    {{#if overwritten_from}}

    Inherited from {{overwritten_from/class}} {{#if foundAt}} but overwritten in {{/if}} {{else}} {{#if extended_from}}

    Inherited from {{extended_from}}: {{else}} {{#providedBy}}

    Provided by the {{.}} module.

    {{/providedBy}}

    {{#if foundAt}} Defined in {{/if}} {{/if}} {{/if}} {{#if foundAt}} `{{{file}}}:{{{line}}}` {{/if}}

    {{#if deprecationMessage}}

    Deprecated: {{deprecationMessage}}

    {{/if}} {{#if since}}

    Available since {{since}}

    {{/if}}
    {{{attrDescription}}}
    {{#if default}}

    Default: {{default}}

    {{/if}} {{#if emit}}

    Fires event {{name}}Change

    Fires when the value for the configuration attribute `{{{name}}}` is changed. You can listen for the event using the `on` method if you wish to be notified before the attribute's value has changed, or using the `after` method if you wish to be notified after the attribute's value has changed.

    Parameters:

    • e {{#crossLink "EventFacade"}}{{/crossLink}}
      An Event Facade object with the following attribute-specific properties added:
      • prevVal Any
        The value of the attribute, prior to it being set.
      • newVal Any
        The value the attribute is to be set to.
      • attrName {{#crossLink "String"}}{{/crossLink}}
        The name of the attribute being set.
      • subAttrName {{#crossLink "String"}}{{/crossLink}}
        If setting a property within the attribute's value, the name of the sub-attribute property being set.
    {{/if}} {{#example}}

    Example:

    {{{.}}}
    {{/example}}
    ================================================ FILE: extras/yuidoc-theme-topheman/partials/classes.handlebars ================================================

    {{name}}

    {{#if uses}}
    Uses
      {{#uses}}
    • {{.}}
    • {{/uses}}
    {{/if}} {{#if extends}}
    Extends {{#crossLink extends}}{{/crossLink}}
    {{/if}} {{#if foundAt}} {{/if}} {{#if module}} {{#if submodule}} Module: {{#crossLinkModule submodule}}{{/crossLinkModule}}
    Parent Module: {{#crossLinkModule module}}{{/crossLinkModule}} {{else}} Module: {{#crossLinkModule module}}{{/crossLinkModule}} {{/if}} {{/if}} {{#if since}}

    Available since {{since}}

    {{/if}} {{#if static}}

    static

    {{/if}}
    {{#if deprecated}}

    {{#if deprecationMessage}} Deprecated: {{deprecationMessage}} {{else}} This class is deprecated. {{/if}}

    {{/if}}

    Summary

    {{{classDescription}}}
    {{#is_constructor}}

    Constructor

    {{>method}}
    {{/is_constructor}}

    Item Index

    {{#if methods}}

    Methods

      {{#methods}}
    • {{name}} {{#if static}} static {{/if}} {{#if deprecated}} deprecated {{/if}}
    • {{/methods}}
    {{/if}} {{#if properties}}

    Properties

      {{#properties}}
    • {{name}} {{#if static}} static {{/if}} {{#if deprecated}} deprecated {{/if}}
    • {{/properties}}
    {{/if}} {{#if attrs}}

    Attributes

    {{/if}} {{#if events}}

    Events

      {{#events}}
    • {{name}} {{#if static}} static {{/if}} {{#if deprecated}} deprecated {{/if}}
    • {{/events}}
    {{/if}}
    {{#if methods}}

    Methods

    {{#methods}} {{>method}} {{/methods}}
    {{/if}} {{#if properties}}

    Properties

    {{#properties}} {{>props}} {{/properties}}
    {{/if}} {{#if attrs}}

    Attributes

    {{#attrs}} {{>attrs}} {{/attrs}}
    {{/if}} {{#if events}}

    Events

    {{#events}} {{>events}} {{/events}}
    {{/if}}
    {{> exampleurl }} ================================================ FILE: extras/yuidoc-theme-topheman/partials/events.handlebars ================================================

    {{name}}

    {{#if overwritten_from}}

    Inherited from {{overwritten_from/class}} {{#if foundAt}} but overwritten in {{/if}} {{else}} {{#if extended_from}}

    Inherited from {{extended_from}}: {{else}} {{#providedBy}}

    Provided by the {{.}} module.

    {{/providedBy}}

    {{#if foundAt}} Defined in {{/if}} {{/if}} {{/if}} {{#if foundAt}} `{{{file}}}:{{{line}}}` {{/if}}

    {{#if deprecationMessage}}

    Deprecated: {{deprecationMessage}}

    {{/if}} {{#if since}}

    Available since {{since}}

    {{/if}}

    Syntax

    {{name}}

    {{#crossLink type}}{{/crossLink}} {{#if deprecated}} deprecated {{/if}} {{#if access}} {{access}} {{/if}} {{#if final}} final {{/if}} {{#if static}} static {{/if}}

    Summary

    {{{eventDescription}}}
    {{#if params}}

    Event Payload:

      {{#params}}
    • {{#if optional}} [{{name}}{{#if optdefault}}={{optdefault}}{{/if}}] {{#crossLink type}}{{/crossLink}} optional {{else}} {{name}} {{#crossLink type}}{{/crossLink}} {{/if}} {{#if multiple}} Multiple {{/if}}
      {{{description}}}
      {{#if props}}
        {{#props}}
      • {{#if optional}} [{{name}}{{#if optdefault}}={{optdefault}}{{/if}}] {{#crossLink type}}{{/crossLink}} optional {{else}} {{name}} {{#crossLink type}}{{/crossLink}} {{/if}}
        {{{description}}}
        {{#if props}}
          {{#props}}
        • {{name}} {{#crossLink type}}{{/crossLink}}
          {{{description}}}
        • {{/props}}
        {{/if}}
      • {{/props}}
      {{/if}}
    • {{/params}}
    {{/if}} {{#example}}

    Example:

    {{{.}}}
    {{/example}} {{> exampleurl }}
    ================================================ FILE: extras/yuidoc-theme-topheman/partials/exampleurl.handlebars ================================================ {{#if exampleIframe }}

    Live example:

    {{{ exampleIframe }}}
    {{/if}} ================================================ FILE: extras/yuidoc-theme-topheman/partials/files.handlebars ================================================

    File: {{fileName}}

    {{fileData}}
        
    ================================================ FILE: extras/yuidoc-theme-topheman/partials/index.handlebars ================================================

    Welcome

    This doc was generated from {{projectName}} source code with yuidoc. Start here.

    This is only the generated doc for the basic ES6 app I developed for ES6/JSPM boilerplate.
    You'll want to refer to the github repo to find out about the whole workflow.

    Checkout topheman/vanilla-es6-jspm on github (README, FAQ, Wiki).

    Note: If you have a better solution than YUIDoc for generating docs on ES6 code base, please let me know!

    ================================================ FILE: extras/yuidoc-theme-topheman/partials/method.handlebars ================================================

    {{name}}

    {{#if overwritten_from}}

    Inherited from {{overwritten_from/class}} {{#if foundAt}} but overwritten in {{/if}} {{else}} {{#if extended_from}}

    Inherited from {{extended_from}}: {{else}} {{#providedBy}}

    Provided by the {{.}} module.

    {{/providedBy}}

    {{#if foundAt}} Defined in {{/if}} {{/if}} {{/if}} {{#if foundAt}} `{{{file}}}:{{{line}}}` {{/if}}

    {{#if deprecationMessage}}

    Deprecated: {{deprecationMessage}}

    {{/if}} {{#if since}}

    Available since {{since}}

    {{/if}}

    Syntax

    {{name}}

    {{#if params}}
    (
      {{#params}}
    • {{#if optional}} [{{name}}{{#if optdefault}}={{optdefault}}{{/if}}] {{else}} {{name}} {{/if}}
    • {{/params}}
    )
    {{else}} () {{/if}} {{#if return}} {{#crossLink returnType}}{{/crossLink}} {{/if}} {{#if deprecated}} deprecated {{/if}} {{#if access}} {{access}} {{/if}} {{#if final}} final {{/if}} {{#if static}} static {{/if}} {{#if chainable}} chainable {{/if}} {{#if async}} async {{/if}}

    Summary

    {{{methodDescription}}}
    {{#if params}}

    Parameters:

      {{#params}}
    • {{#if optional}} [{{name}}{{#if optdefault}}={{optdefault}}{{/if}}] {{#crossLink type}}{{/crossLink}} optional {{else}} {{name}} {{#crossLink type}}{{/crossLink}} {{/if}} {{#if multiple}} multiple {{/if}}
      {{{description}}}
      {{#if props}}
        {{#props}}
      • {{#if optional}} [{{name}}{{#if optdefault}}={{optdefault}}{{/if}}] {{#crossLink type}}{{/crossLink}} optional {{else}} {{name}} {{#crossLink type}}{{/crossLink}} {{/if}}
        {{{description}}}
        {{#if props}}
          {{#props}}
        • {{#if optional}} [{{name}}{{#if optdefault}}={{optdefault}}{{/if}}] {{#crossLink type}}{{/crossLink}} optional {{else}} {{name}} {{#crossLink type}}{{/crossLink}} {{/if}}
          {{{description}}}
        • {{/props}}
        {{/if}}
      • {{/props}}
      {{/if}}
    • {{/params}}
    {{/if}} {{#return}}

    Returns:

    {{#if type}} {{#crossLink type}}{{/crossLink}}: {{/if}} {{#if description}}
    {{{description}}}
    {{/if}}
    {{/return}} {{#example}}

    Example:

    {{{.}}}
    {{/example}} {{> exampleurl }}
    ================================================ FILE: extras/yuidoc-theme-topheman/partials/module.handlebars ================================================

    {{displayName}} Module

    {{#extra}} {{#selleck}} User Guide & Examples {{/selleck}} {{/extra}} {{#if requires}}
    Requires
      {{#requires}}
    • {{#crossLinkModule .}}{{/crossLinkModule}}
    • {{/requires}}
    {{/if}} {{#if foundAt}} {{/if}} {{#if since}}

    Available since {{since}}

    {{/if}}
    {{#if deprecated}}

    {{#if deprecationMessage}} Deprecated: {{deprecationMessage}} {{else}} This module is deprecated. {{/if}}

    {{/if}}

    Summary

    {{{moduleDescription}}}
    {{#example}}

    Example:

    {{{.}}}
    {{/example}}
    {{#if moduleClasses}}

    This module provides the following classes:

    {{/if}}
    {{#if subModules}}

    This module is a rollup of the following modules:

    {{/if}}
    ================================================ FILE: extras/yuidoc-theme-topheman/partials/options.handlebars ================================================
    Show:
    ================================================ FILE: extras/yuidoc-theme-topheman/partials/props.handlebars ================================================

    {{name}}

    {{#if overwritten_from}}

    Inherited from {{overwritten_from/class}} {{#if foundAt}} but overwritten in {{/if}} {{else}} {{#if extended_from}}

    Inherited from {{extended_from}}: {{else}} {{#providedBy}}

    Provided by the {{.}} module.

    {{/providedBy}}

    {{#if foundAt}} Defined in {{/if}} {{/if}} {{/if}} {{#if foundAt}} `{{{file}}}:{{{line}}}` {{/if}}

    {{#if deprecationMessage}}

    Deprecated: {{deprecationMessage}}

    {{/if}} {{#if since}}

    Available since {{since}}

    {{/if}}

    Syntax

    {{name}}

    {{#crossLink type}}{{/crossLink}} {{#if deprecated}} deprecated {{/if}} {{#if access}} {{access}} {{/if}} {{#if final}} final {{/if}} {{#if static}} static {{/if}}

    Summary

    {{{propertyDescription}}}
    {{#if default}}

    Default: {{default}}

    {{/if}} {{#if subprops}}

    Sub-properties:

      {{#subprops}}
    • {{#if optional}} [{{name}}{{#if optdefault}}={{optdefault}}{{/if}}] {{#crossLink type}}{{/crossLink}} optional {{else}} {{name}} {{#crossLink type}}{{/crossLink}} {{/if}}
      {{{description}}}
      {{#if subprops}}
        {{#subprops}}
      • {{#if optional}} [{{name}}{{#if optdefault}}={{optdefault}}{{/if}}] {{#crossLink type}}{{/crossLink}} optional {{else}} {{name}} {{#crossLink type}}{{/crossLink}} {{/if}}
        {{{description}}}
      • {{/subprops}}
      {{/if}}
    • {{/subprops}}
    {{/if}} {{#example}}

    Example:

    {{{.}}}
    {{/example}} {{> exampleurl }}
    ================================================ FILE: extras/yuidoc-theme-topheman/partials/sidebar.handlebars ================================================

    APIs

    ================================================ FILE: extras/yuidoc-theme-topheman/theme.json ================================================ { "yuiGridsUrl": "http://yui.yahooapis.com/3.9.1/build/cssgrids/cssgrids-min.css", "yuiSeedUrl": "http://yui.yahooapis.com/combo?3.9.1/build/yui/yui-min.js" } ================================================ FILE: gulp/const.js ================================================ 'use strict'; import util from 'gulp-util'; import moment from 'moment'; import pkg from '../package.json'; import gitRev from 'git-rev-sync'; import {ENV} from './utils.js'; var infos = { file: '', pkg: pkg, today: moment(new Date()).format('DD/MM/YYYY'), year: new Date().toISOString().substr(0, 4), gitRevisionShort: gitRev.short(), gitRevisionLong: gitRev.long(), urlToCommit: null }; //retrieve and reformat repo url from package.json if (typeof(pkg.repository) === 'string') { infos.urlToCommit = pkg.repository; } else if (typeof(pkg.repository.url) === 'string') { infos.urlToCommit = pkg.repository.url; } //check that there is a git repo specified in package.json & it is a github one if (infos.urlToCommit !== null && /^https:\/\/github.com/.test(infos.urlToCommit)) { infos.urlToCommit = infos.urlToCommit.replace(/.git$/, '/tree/' + infos.gitRevisionLong);//remove the .git at the end } var tpl = [ '', '<%= pkg.name %>', '', '<%= pkg.description %>', '', '@version v<%= pkg.version %> - <%= today %>', '@revision #<%= gitRevisionShort %><% if (urlToCommit !== null) { %> - <%= urlToCommit %><% } %>', '@author <%= (pkg.author && pkg.author.name) ? pkg.author.name : pkg.author %>', '@copyright <%= year %>(c) <%= (pkg.author && pkg.author.name) ? pkg.author.name : pkg.author %>', '@license <%= pkg.license %>' ]; if(ENV === 'test'){ tpl = [].concat(tpl, '', 'THIS IS A TEST VERSION', 'This version is not meant for production but for testing purpose only' ); } tpl = tpl.join('\n * '); /** * The banner is the comment that is placed at the top of our compiled * source files. It is first processed as a Gulp template, where the `<%=` * pairs are evaluated based on this very configuration object. */ export const BANNER = util.template( '/**' + tpl + '\n */\n', infos); /** * This banner is meant to be put in the html file, at the end */ export const BANNER_HTML = util.template( '\n', infos); ================================================ FILE: gulp/paths.js ================================================ 'use strict'; import path from 'path'; const root = path.dirname(__dirname);//needed so that imports could co-exist with requires (on some edge cases) const paths = { gulpfile: `${root}/gulpfile.js`, /** * This is a collection of file patterns that refer to our app code (the * stuff in `src/`). These file paths are used in the configuration of * build tasks. * * - 'styles' contains all project css styles * - 'images' contains all project images * - 'fonts' contains all project fonts * - 'scripts' contains all project javascript except config-env.js and unit test files * - 'html' contains main html files * - 'templates' contains all project html templates */ app: { basePath: `${root}/src/`, styles: `${root}/src/styles/**/*.scss`, fonts: [ `${root}/src/fonts/**/*.{eot,svg,ttf,woff}`, `${root}/jspm_packages/**/*.{eot,svg,ttf,woff}`, ], images: `${root}/src/images/**/*.{png,gif,jpg,jpeg}`, scripts: [`${root}/src/app/**/*.js`], html: `${root}/src/index.html`, templates: `${root}/src/app/**/*.html` }, config: { karma: `${root}/karma.conf.js`, e2e: `${root}/protractor.config.js`, jspm: `${root}/jspm.config.js` }, /** * The 'tmp' folder is where our html templates are compiled to JavaScript during * the build process and then they are concatenating with all other js files and * copy to 'dist' folder. */ tmp: { basePath: `${root}/.tmp/`, styles: `${root}/.tmp/styles/`, scripts: `${root}/.tmp/scripts/`, config: { basePath: `${root}/.tmp/config/`, jspm: `${root}/.tmp/config/jspm.config.js` } }, build: { basePath: `${root}/build/`, dist: { basePath: `${root}/build/dist/`, fonts: `${root}/build/dist/fonts/`, images: `${root}/build/dist/images/`, styles: `${root}/build/dist/styles/`, scripts: `${root}/build/dist/scripts/`, docs: `${root}/build/dist/docs/` }, docs: `${root}/build/docs/` }, test: { basePath: `${root}/test/`, config: { jspmOverride: `${root}/test/jspm.override.json` }, unit: `${root}/test/unit/**/*.js`, fixtures: `${root}/test/fixtures/**/*.html`, e2e: `${root}/test/e2e/**/*.js`, stubs: `${root}/test/stubs/**/*.js` } }; export default paths; ================================================ FILE: gulp/tasks/build.js ================================================ 'use strict'; import del from 'del'; import gulp from 'gulp'; import util from 'gulp-util'; import uglify from 'gulp-uglify'; import bytediff from 'gulp-bytediff'; import size from 'gulp-size'; import minifyCss from 'gulp-minify-css'; import minifyHtml from 'gulp-minify-html'; import rev from 'gulp-rev'; import header from 'gulp-header'; import footer from 'gulp-footer'; import usemin from 'gulp-usemin'; import inject from 'gulp-inject'; import runSequence from 'run-sequence'; import {BANNER, BANNER_HTML} from '../const'; import {LOG, COLORS, WITH_DOCS} from '../utils'; import paths from '../paths'; //============================================= // UTILS FUNCTIONS //============================================= /** * Format a number as a percentage * @param {Number} num Number to format as a percent * @param {Number} precision Precision of the decimal * @return {String} Formatted percentage */ function formatPercent(num, precision) { return (num * 100).toFixed(precision); } /** * Formatter for bytediff to display the size changes after processing * @param {Object} data - byte data * @return {String} Difference in bytes, formatted */ function bytediffFormatter(data) { const difference = (data.savings > 0) ? ' smaller.' : ' larger.'; return COLORS.yellow(data.fileName + ' went from ' + (data.startSize / 1000).toFixed(2) + ' kB to ' + (data.endSize / 1000).toFixed(2) + ' kB and is ' + formatPercent(1 - data.percent, 2) + '%' + difference); } //============================================= // TASKS //============================================= /** * The 'clean' task delete 'build/dist' and '.tmp' directories. * But keeps build/dist/.git (if you git init this folder to deploy via git) */ gulp.task('clean', (cb) => { const files = [ paths.build.dist.basePath + '*', '!' + paths.build.dist.basePath + '.git*', paths.tmp.basePath ]; LOG('Cleaning: ' + COLORS.blue(files)); return del(files, cb); }); /** * Copies assets at the root of `src` to the `build/dist` folder, such as : * - favicon files * - 404.html file */ gulp.task('extras', () => { return gulp.src([paths.app.basePath + '*.{ico,png,txt}', paths.app.basePath + '404.html']) .pipe(gulp.dest(paths.build.dist.basePath)); }); /** * This task generates doc to `build/docs` and copies it to `build/dist/docs` * It only does it if run with correct flag: `gulp build --with-docs` * * If no flag, does nothing. */ gulp.task('extras-docs', (cb) => { if(WITH_DOCS){ runSequence( ['generate-docs'], ['copy-generated-docs'], (err) => { if (err) { let exitCode = 3; LOG('[ERROR] gulp build task failed (docs generation step)', err); LOG('[FAIL] gulp build task failed (docs generation step) - exiting with code ' + exitCode); return process.exit(exitCode); } else { return cb(); } } ); } else{ return cb(); } }); /** * The 'compile' task compile all js, css and html files. * * 1. it inject bundle into `index.html` * 2. css - minify, add revision number, add banner header * js - minify, add revision number, add banner header * html - minify */ gulp.task('compile', ['htmlhint', 'sass', 'bundle'], () => { return gulp.src(paths.app.html) .pipe(inject(gulp.src(paths.tmp.scripts + 'app.bootstrap.build.js', {read: false}), { starttag: '' })) .pipe(inject(gulp.src(paths.app.basePath + 'analytics.snippet.html'), { starttag: '', transform: (filePath, file) => { // return file contents as string return file.contents.toString('utf8'); } })) .pipe(usemin({ css: [ bytediff.start(), minifyCss({keepSpecialComments: 0}), bytediff.stop(bytediffFormatter), rev(), header(BANNER) ], js: [ bytediff.start(), uglify(), bytediff.stop(bytediffFormatter), rev(), header(BANNER) ], html: [ bytediff.start(), minifyHtml({empty: true}), footer(BANNER_HTML), bytediff.stop(bytediffFormatter) ] })) .pipe(gulp.dest(paths.build.dist.basePath)) .pipe(size({title: 'compile', showFiles: true})); }); /** * The 'build' task gets app ready for deployment by processing files * and put them into `build/dist` directory ready for deployment. * * Added callback to manage errors and exit with a clean exit code if task fails * (needed for CI tools such as Travis) */ gulp.task('build', (cb) => { runSequence( ['clean'], ['compile', 'extras', 'images'], ['extras-docs'], (err) => { if (err) { let exitCode = 2; LOG('[ERROR] gulp build task failed', err); LOG('[FAIL] gulp build task failed - exiting with code ' + exitCode); return process.exit(exitCode); } else { return cb(); } } ); }); ================================================ FILE: gulp/tasks/docs.js ================================================ 'use strict'; import gulp from 'gulp'; import {exec} from 'child_process'; import paths from '../paths'; /** * This task simply encapsulate the npm task `npm run yuidoc` * so that it could be integrated in the `gulp build --with-docs` workflow */ gulp.task('generate-docs', (cb) => { return exec('npm run yuidoc', (error, stdout, stderr) => { console.log('stdout: ' + stdout); console.log('stderr: ' + stderr); if (error !== null) { console.log('exec error: ' + error); } cb(); }); }); /** * This task simply copies generated docs from `build/docs` to `build/dist/docs` * `build/docs` must have been generated before */ gulp.task('copy-generated-docs', () => { return gulp.src(paths.build.docs + '**/*') .pipe(gulp.dest(paths.build.dist.docs)); }); ================================================ FILE: gulp/tasks/html.js ================================================ 'use strict'; import gulp from 'gulp'; import htmlhint from 'gulp-htmlhint'; import paths from '../paths'; import {ENV} from '../utils.js'; /** * The 'htmlhint' task defines the rules of our hinter as well as which files we * should check. It helps to detect errors and potential problems in our * HTML code. * * Can also be executed in test env, like the jshint task * * @return {Stream} */ gulp.task('htmlhint', () => { var src; switch (ENV) { case 'test': src = [].concat(paths.app.html, paths.app.templates, paths.test.fixtures); break; case 'dev': default: src = [].concat(paths.app.html, paths.app.templates); break; } return gulp.src(src) .pipe(htmlhint('.htmlhintrc')) .pipe(htmlhint.reporter()) .pipe(htmlhint.failReporter()); }); ================================================ FILE: gulp/tasks/images.js ================================================ 'use strict'; import gulp from 'gulp'; import cache from 'gulp-cache'; import size from 'gulp-size'; import imagemin from 'gulp-imagemin'; import paths from '../paths'; /** * The 'images' task minifies and copies images to `build/dist` directory. */ gulp.task('images', () => { return gulp.src(paths.app.images) .pipe(cache(imagemin({ progressive: true, interlaced: true }))) .pipe(gulp.dest(paths.build.dist.images)) .pipe(size({title: 'images'})); }); ================================================ FILE: gulp/tasks/scripts.js ================================================ 'use strict'; import util from 'gulp-util'; import gulp from 'gulp'; import jshint from 'gulp-jshint'; import cache from 'gulp-cache'; import footer from 'gulp-footer'; import gulpif from 'gulp-if'; import {LOG,COLORS,ENV} from '../utils.js'; import paths from '../paths'; /** * The 'jshint' task defines the rules of our hinter as well as which files * we should check. It helps to detect errors and potential problems in our * JavaScript code. * * It can be launched in test env (which will also hint all test related tasks) */ gulp.task('jshint', () => { var src; switch (ENV) { case 'test': src = [].concat(paths.app.scripts, paths.gulpfile, paths.config.karma, paths.config.e2e, paths.test.stubs, paths.test.unit, paths.test.e2e); break; case 'dev': default: src = [].concat(paths.app.scripts, paths.gulpfile, paths.config.karma, paths.config.e2e); break; } return gulp.src(src) .pipe(jshint('.jshintrc')) .pipe(jshint.reporter('jshint-stylish')) .pipe(jshint.reporter('fail')); }); gulp.task('jspmconfig', () => { var injection; if(ENV === 'test'){ var jspmOverride = require(paths.test.config.jspmOverride); LOG(COLORS.yellow('[INFOS] Using jspm.override.json:')) var injection = "System.config("+JSON.stringify(jspmOverride)+")"; LOG(COLORS.yellow(injection)); } return gulp.src(paths.config.jspm) .pipe(gulpif(ENV === 'test', footer(injection))) .pipe(gulp.dest(paths.tmp.config.basePath)); }); /** * Create JS production bundle. * * If the flag `--env test` was passed, make a production bundle based on the test configuration */ gulp.task('bundle', ['jshint', 'jspmconfig'], (cb) => { const Builder = require('systemjs-builder'); const builder = new Builder(); const inputPath = 'src/app/bootstrap'; const outputFile = paths.tmp.scripts + 'app.bootstrap.build.js'; const outputOptions = {sourceMaps: true, config: {sourceRoot: paths.tmp.scripts}}; builder.loadConfig(paths.tmp.config.jspm) .then(() => { builder.buildStatic(inputPath, outputFile, outputOptions) .then(() => { return cb(); }) .catch((ex) => { cb(new Error(ex)); }); }); }); /** * gulp-cache is used in some tasks to save time * Though, when developing/debugging the gulp part, the cache can mess with the streams * This will clear it. */ gulp.task('cache-clean', (done) => { return cache.clearAll(done); }); ================================================ FILE: gulp/tasks/server.js ================================================ 'use strict'; import gulp from 'gulp'; import util from 'gulp-util'; import modRewrite from 'connect-modrewrite'; import browserSync from 'browser-sync'; import jspmOverride from '../../test/jspm.override.json'; import {COLORS,LOG,PORT,OPEN,ENV} from '../utils.js'; import path from '../paths'; function infos(env) { LOG(COLORS.yellow('[INFOS] call `gulp serve --env ' + env + ' --port 9002` (for example) to launch on another port')); LOG(COLORS.yellow('[INFOS] call `gulp serve --env ' + env + ' --disable-watch` if you don\'t need it')); LOG(COLORS.yellow('[INFOS] call `gulp serve --env ' + env + ' --open false` if you don\'t want the browser to open')); } //============================================= // PROXY CONFIGURATION //============================================= /** * Launches a browserSync server * Injecting `env` as a global variable + overriding jspm.config.js if in test * @param env dev/test/dist * @param baseDir * @param [options] * @param [options.files='default'] * @param [options.browser='default'] * @param [options.port=PORT] */ function startBrowserSync(env, baseDir, options = {}) { env = env.toLowerCase(); options.browser = options.browser === undefined ? 'default' : options.browser; options.files = options.files === undefined ? 'default' : options.files; options.port = options.port === undefined ? PORT : options.port; options.open = options.open === undefined ? true : options.open; var config = { open: options.open, files: options.files, port: options.port, notify: false, server: { baseDir: baseDir, middleware: [ //proxyMiddleware, //modRewrite(['!\\.\\w+$ /index.html [L]']), // require for HTML5 mode function (req, res, next) { //don't cache the entry point (since there are some inline '); injectBrowserSync.push(bsHtmlSnippet); injectBrowserSync = injectBrowserSync.join('\n'); config.rewriteRules = [ { match: //g, fn: function (match) { return injectBrowserSync; } } ]; } browserSync(config); } //============================================= // TASKS //============================================= /** * The 'serve' task. run `gulp serve --env dev/dist/test` * * Pass the env dev/dist/test via the --env flag * * - dev: runs a dev server with livereload/watch * - test: runs a test server with livereload/watch (over the test also) * - dist: serves the `build/dist` folder */ var gulpServeDependencyTasks; switch(ENV){ case 'dist': gulpServeDependencyTasks = []; break; case 'test': case 'dev': gulpServeDependencyTasks = ['sass', 'watch']; break; } gulp.task('serve', gulpServeDependencyTasks, () => { infos(ENV); switch(ENV){ case 'dist': startBrowserSync('dist', ['./build/dist'], {port: PORT, open: OPEN}); break; case 'test': startBrowserSync('test', ['.tmp', 'src', 'jspm_packages', './'], {port: PORT, open: OPEN}); break; case 'dev': startBrowserSync('dev', ['.tmp', 'src', 'jspm_packages', './'], {port: PORT, open: OPEN}); break; } }); ================================================ FILE: gulp/tasks/styles.js ================================================ 'use strict'; import gulp from 'gulp'; import util from 'gulp-util'; import sass from 'gulp-sass'; import changed from 'gulp-changed'; import sourcemaps from 'gulp-sourcemaps'; import autoprefixer from 'gulp-autoprefixer'; import concat from 'gulp-concat'; import filter from 'gulp-filter'; import browserSync from 'browser-sync'; import paths from '../paths'; /** * Compile SASS files into the main.css. */ gulp.task('sass', () => { return gulp.src(paths.app.styles) .pipe(changed(paths.tmp.styles, {extension: '.scss'})) .pipe(sourcemaps.init()) .pipe(sass({style: 'compressed'}).on('error', sass.logError)) .pipe(autoprefixer('last 2 version')) .pipe(concat('main.css')) .pipe(sourcemaps.write('../maps')) .pipe(gulp.dest(paths.tmp.styles)) .pipe(filter('**/*.css')) // Filtering stream to only css files .pipe(browserSync.reload({stream: true})); }); ================================================ FILE: gulp/tasks/watch.js ================================================ 'use strict'; import gulp from 'gulp'; import util from 'gulp-util'; import browserSync from 'browser-sync'; import {COLORS,LOG,ENV} from '../utils.js'; import paths from '../paths'; import {DISABLE_WATCH} from '../utils.js'; /** * The 'watch' task set up the checks to see if any of the files listed below * change, and then to execute the listed tasks when they do. * * According to the env it's launched to, it won't watch the same files (in test, will watch more files) */ gulp.task('watch', () => { if (DISABLE_WATCH) { LOG(COLORS.yellow('[INFOS] watch is disabled')); return; } // Watch images and fonts files gulp.watch([paths.app.images, paths.app.fonts], [browserSync.reload]); // Watch css files gulp.watch(paths.app.styles, ['sass', browserSync.reload]);//if takes to long, take a look at https://github.com/Browsersync/recipes/tree/master/recipes/gulp.task.sequence // Create the html list of file to watch according to env if (ENV !== 'dist') { var htmlFileList; switch (ENV) { case 'test': htmlFileList = [].concat(paths.app.html, paths.app.templates, paths.test.fixtures); break; case 'dev': htmlFileList = [].concat(paths.app.html, paths.app.templates); break; } // Create the js list of file to watch according to env var jsFileList; switch (ENV) { case 'test': jsFileList = [].concat(paths.app.scripts, paths.gulpfile, paths.config.karma, paths.config.e2e, paths.test.stubs, paths.test.unit, paths.test.e2e); break; case 'dev': jsFileList = [].concat(paths.app.scripts, paths.gulpfile); break; } // Watch html files gulp.watch(htmlFileList, ['htmlhint', browserSync.reload]); // Watch js files gulp.watch(jsFileList, ['jshint', browserSync.reload]); } }); ================================================ FILE: gulp/utils.js ================================================ 'use strict'; import util from 'gulp-util'; export const LOG = util.log; export const COLORS = util.colors; import pkg from '../package.json'; //launch your task with `--port 9002` for example export const PORT = util.env.port || (pkg.config ? (pkg.config.port ? pkg.config.port : null) : null) || 9000; //launch your task with `--open` `--open false` for example export const OPEN = util.env.open === 'false' ? false : true; //launch your task with `--disable-watch` for example export const DISABLE_WATCH = util.env['disable-watch']; // if no --env flag, environment variable ENV is taken, // if none of them is set, 'dev' is set by default // if you pass by --env flag, it will be reflected in process.env.ENV var environment = ((util.env.env === true ? 'dev' : util.env.env) || process.env.ENV || 'dev').toLowerCase(); if (['dev', 'dist', 'test'].indexOf(environment) === -1) { throw new Error('--env flag only accepts dev/dist/test') } if (!process.env.ENV) { LOG(COLORS.yellow('[INFOS] Setting process.env.ENV=' + environment)); process.env.ENV = environment; } LOG(COLORS.yellow('### Running in ' + environment + ' ###')); export const ENV = environment; export const WITH_DOCS = util.env['with-docs'] || process.env.WITH_DOCS; if(WITH_DOCS){ LOG(COLORS.yellow('### Running in --with-docs mode ###')); } /** * @warn this is still in progress * * @todo add config.runUnitTestsOnChange: true in package.json * @todo add npm run test-unit to the watch tasks * * For grunt serve task - Unit tests will be run on file changes if: * In package.json, config.runUnitTestsOnChange = true (turning it to false won't run the tests on change) * You can override this behavior by passing the flag : * * `--run-unit-tests-on-change` (to run the unit tests) * * `--run-unit-tests-on-change false` (not to run the unit tests) */ var runUnitTestsOnChange = (pkg.config ? (pkg.config.runUnitTestsOnChange !== undefined ? pkg.config.runUnitTestsOnChange : true) : true); if (util.env['run-unit-tests-on-change'] !== undefined) { runUnitTestsOnChange = util.env['run-unit-tests-on-change'] === 'false' ? false : util.env['run-unit-tests-on-change']; } export const RUN_UNIT_TESTS_ON_RELOAD = runUnitTestsOnChange; ================================================ FILE: gulpfile.js ================================================ 'use strict'; //inspired by the gulpfile.js from https://github.com/martinmicunda/employee-scheduling-ui //use babel transpiler for ES6 files in node without needing --harmony nor a gulpfile.babel.js require('babel/register'); // require all tasks require('require-dir')('./gulp/tasks', {recurse: true}); require('gulp').task('default', ['serve']); ================================================ FILE: jspm.config.js ================================================ System.config({ baseURL: "./", defaultJSExtensions: true, transpiler: "babel", babelOptions: { "optional": [ "runtime", "optimisation.modules.system" ] }, paths: { "components/*": "src/app/components/*", "services/*": "src/app/services/*", "github:*": "jspm_packages/github/*", "npm:*": "jspm_packages/npm/*" }, map: { "babel": "npm:babel-core@5.8.34", "babel-runtime": "npm:babel-runtime@5.8.34", "bootstrap-sass": "npm:bootstrap-sass@3.3.5", "clean-css": "npm:clean-css@3.4.3", "core-js": "npm:core-js@1.2.6", "css": "github:systemjs/plugin-css@0.1.17", "fetch-polyfill": "npm:fetch-polyfill@0.8.1", "text": "github:systemjs/plugin-text@0.0.2", "github:jspm/nodelibs-assert@0.1.0": { "assert": "npm:assert@1.3.0" }, "github:jspm/nodelibs-buffer@0.1.0": { "buffer": "npm:buffer@3.5.0" }, "github:jspm/nodelibs-events@0.1.1": { "events": "npm:events@1.0.2" }, "github:jspm/nodelibs-http@1.7.1": { "Base64": "npm:Base64@0.2.1", "events": "github:jspm/nodelibs-events@0.1.1", "inherits": "npm:inherits@2.0.1", "stream": "github:jspm/nodelibs-stream@0.1.0", "url": "github:jspm/nodelibs-url@0.1.0", "util": "github:jspm/nodelibs-util@0.1.0" }, "github:jspm/nodelibs-https@0.1.0": { "https-browserify": "npm:https-browserify@0.0.0" }, "github:jspm/nodelibs-os@0.1.0": { "os-browserify": "npm:os-browserify@0.1.2" }, "github:jspm/nodelibs-path@0.1.0": { "path-browserify": "npm:path-browserify@0.0.0" }, "github:jspm/nodelibs-process@0.1.2": { "process": "npm:process@0.11.2" }, "github:jspm/nodelibs-stream@0.1.0": { "stream-browserify": "npm:stream-browserify@1.0.0" }, "github:jspm/nodelibs-url@0.1.0": { "url": "npm:url@0.10.3" }, "github:jspm/nodelibs-util@0.1.0": { "util": "npm:util@0.10.3" }, "npm:amdefine@1.0.0": { "fs": "github:jspm/nodelibs-fs@0.1.2", "module": "github:jspm/nodelibs-module@0.1.0", "path": "github:jspm/nodelibs-path@0.1.0", "process": "github:jspm/nodelibs-process@0.1.2" }, "npm:assert@1.3.0": { "util": "npm:util@0.10.3" }, "npm:babel-runtime@5.8.34": { "process": "github:jspm/nodelibs-process@0.1.2" }, "npm:buffer@3.5.0": { "base64-js": "npm:base64-js@0.0.8", "ieee754": "npm:ieee754@1.1.6", "is-array": "npm:is-array@1.0.1" }, "npm:clean-css@3.4.3": { "buffer": "github:jspm/nodelibs-buffer@0.1.0", "commander": "npm:commander@2.8.1", "fs": "github:jspm/nodelibs-fs@0.1.2", "http": "github:jspm/nodelibs-http@1.7.1", "https": "github:jspm/nodelibs-https@0.1.0", "os": "github:jspm/nodelibs-os@0.1.0", "path": "github:jspm/nodelibs-path@0.1.0", "process": "github:jspm/nodelibs-process@0.1.2", "source-map": "npm:source-map@0.4.4", "url": "github:jspm/nodelibs-url@0.1.0", "util": "github:jspm/nodelibs-util@0.1.0" }, "npm:commander@2.8.1": { "child_process": "github:jspm/nodelibs-child_process@0.1.0", "events": "github:jspm/nodelibs-events@0.1.1", "fs": "github:jspm/nodelibs-fs@0.1.2", "graceful-readlink": "npm:graceful-readlink@1.0.1", "path": "github:jspm/nodelibs-path@0.1.0", "process": "github:jspm/nodelibs-process@0.1.2" }, "npm:core-js@1.2.6": { "fs": "github:jspm/nodelibs-fs@0.1.2", "path": "github:jspm/nodelibs-path@0.1.0", "process": "github:jspm/nodelibs-process@0.1.2", "systemjs-json": "github:systemjs/plugin-json@0.1.0" }, "npm:core-util-is@1.0.1": { "buffer": "github:jspm/nodelibs-buffer@0.1.0" }, "npm:graceful-readlink@1.0.1": { "fs": "github:jspm/nodelibs-fs@0.1.2" }, "npm:https-browserify@0.0.0": { "http": "github:jspm/nodelibs-http@1.7.1" }, "npm:inherits@2.0.1": { "util": "github:jspm/nodelibs-util@0.1.0" }, "npm:os-browserify@0.1.2": { "os": "github:jspm/nodelibs-os@0.1.0" }, "npm:path-browserify@0.0.0": { "process": "github:jspm/nodelibs-process@0.1.2" }, "npm:process@0.11.2": { "assert": "github:jspm/nodelibs-assert@0.1.0" }, "npm:punycode@1.3.2": { "process": "github:jspm/nodelibs-process@0.1.2" }, "npm:readable-stream@1.1.13": { "buffer": "github:jspm/nodelibs-buffer@0.1.0", "core-util-is": "npm:core-util-is@1.0.1", "events": "github:jspm/nodelibs-events@0.1.1", "inherits": "npm:inherits@2.0.1", "isarray": "npm:isarray@0.0.1", "process": "github:jspm/nodelibs-process@0.1.2", "stream-browserify": "npm:stream-browserify@1.0.0", "string_decoder": "npm:string_decoder@0.10.31" }, "npm:source-map@0.4.4": { "amdefine": "npm:amdefine@1.0.0", "process": "github:jspm/nodelibs-process@0.1.2" }, "npm:stream-browserify@1.0.0": { "events": "github:jspm/nodelibs-events@0.1.1", "inherits": "npm:inherits@2.0.1", "readable-stream": "npm:readable-stream@1.1.13" }, "npm:string_decoder@0.10.31": { "buffer": "github:jspm/nodelibs-buffer@0.1.0" }, "npm:url@0.10.3": { "assert": "github:jspm/nodelibs-assert@0.1.0", "punycode": "npm:punycode@1.3.2", "querystring": "npm:querystring@0.2.0", "util": "github:jspm/nodelibs-util@0.1.0" }, "npm:util@0.10.3": { "inherits": "npm:inherits@2.0.1", "process": "github:jspm/nodelibs-process@0.1.2" } } }); ================================================ FILE: karma.conf.js ================================================ var argv = require('minimist')(process.argv.slice(2)); var jspmOverride = require('./test/jspm.override.json'); var _ = require('lodash'); var colors = require('colors'); var clientCaptureConsole = true; if (typeof(argv['capture-console']) !== 'undefined') { if (argv['capture-console'] !== 'true' && argv['capture-console'] !== 'false') { console.error('[ERROR][Invalid Argument] Flag --capture-console only accepts true or false'.red); console.error('[ERROR][Invalid Argument] Exiting'.red); process.exit(9);// "Invalid Argument" - see exit code list : https://github.com/joyent/node/blob/master/doc/api/process.markdown#exit-code } else { clientCaptureConsole = argv['capture-console'] === 'false' ? false : true; } } if (clientCaptureConsole === false) { console.log('[INFO] console.*() statements are removed to have a clearer report.'.yellow); console.log('[INFO] If you want to access them, launch npm run test-unit'.yellow); } /** * karma-jspm passes this config to jspm via karma * It contains some karma-jspm specific attributes such as config, loadFiles, serveFiles * It can also accept any jspm configuration you'd like to overload, such as paths or map * * The `test/jspm.override.json` file (containing the systemjs config for test used in `gulp serve:test`) * will be merged into the following karmaJspmConfig. * * This way, the file `test/jspm.override.json` is shared between karma and gulp. */ var karmaJspmConfig = { config: 'jspm.config.js', loadFiles: [ 'node_modules/phantomjs-polyfill/bind-polyfill.js',//necessary for PhantomJS (doesn't have Function.bind) 'test/unit/spec/**/*.js', 'test/fixtures/**/*.html' ], serveFiles: [ 'src/app/**/*.js', 'src/app/**/*.html', 'src/app/**/*.css', 'test/stubs/**/*' ] }; //merging the config karmaJspmConfig = _.assign(karmaJspmConfig, jspmOverride); module.exports = function (config) { 'use strict'; config.set({ //basePath: '',//don't override basePath, use proxies frameworks: ['jspm', 'jasmine'], // list of files / patterns to load in the browser files: [], // specific karma-jspm config (with the merged configs from `test/jspm.override.json`) jspm: karmaJspmConfig, proxies: { '/src/': '/base/src/', '/test/': '/base/test/', '/jspm_packages/': '/base/jspm_packages/', '/node_modules/phantomjs-polyfill/': '/base/node_modules/phantomjs-polyfill/' }, reporters: ['spec'], preprocessors: { 'test/fixtures/**/*.html': ['html2js'] }, port: 9876, colors: true, autoWatch: false, singleRun: true, // level of logging // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG logLevel: config.LOG_INFO, client: { captureConsole: clientCaptureConsole }, browsers: ['PhantomJS'], plugins: [ 'karma-jspm', 'karma-chrome-launcher', 'karma-firefox-launcher', 'karma-safari-launcher', 'karma-phantomjs-launcher', 'karma-jasmine', 'karma-spec-reporter', 'karma-html2js-preprocessor' ] }); }; ================================================ FILE: package.json ================================================ { "name": "vanilla-es6-jspm", "version": "0.10.3", "description": "Seed project for ES6 / jspm based apps with full production workflow", "main": "index.js", "scripts": { "start": "./node_modules/.bin/gulp serve", "test": "./node_modules/.bin/gulp jshint --env test && ./node_modules/.bin/gulp htmlhint --env test && ./node_modules/.bin/karma start --single-run --browsers PhantomJS --capture-console false", "test-unit": "./node_modules/.bin/karma start", "postinstall": "./node_modules/.bin/jspm install && npm run webdriver-manager-update", "test-build": "./bin/test-build.sh", "test-e2e": "./node_modules/.bin/protractor protractor.config.js", "forever-start-test": "echo \"Launching server (test mode) ...\" && ./node_modules/.bin/forever start ./test/forever.gulp.serve.test.json", "forever-stop-test": "echo \"Stopping script (test mode) ...\" && ./node_modules/.bin/forever stop gulp.serve.test", "forever-start-dist": "echo \"Launching server (dist mode) ...\" && ./node_modules/.bin/forever start ./test/forever.gulp.serve.dist.json", "forever-stop-dist": "echo \"Stopping script (dist mode) ...\" && ./node_modules/.bin/forever stop gulp.serve.dist", "forever-stopall": "echo \"Stopping all script ...\" && ./node_modules/.bin/forever stopall", "forever-list": "./node_modules/.bin/forever list", "test-e2e-standalone": "npm run forever-start-test && sleep 4 && npm run test-e2e && npm run forever-stop-test", "webdriver-manager-update": "./node_modules/.bin/webdriver-manager update", "yuidoc": "./node_modules/.bin/yuidoc", "build-prod": "gulp build --with-docs" }, "pre-commit": [ "test" ], "pre-push": [ "test-build" ], "repository": { "type": "git", "url": "https://github.com/topheman/vanilla-es6-jspm.git" }, "bugs": { "url": "https://github.com/topheman/vanilla-es6-jspm/issues" }, "keywords": [ "ES6", "jspm", "gulp" ], "author": "Christophe Rosset", "license": "MIT", "jspm": { "configFile": "jspm.config.js", "dependencies": { "bootstrap-sass": "npm:bootstrap-sass@3.3.5", "clean-css": "npm:clean-css@^3.3.9", "css": "github:systemjs/plugin-css@^0.1.17", "fetch-polyfill": "npm:fetch-polyfill@^0.8.1", "text": "github:systemjs/plugin-text@^0.0.2" }, "devDependencies": { "babel": "npm:babel-core@^5.8.24", "babel-runtime": "npm:babel-runtime@^5.8.24", "core-js": "npm:core-js@^1.1.4" } }, "devDependencies": { "babel": "^5.8.12", "browser-sync": "^2.11.1", "chromedriver": "^2.27.3", "colors": "^1.1.2", "connect-modrewrite": "^0.8.5", "del": "^2.0.1", "forever": "^0.15.1", "git-rev-sync": "^1.3.0", "gulp": "^3.9.1", "gulp-autoprefixer": "^3.0.1", "gulp-bytediff": "^1.0.0", "gulp-cache": "^0.4.2", "gulp-changed": "^1.2.1", "gulp-concat": "^2.5.2", "gulp-filter": "^3.0.0", "gulp-footer": "^1.0.5", "gulp-header": "^1.2.2", "gulp-htmlhint": "^0.3.1", "gulp-if": "^2.0.0", "gulp-imagemin": "^2.3.0", "gulp-inject": "^3.0.0", "gulp-jshint": "^2.0.0", "gulp-load-plugins": "^1.0.0-rc.1", "gulp-minify-css": "^1.2.0", "gulp-minify-html": "^1.0.4", "gulp-rev": "^7.0.0", "gulp-sass": "^2.2.0", "gulp-size": "^2.0.0", "gulp-sourcemaps": "^1.5.2", "gulp-uglify": "^1.5.2", "gulp-usemin": "^0.3.20", "gulp-util": "^3.0.5", "jasmine-core": "^2.3.4", "jasmine-spec-reporter": "^2.4.0", "jshint": "^2.8.0", "jshint-stylish": "^2.0.0", "jspm": "^0.16.27", "karma": "^0.13.3", "karma-chrome-launcher": "^0.2.0", "karma-firefox-launcher": "^0.1.6", "karma-html2js-preprocessor": "^0.1.0", "karma-jasmine": "^0.3.7", "karma-jspm": "^2.0.1-beta.1", "karma-phantomjs-launcher": "^1.0.0", "karma-safari-launcher": "^0.1.1", "karma-spec-reporter": "0.0.24", "lodash": "^3.10.1", "minimist": "^1.1.3", "moment": "^2.11.2", "phantomjs-polyfill": "0.0.1", "phantomjs-prebuilt": "^2.1.4", "pre-commit": "^1.1.1", "pre-push": "^0.1.1", "protractor": "^3.1.1", "require-dir": "^0.3.0", "run-sequence": "^1.1.2", "systemjs-builder": "^0.15.7", "yuidocjs": "^0.10.0" }, "yuidoc": { "options": { "linkNatives": "true", "attributesEmit": "false", "selleck": "false", "paths": [ "./src/app" ], "outdir": "./build/docs", "themedir": "./extras/yuidoc-theme-topheman" } }, "config": { "port": 9000, "isAngular": false }, "engines": { "node": ">=4.2.x", "npm": ">=2.0.0" } } ================================================ FILE: protractor.config.js ================================================ 'use strict'; require('babel/register');//write test in es6 var SpecReporter = require('jasmine-spec-reporter'); var pkg = require('./package.json'); /** * This constant is retrieved from the package.json in the `config.isAngular` * That way, you can specify globally if the site is Anuglar or not */ var IS_ANGULAR = (pkg.config ? (pkg.config.isAngular ? pkg.config.isAngular : false) : false); /** * The default port on which the test will be run is the one specified in package.json under config.port * * To overload this port, just pass the flag --port * * Use the global goToUrl(relativeUrl) helper (which will use what ever port you defined) * */ var argv = require('minimist')(process.argv.slice(2)); var PORT = argv.port || (pkg.config ? (pkg.config.port ? pkg.config.port : null) : null) || 9000; var BASE_URL = argv['base-url'] || 'http://localhost'; var WITH_DOCS = argv['with-docs'] || process.env.WITH_DOCS; console.log('[INFOS] Testing on ' + BASE_URL + ':' + PORT); var specs = [ 'test/e2e/spec/**/*.spec.js' ]; if(WITH_DOCS){ console.log('[INFOS] Running in --with-docs mode (will run the test that will check for /docs to make sure they were correctly generated)'); specs.push('test/e2e/spec/docs.specs.conditional.js'); } var config = { framework: 'jasmine2', specs: specs, chromeDriver: './node_modules/chromedriver/lib/chromedriver/chromedriver', onPrepare: function () { browser.ignoreSynchronization = !IS_ANGULAR; /** * Set on/off angular synchronisation of protractor * Use the beforeEachIsAngular helper in `test/e2e/utils.js` * @param flag */ global.isAngularSite = function (flag) { browser.ignoreSynchronization = !flag; }; /** * Helper to use instead of directly `browser.get` so that you don't bother about the port * baseUrl and port are optional and can be overriden globally when launching protractor * with the flags --base-url and --port * @param relativeUrl * @param baseUrl * @param port */ global.goToUrl = function (relativeUrl, baseUrl, port) { baseUrl = typeof baseUrl === 'undefined' ? BASE_URL : baseUrl; port = typeof port === 'undefined' ? PORT : port; browser.get(baseUrl + ':' + port + relativeUrl); }; jasmine.getEnv().addReporter(new SpecReporter()); } }; if (process.env.TRAVIS) { config.sauceUser = process.env.SAUCE_USERNAME; config.sauceKey = process.env.SAUCE_ACCESS_KEY; config.capabilities = { 'name': 'vanilla-es6-jspm E2E node v' + process.env.TRAVIS_NODE_VERSION, 'browserName': 'chrome', 'seleniumVersion': '2.48.2', 'chromedriverVersion': '2.20', 'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER, 'build': process.env.TRAVIS_BUILD_NUMBER }; } module.exports.config = exports.config = config; ================================================ FILE: src/404.html ================================================ Page Not Found

    Page Not Found

    Sorry, but the page you were trying to view does not exist.

    Back to homepage

    ================================================ FILE: src/analytics.snippet.html ================================================ ================================================ FILE: src/app/bootstrap.js ================================================ /** * @module src/app */ //import bootstrap from 'bootstrap'; //import $ from 'jquery'; import 'fetch-polyfill'; import main from './main.js'; /** * This is the entry point of the whole application. * * Example: * * ``` * System.import('app/bootstrap.js').catch(console.error.bind(console)); * ``` * @class bootstrap * @main src/app */ export default class bootstrap { /** * Launches the whole app. * @method init * @static */ static init() { console.log('bootstrap.init !!!'); main.init(); } } bootstrap.init(); ================================================ FILE: src/app/components/Component/Component.js ================================================ /** * @module src/app */ export default class Component { /** * This class is meant to be extended. * It provides the very basic methods to manage WebComponent-like (very simple version) objects. * * You may override the init method according to your needs * @namespace components.Component * @class Component * @constructor * @param {HTMLElement|String} domNode Can be an domNode or a domNode id * @param {String} template */ constructor(domNode, template) { if (typeof domNode === 'string') { let nodeId = domNode; domNode = document.getElementById(domNode); if (domNode === null) { throw new Error(`No element found under #${nodeId}`); } } if (domNode instanceof HTMLElement) { this.domNode = domNode; this.domNode.innerHTML = template; } else { throw new Error('Invalid param, must be an HTMLElement or a string of the id of one'); } } /** * Once you instanciated your object, call this method to init it. * * This method is meant to be overridden. * @method init * @chainable * @return {components.Component.Component} */ init() { return this; } /** * Displays block your component. * @method show * @chainable * @return {components.Component.Component} */ show() { this.domNode.style.display = "block"; return this; } /** * Displays none your component. * @method hide * @chainable * @return {components.Component.Component} */ hide() { this.domNode.style.display = "none"; return this; } } ================================================ FILE: src/app/components/Geolocation/Geolocation.html ================================================
    Geolocation example

      ================================================ FILE: src/app/components/Geolocation/Geolocation.js ================================================ /** * @module src/app */ import Component from '../Component/Component.js'; import Spinner from '../Spinner/Spinner.js'; import template from './Geolocation.html!text'; import {geolocation} from 'services/geolocation/geolocation.js'; export default class Geolocation extends Component { /** * Creates a full Geolocation component with its whole logic encapsulated: * * * button to launch a geolocation request * * spinner while requesting (based on {{#crossLink "Spinner"}}Spinner{{/crossLink}}) * * display of the result * * Example: * * ``` * var myGeolocation = (new Geolocation('geolocation')).init(); * ``` * @namespace components.Geolocation * @class Geolocation * @extends components.Component.Component * @constructor * @param {HTMLElement|String} domNode Can be an domNode or a domNode id */ constructor(domNode) { super(domNode, template); } /** * Inits the Geolocation component, adding all its specific logic. * @method init * @chainable * @return {components.Geolocation.Geolocation} */ init() { this.spinner = (new Spinner(this.domNode.querySelector('.spinner'))).init().hide(); let geolocationInfosBloc = this.domNode.querySelector('.geolocation-infos'); this.domNode.querySelector('.geolocation-button').addEventListener('click', () => { geolocationInfosBloc.style.display = "none"; this.spinner.show(); geolocation() .then((result) => { console.log(result); let tpl = `
    • City: ${result.city}
    • Country: ${result.country_name}
    • Region: ${result.region_name}
    • Time zone: ${result.time_zone}
    • Region: ${result.region_name}
    • Latitude : ${result.latitude} / Longitude: ${result.longitude}
    • Timeout : ${result.timeout}ms
    • `; this.spinner.hide(); geolocationInfosBloc.style.display = "block"; geolocationInfosBloc.innerHTML = tpl; }) .catch(e => { console.error(e); geolocationInfosBloc.innerHTML = '
    • An error occured
    • '; this.spinner.hide(); geolocationInfosBloc.style.display = "block"; }); }, false); return this; } } ================================================ FILE: src/app/components/Spinner/Spinner.css ================================================ /** from http://cssload.net/ */ #circularG { position: relative; width: 64px; height: 64px } .circularG { position: absolute; background-color: #900000; width: 15px; height: 15px; -moz-border-radius: 10px; -moz-animation-name: bounce_circularG; -moz-animation-duration: 0.64s; -moz-animation-iteration-count: infinite; -moz-animation-direction: normal; -webkit-border-radius: 10px; -webkit-animation-name: bounce_circularG; -webkit-animation-duration: 0.64s; -webkit-animation-iteration-count: infinite; -webkit-animation-direction: normal; -ms-border-radius: 10px; -ms-animation-name: bounce_circularG; -ms-animation-duration: 0.64s; -ms-animation-iteration-count: infinite; -ms-animation-direction: normal; -o-border-radius: 10px; -o-animation-name: bounce_circularG; -o-animation-duration: 0.64s; -o-animation-iteration-count: infinite; -o-animation-direction: normal; border-radius: 10px; animation-name: bounce_circularG; animation-duration: 0.64s; animation-iteration-count: infinite; animation-direction: normal; } #circularG_1 { left: 0; top: 25px; -moz-animation-delay: 0.24s; -webkit-animation-delay: 0.24s; -ms-animation-delay: 0.24s; -o-animation-delay: 0.24s; animation-delay: 0.24s; } #circularG_2 { left: 7px; top: 7px; -moz-animation-delay: 0.32s; -webkit-animation-delay: 0.32s; -ms-animation-delay: 0.32s; -o-animation-delay: 0.32s; animation-delay: 0.32s; } #circularG_3 { top: 0; left: 25px; -moz-animation-delay: 0.4s; -webkit-animation-delay: 0.4s; -ms-animation-delay: 0.4s; -o-animation-delay: 0.4s; animation-delay: 0.4s; } #circularG_4 { right: 7px; top: 7px; -moz-animation-delay: 0.48s; -webkit-animation-delay: 0.48s; -ms-animation-delay: 0.48s; -o-animation-delay: 0.48s; animation-delay: 0.48s; } #circularG_5 { right: 0; top: 25px; -moz-animation-delay: 0.56s; -webkit-animation-delay: 0.56s; -ms-animation-delay: 0.56s; -o-animation-delay: 0.56s; animation-delay: 0.56s; } #circularG_6 { right: 7px; bottom: 7px; -moz-animation-delay: 0.64s; -webkit-animation-delay: 0.64s; -ms-animation-delay: 0.64s; -o-animation-delay: 0.64s; animation-delay: 0.64s; } #circularG_7 { left: 25px; bottom: 0; -moz-animation-delay: 0.72s; -webkit-animation-delay: 0.72s; -ms-animation-delay: 0.72s; -o-animation-delay: 0.72s; animation-delay: 0.72s; } #circularG_8 { left: 7px; bottom: 7px; -moz-animation-delay: 0.8s; -webkit-animation-delay: 0.8s; -ms-animation-delay: 0.8s; -o-animation-delay: 0.8s; animation-delay: 0.8s; } @-moz-keyframes bounce_circularG { 0% { -moz-transform: scale(1) } 100% { -moz-transform: scale(.3) } } @-webkit-keyframes bounce_circularG { 0% { -webkit-transform: scale(1) } 100% { -webkit-transform: scale(.3) } } @-ms-keyframes bounce_circularG { 0% { -ms-transform: scale(1) } 100% { -ms-transform: scale(.3) } } @-o-keyframes bounce_circularG { 0% { -o-transform: scale(1) } 100% { -o-transform: scale(.3) } } @keyframes bounce_circularG { 0% { transform: scale(1) } 100% { transform: scale(.3) } } ================================================ FILE: src/app/components/Spinner/Spinner.html ================================================
      ================================================ FILE: src/app/components/Spinner/Spinner.js ================================================ /** * @module src/app */ import Component from '../Component/Component.js'; import template from './Spinner.html!text'; import stylesheet from './Spinner.css!'; export default class Spinner extends Component { /** * Creates a spinner on any domNode. * * Since it inherits from {{#crossLink "components.Component.Component"}}Component{{/crossLink}}, * you have access to {{#crossLink "components.Component.Component/show"}}show{{/crossLink}} and {{#crossLink "components.Component.Component/hide"}}hide{{/crossLink}} methods. * * Example: * * ``` * var mySpinner = (new Spinner(document.getElementById('spinner'))).init().hide(); * ``` * @namespace components.Spinner * @class Spinner * @extends components.Component.Component * @constructor * @param {HTMLElement|String} domNode Can be an domNode or a domNode id */ constructor(domNode) { super(domNode, template); } } ================================================ FILE: src/app/main.js ================================================ /** * @module src/app */ import Geolocation from './components/Geolocation/Geolocation.js'; /** * This class is called by the app entry point. * It holds the logic initiation. * @class main */ export default class main { /** * Inits the whole logic of the app * @method init * @static */ static init() { this.initGeolocation(); } /** * Inits the {{#crossLink "components.Geolocation.Geolocation"}}Geolocation{{/crossLink}} component * @method initGeolocation * @static */ static initGeolocation() { (new Geolocation('geolocation')).init(); } } ================================================ FILE: src/app/services/geolocation/geolocation.js ================================================ /** * @module src/app */ /** * @namespace services.geolocation * @class geolocation */ /** * Very simple geolocation method based on https://freegeoip.net free geoip service * (may not be the most accurate nor the most fast or available, but it's only to have some xhr in the code example). * * Example: * * ``` * geolocation() * .then((result) => { * console.log(result);//there you are * }) * .catch(e => { * console.error(e); * }); * ``` * * @method geolocation * @param {String} [ipAddress] You can pass a specific IP address to geoloc if you want. * @return {Promise} */ export function geolocation(ipAddress = "") { "use strict"; let url = `https://freegeoip.net/json/${ipAddress}`; return new Promise((resolve, reject) => { var time = new Date(); fetch(url) .then(res => res.json()) .then(json => { json.timeout = (new Date()).getTime() - time; return resolve(json); }) .catch(e => reject(e)); }); } ================================================ FILE: src/index.html ================================================ vanilla-es6-jspm

      vanilla-es6-jspm

      Welcome

      vanillaJS/ES6/jspm project boilerplate, with the following features:

      • jspm/ES6 integration
      • gulp tasks (written in ES6) for :
        • watch / livereload
        • sass
        • jshint / htmlhint
        • build
      • unit tests (written in ES6) with karma
      • e2e tests (written in ES6) with protractor
      • continuous integration
        • Travis CI
        • SauceLabs
      • automated documentation generation

      Learn more on github ...

      ================================================ FILE: src/styles/_footer.scss ================================================ @media only screen and (max-width: $grid-float-breakpoint) { footer { font-size: 90%; } } ================================================ FILE: src/styles/_header.scss ================================================ @import "_networks-headers"; header { margin-bottom: 15px; } header h1 { margin-top: 5px; } @media only screen and (max-width: $grid-float-breakpoint) { header h1 { margin-top: 10px; font-size: 26px; } } ================================================ FILE: src/styles/_index.scss ================================================ @media only screen and (max-width: $grid-float-breakpoint) { .index-page .jumbotron img.pull-right { width: 25%; margin-top: $grid-gutter-width/2; //pading between columns divided by half //display: block; //float: none !important; //margin: 0 auto; } .index-page .jumbotron ul { padding-left: 20px; } } .index-page .jumbotron { @media screen and (max-width: $grid-float-breakpoint) { padding-top: ($jumbotron-padding * 0); padding-bottom: ($jumbotron-padding * 0); h1, .h1 { font-size: $jumbotron-heading-font-size*0.5; } } } ================================================ FILE: src/styles/_networks-headers.scss ================================================ /** github logo from my other sites**/ /** networks header */ .site-networks { position: absolute; right: 20px; top: 10px; margin: 0; padding: 0; } ul.site-networks { list-style: none; text-align: center; padding: 0px 0px 10px 0px; } ul.site-networks li { position: relative; display: inline-block; vertical-align: middle; margin-left: 15px; } ul.site-networks li a { display: block; width: 32px; height: 32px; text-decoration: none; padding-top: 0px; -webkit-transition: all 0.5s; -moz-transition: all 0.5s; -ms-transition: all 0.5s; -o-transition: all 0.5s; transition: all 0.5s; } ul.site-networks li a span.icon { position: absolute; display: block; width: 32px; height: 32px; -webkit-transition: all 0.5s; -moz-transition: all 0.5s; -ms-transition: all 0.5s; -o-transition: all 0.5s; transition: all 0.5s; } ul.site-networks li a span.desc { display: none; } ul.site-networks li a:hover { } ul.site-networks li a:hover span.icon { left: 0px; -webkit-transform: rotate(360deg); -moz-transform: rotate(360deg); -ms-transform: rotate(360deg); -o-transform: rotate(360deg); transform: rotate(360deg); } /** since logos are included with the css in base64, we don't bother about pixel ratio media query (everybody gets the retina version)*/ ul.site-networks li.twitter a span.icon { background-image: url(../images/twitter-retina.png); background-size: 32px 32px; } ul.site-networks li.github a span.icon { background-image: url(../images/github-retina.png); background-size: 32px 32px; } @media only screen and (max-width: $grid-float-breakpoint) { ul.site-networks { right: 15px; } ul.site-networks li { margin-left: 0px; } } ================================================ FILE: src/styles/_variables.scss ================================================ $brand-primary: #900000; $input-border-focus: $brand-primary; ================================================ FILE: src/styles/main.scss ================================================ @import "_variables"; @import "../../jspm_packages/npm/bootstrap-sass@3.3.5/assets/stylesheets/bootstrap"; @import "_header"; @import "_index"; @import "_footer"; ================================================ FILE: test/e2e/spec/docs.specs.conditional.js ================================================ 'use strict'; /** * This test is only run when the --with-docs flag is active : `npm run test-e2e -- --with-docs` * or when WITH_DOCS env variable is declared at true * * It's only meant to be run against a built version (also built with the flag --with-docs or WITH_DOCS env variable declared) * * This is not a documented feature. This is more to ensure on travis that not only: * - the doc generates correctly without failing * - but it also generates a correct output */ // before each 'it' of the following describe: describe('Docs home page /docs', () => { beforeEach(() => { //go to page (if not yet) goToUrl('/docs'); }); it('should have a title', () => { expect(browser.getTitle()).toEqual('vanilla-es6-jspm'); }); it('should have a title in the header', () => { expect(element(by.css('h1.blue-main-title')).getText()).toEqual('vanilla-es6-jspm'); }); }); ================================================ FILE: test/e2e/spec/home.spec.js ================================================ 'use strict'; describe('Home page', () => { // before each 'it' of the following describe: beforeEach(() => { //go to page (if not yet) goToUrl('/'); //wait for the component to be loaded browser.driver.wait(() => { //will stop wait when the element is displayed - (~like a DOM Ready for e2e tests) - timeout is only here to error in case it takes too long return browser.driver.findElement(by.id('geolocation')).isDisplayed(); }, 4000); }); it('should have a title', () => { expect(browser.getTitle()).toEqual('vanilla-es6-jspm'); }); it('geolocation widget should be present', () => { expect(element(by.id('geolocation')).isPresent()).toBeTruthy(); }); it('results should show on "click to launch geolocation"', () => { browser.findElement(by.css('button.geolocation-button')).click().then(() => { expect(element(by.css('.geolocation-infos')).isDisplayed()).toBeTruthy(); }); }); it('results should be right on "click to launch geolocation"', () => { browser.findElement(by.css('button.geolocation-button')).click().then(() => { expect(element.all(by.css('.geolocation-infos li')).first().getText()).toEqual('City: Hello World !!!'); }); }); }); ================================================ FILE: test/e2e/utils.js ================================================ 'use strict'; /** * When you use protractor in a non angular way, you have to tell it not to wait * by specifying browser.ignoreSynchronization = false in the onPrepare of the protractor config. * * If you have a website completly angular or completly non-angular, just use the config.isAngular in package.json * * If you want to be able to switch the behavior of protractor, use the following helper: * - in the protractor config, a global method is exposed: isAngularSite * - this method switches on/off the browser.ignoreSynchronization flag * You have to do that for each beforeEach. * * This utility is here to simplify the boilerplate. * * Example: beforeEachIsAngular(false) or beforeEachIsAngular(false, () => { console.log('toto'); }) * @param args * @returns {*} */ export function beforeEachIsAngular(...args) { /* jshint undef: false, unused: true */ // case with beforeEachIsAngular(() => {}, false); if(typeof args[1] === 'function' && typeof args[0] === 'boolean'){ return beforeEach(() => { isAngularSite(args[0]); args[1](); }); } // case with beforeEachIsAngular(() => {}); else if (typeof args[0] === 'function') { return beforeEach(args[0]); } // case with beforeEachIsAngular(false); else if (typeof args[0] === 'boolean'){ return beforeEach(() => { isAngularSite(args[0]); }); } else{ throw new Error('beforeEachIsAngular: wrong parameters - (boolean, fn) or (fn) or (boolean)'); } } ================================================ FILE: test/fixtures/bs.snippet.html ================================================ ================================================ FILE: test/fixtures/components/simple-wrapper.html ================================================
      ================================================ FILE: test/forever.gulp.serve.dist.json ================================================ { "uid": "gulp.serve.dist", "append": true, "watch": false, "script": "./node_modules/.bin/gulp", "args": [ "serve", "--env", "dist", "--disable-watch", "--open", false ] } ================================================ FILE: test/forever.gulp.serve.test.json ================================================ { "uid": "gulp.serve.test", "append": true, "watch": false, "script": "./node_modules/.bin/gulp", "args": [ "serve", "--env", "test", "--disable-watch", "--open", false ] } ================================================ FILE: test/jspm.override.json ================================================ { "paths": { "services/geolocation/geolocation.js": "test/stubs/app/services/geolocation/geolocation.js" } } ================================================ FILE: test/stubs/app/services/geolocation/geolocation.js ================================================ console.log('[STUB]', 'LOADED', 'geolocation'); import mock from './geolocation.json!text'; export function geolocation() { "use strict"; return new Promise(function (resolve, reject) { var result = JSON.parse(mock); result.timeout = 0; setTimeout(function () { console.log('[STUB]', 'CALL', 'geolocation', result); resolve(result); }, result.timeout); }); } ================================================ FILE: test/stubs/app/services/geolocation/geolocation.json ================================================ { "ip": "127.0.0.1", "country_code": "FR", "country_name": "France", "region_code": "", "region_name": "", "city": "Hello World !!!", "zip_code": "", "time_zone": "Europe/Paris", "latitude": 48.86, "longitude": 2.35, "metro_code": 0 } ================================================ FILE: test/unit/spec/components/Component.spec.js ================================================ 'use strict'; import Component from 'components/Component/Component.js'; describe('components/Component/Component.js', function () { let component; let htmlElement; beforeEach(()=> { htmlElement = document.createElement('div'); component = new Component(htmlElement); }); it('.init method should be defined', ()=> { expect(component.init).not.toBe(undefined); }); it('.init() should return this', () => { expect(component.init() instanceof Component).toBe(true); }); it('.show() should display block', () => { component.show(); expect(component.domNode.style.display).toEqual('block'); }); it('.hide() should display none', () => { component.hide(); expect(component.domNode.style.display).toEqual('none'); }); }); ================================================ FILE: test/unit/spec/components/Geolocation.spec.js ================================================ 'use strict'; import Geolocation from 'components/Geolocation/Geolocation.js'; describe('components/Component/Geolocation.js', () => { const WRAPPER_ID = 'simple-wrapper'; var geolocationComponent = null; /** * Inject a simple fixture before each test */ beforeEach(() => { document.body.innerHTML = window.__html__['test/fixtures/components/simple-wrapper.html']; }); afterEach(() => { document.body.innerHTML = null; geolocationComponent = null; }); describe('DOM testing - component init', () => { it('should import the html fixture to the DOM', () => { expect(document.getElementById(WRAPPER_ID)).toBeDefined(); }); it('component should init from html id', () => { geolocationComponent = (new Geolocation(WRAPPER_ID)).init(); expect(document.querySelector('.panel-heading').innerHTML).toEqual('Geolocation example'); }); it('component should init from html node', () => { var node = document.getElementById(WRAPPER_ID); geolocationComponent = (new Geolocation(node)).init(); expect(document.querySelector('.panel-heading').innerHTML).toEqual('Geolocation example'); }); it('click on button should show spinner while waiting', () => { geolocationComponent = (new Geolocation(WRAPPER_ID)).init(); document.querySelector('button.geolocation-button').click(); expect(document.querySelector('.spinner').style.display).toEqual('block'); }); }); /** * Inject a simple fixture + init the component before each test */ beforeEach(() => { document.body.innerHTML = window.__html__['test/fixtures/components/simple-wrapper.html']; geolocationComponent = (new Geolocation(WRAPPER_ID)).init(); }); afterEach(() => { document.body.innerHTML = null; geolocationComponent = null; }); describe('DOM testing - click button [more e2e]', () => { it('should hide spinner when results ready', (done) => { document.querySelector('button.geolocation-button').click(); setTimeout(() => { expect(document.querySelector('.spinner').style.display).toEqual('none'); done(); },50);//sad but PhantomJS friendly ... }); it('should show results when ready', (done) => { document.querySelector('button.geolocation-button').click(); setTimeout(() => { expect(document.querySelector('ul.geolocation-infos li').innerHTML).toEqual('City: Hello World !!!'); done(); },50);//sad but PhantomJS friendly ... }); }); }); ================================================ FILE: test/unit/spec/components/Spinner.spec.js ================================================ 'use strict'; import Spinner from 'components/Spinner/Spinner.js'; describe('components/Spinner/Spinner.js', function () { let spinner; let htmlElement; let expectedInnerHTML = `
      `; beforeEach(()=> { htmlElement = document.createElement('div'); spinner = new Spinner(htmlElement); }); it('.init method should be defined', ()=> { expect(spinner.init).not.toBe(undefined); }); it('.init() should return this', () => { expect(spinner.init() instanceof Spinner).toBe(true); }); it('.domNode.innerHTML should be correct', () => { expect(spinner.domNode.innerHTML).toEqual(expectedInnerHTML); }); }); ================================================ FILE: test/unit/spec/services/geolocation.spec.js ================================================ 'use strict'; //in test mode, this is the stub which will be retrieved import {geolocation} from 'services/geolocation/geolocation.js'; describe('services/geolocation/geolocation.js (stub version)', function () { let result = null; beforeEach((done) => { geolocation().then(function (res) { result = res; done(); }); }); afterEach(() => { result = null; }); it('should make an async call', function (done) { expect(result).not.toBe(null); done(); }); // those values are from `/test/unit/stubs/app/services/geolocation/geolocation.json` it('object result values should be correct', function (done) { expect(result).toEqual(jasmine.objectContaining({ "ip": "127.0.0.1", "country_code": "FR", "country_name": "France", "region_code": "", "region_name": "", "city": "Hello World !!!", "zip_code": "", "time_zone": "Europe/Paris", "latitude": 48.86, "longitude": 2.35, "metro_code": 0, "timeout": 0 })); done(); }); }); ================================================ FILE: test/unit/utils.js ================================================ 'use strict'; /** * @unsused since the MutationObserver shim messes with jasmine async, this utility is not used for the moment * You can see an example at this commit: https://github.com/topheman/vanilla-es6-jspm/commit/32f9923353ed818f03b166102b912a2530ee40b6 * * This helper will listen to DOM changes and fire the callback * It is based on DOM3 MutationObserver * * For PhantomJS and other browser which don't support it a shim is installed : https://github.com/megawac/MutationObserver.js/tree/master * * More infos on https://developer.mozilla.org/fr/docs/Web/API/MutationObserver * * @param {HTMLElement} DOMNode * @param {function} callback */ export function onDOMElementChange(DOMNode, callback) { // select the target node var target = DOMNode; // create an observer instance var observer = new MutationObserver((mutations) => { // don't bother about finding what changed // if something changed -> fire the callback if(mutations.length > 0){ // stop observing before launching callback observer.disconnect(); callback(); } }); // configuration of the observer: var config = { attributes: true, childList: true, characterData: true }; // pass in the target node, as well as the observer options observer.observe(target, config); }