From 399cfc517aaba37921fa35fd007d42140689c075 Mon Sep 17 00:00:00 2001 From: Leonardo Gentile Date: Sat, 1 Apr 2017 18:16:47 +0200 Subject: [PATCH] First commit --- .editorconfig | 21 + .eslintrc | 57 +++ .gitattributes | 15 + .gitignore | 9 + .idea/encodings.xml | 6 + .idea/inspectionProfiles/Project_Default.xml | 18 + .idea/misc.xml | 6 + .idea/mobx-react-router5.iml | 12 + .idea/modules.xml | 8 + .travis.yml | 11 + CHANGELOG.md | 38 ++ CONTRIBUTING.md | 136 ++++++ LICENSE.txt | 21 + README.md | 77 ++++ docs/README.md | 9 + docs/assets/favicon.ico | Bin 0 -> 7406 bytes docs/assets/footer.css | 12 + docs/assets/footer.ejs | 0 docs/assets/header.css | 124 +++++ docs/assets/header.ejs | 31 ++ docs/assets/img/babel.svg | 7 + docs/assets/img/github-icon.svg | 17 + docs/assets/img/hero.svg | 4 + docs/assets/js/onStats.js | 70 +++ docs/assets/main.css | 333 ++++++++++++++ docs/assets/main.ejs | 46 ++ docs/assets/main.js | 33 ++ docs/assets/nav.css | 44 ++ docs/assets/nav.ejs | 20 + docs/assets/robots.txt | 5 + docs/assets/stats.css | 32 ++ docs/assets/stats.ejs | 18 + docs/assets/vendor/highlight.css | 0 docs/assets/vendor/highlight.js | 0 docs/assets/vendor/normalize.css | 424 ++++++++++++++++++ docs/getting-started.md | 57 +++ docs/index.md | 29 ++ docs/recipes/testing-with-mocha-and-jsdom.md | 75 ++++ .../throwing-errors-with-fbjs-invariant.md | 74 +++ package.json | 82 ++++ src/index.js | 7 + src/modules/BaseLink.js | 94 ++++ src/modules/routeNode.js | 56 +++ src/modules/utils.js | 43 ++ src/modules/withRoute.js | 56 +++ test/.eslintrc | 16 + test/GreetingSpec.js | 31 ++ tools/.eslintrc | 12 + tools/build.js | 53 +++ 49 files changed, 2349 insertions(+) create mode 100644 .editorconfig create mode 100644 .eslintrc create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .idea/encodings.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/mobx-react-router5.iml create mode 100644 .idea/modules.xml create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE.txt create mode 100644 README.md create mode 100644 docs/README.md create mode 100644 docs/assets/favicon.ico create mode 100644 docs/assets/footer.css create mode 100644 docs/assets/footer.ejs create mode 100644 docs/assets/header.css create mode 100644 docs/assets/header.ejs create mode 100644 docs/assets/img/babel.svg create mode 100644 docs/assets/img/github-icon.svg create mode 100644 docs/assets/img/hero.svg create mode 100644 docs/assets/js/onStats.js create mode 100644 docs/assets/main.css create mode 100644 docs/assets/main.ejs create mode 100644 docs/assets/main.js create mode 100644 docs/assets/nav.css create mode 100644 docs/assets/nav.ejs create mode 100644 docs/assets/robots.txt create mode 100644 docs/assets/stats.css create mode 100644 docs/assets/stats.ejs create mode 100644 docs/assets/vendor/highlight.css create mode 100644 docs/assets/vendor/highlight.js create mode 100644 docs/assets/vendor/normalize.css create mode 100644 docs/getting-started.md create mode 100644 docs/index.md create mode 100644 docs/recipes/testing-with-mocha-and-jsdom.md create mode 100644 docs/recipes/throwing-errors-with-fbjs-invariant.md create mode 100644 package.json create mode 100644 src/index.js create mode 100644 src/modules/BaseLink.js create mode 100644 src/modules/routeNode.js create mode 100644 src/modules/utils.js create mode 100644 src/modules/withRoute.js create mode 100644 test/.eslintrc create mode 100644 test/GreetingSpec.js create mode 100644 tools/.eslintrc create mode 100644 tools/build.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..8f60fec --- /dev/null +++ b/.editorconfig @@ -0,0 +1,21 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# http://editorconfig.org + +root = true + +[*] + +# Change these settings to your own preference +indent_style = space +indent_size = 2 + +# We recommend you to keep these unchanged +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + + +[*.md] +trim_trailing_whitespace = false diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..4b81621 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,57 @@ +{ + // Parser + "parser": "babel-eslint", + // ECMA Features + "ecmaFeatures": { + "arrowFunctions": true, + "blockBindings": true, + "classes": true, + "defaultParams": true, + "destructuring": true, + "modules": true, + "objectLiteralComputedProperties": true, + "templateStrings": true + }, + "rules": { + // Possible Errors + "no-dupe-args": 2, + "no-dupe-keys": 2, + "no-empty": 2, + "no-func-assign": 2, + "no-inner-declarations": 2, + "no-unreachable": 2, + "no-unexpected-multiline": 2, + // Best practices + "consistent-return": 0, + "curly": [2, "multi-line"], + "eqeqeq": 2, + "no-else-return": 2, + "no-multi-spaces": 0, + // Strict mode + "strict": 0, + // Variables + "no-shadow": 0, + "no-unused-vars": 2, + "no-use-before-define": 0, + // Style + "brace-style": [2, "1tbs"], + "comma-spacing": [2, {"before": false, "after": true}], + "comma-style": [2, "last"], + "consistent-this": [2, "that"], + "lines-around-comment": [2, {"allowBlockStart": true}], + "key-spacing": 0, + "new-parens": 0, + "quotes": [2, "single", "avoid-escape"], + "no-underscore-dangle": 0, + "no-unneeded-ternary": 2, + "semi": 2, + // ES6 + "no-var": 2, + "no-this-before-super": 2, + "object-shorthand": 2, + }, + "env": { + "node": true, + "browser": true + } +} diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6bce4ee --- /dev/null +++ b/.gitattributes @@ -0,0 +1,15 @@ +# Automatically normalize line endings for all text-based files +# http://git-scm.com/docs/gitattributes#_end_of_line_conversion +* text=auto + +# For the following file types, normalize line endings to LF on +# checkin and prevent conversion to CRLF when they are checked out +# (this is required in order to prevent newline related issues like, +# for example, after the build script is run) +.* text eol=lf +*.css text eol=lf +*.ejs text eol=lf +*.js text eol=lf +*.md text eol=lf +*.txt text eol=lf +*.json text eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..95c65a2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +# Include your project-specific ignores in this file +# Read about how to use .gitignore: https://help.github.com/articles/ignoring-files + +coverage +dist +docs/dist +node_modules +npm-debug.log +!/src/modules/BaseLink.js diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..97626ba --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..c3000b2 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,18 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..28a804d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/mobx-react-router5.iml b/.idea/mobx-react-router5.iml new file mode 100644 index 0000000..24643cc --- /dev/null +++ b/.idea/mobx-react-router5.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..d528c90 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..c97d989 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,11 @@ +sudo: false +language: node_js +node_js: + - '6' + - '5' + - '4' +script: + - npm run lint + - npm run test:cover +after_success: + - npm run coveralls diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..8ae2735 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,38 @@ +## Babel Starter Kit Change Log + +All notable changes to this project will be documented in this file. + +### [Unreleased][unreleased] + +- Allow to execute tests in a browser environment (PLANNED) + +### [v1.2.0] - 2016-05-04 + +- Add `tools/build.js` script +- Build source files into `dist` folder +- Update npm modules +- Publish as CommonJS, ES2015 and UMD via [Rollup](http://rollupjs.org/). See `tools/build.js`. + +### [v1.1.2] - 2016-04-03 + +- Add `npm run test:watch` npm script for running tests in watch mode +- Add a recipe: Testing with `mocha` and `jsdom` +- Add a recipe: Throwing errors with FB's `invariant` (`fbjs`) library +- Update `eslint` and `babel-eslint` npm modules to the latest versions +- Update unit test code sample +- Add [CONTRIBUTING.md](CONTRIBUTING.md) and [CHANGELOG.md](CHANGELOG.md) files + +### [v1.1.0] - 2016-03-31 + +- Add code coverage in unit tests with [Istanbul](https://github.com/gotwarlost/istanbul) and [Coveralls](https://coveralls.io/) [#8](https://github.com/kriasoft/babel-starter-kit/pull/8) + +### [v1.0.0] - 2016-03-30 + +- Clean up the code and `package.json` file, update project dependencies +- Integrate [Easystatic](https://easystatic.com) that generates a static site from the `docs/*.md` files + +[unreleased]: https://github.com/kriasoft/babel-starter-kit/compare/v1.2.0...HEAD +[v1.2.0]: https://github.com/kriasoft/babel-starter-kit/compare/v1.1.2...v1.2.0 +[v1.1.2]: https://github.com/kriasoft/babel-starter-kit/compare/v1.1.0...v1.1.2 +[v1.1.0]: https://github.com/kriasoft/babel-starter-kit/compare/v1.0.0...v1.1.0 +[v1.0.0]: https://github.com/kriasoft/babel-starter-kit/compare/v0.1.1...v1.0.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..a067bfd --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,136 @@ +## Contributing to Babel Starter Kit + +♥ [Babel Starter Kit](https://www.kriasoft.com/babel-starter-kit) and want to get involved? Thanks! +There are plenty of ways you can help! + +Please take a moment to review this document in order to make the contribution process easy and +effective for everyone involved. + +Following these guidelines helps to communicate that you respect the time of the developers +managing and developing this open source project. In return, they should reciprocate that respect in +addressing your issue or assessing patches and features. + + +### Using the issue tracker + +The [issue tracker](https://github.com/kriasoft/babel-starter-kit/issues) is the preferred channel +for [bug reports](#bugs), [features requests](#features) and [submitting pull requests](#pull-requests), +but please respect the following restrictions: + +* Please **do not** use the issue tracker for personal support requests. + [Stack Overflow](https://stackoverflow.com/questions/tagged/babel-starter-kit), + [Gitter](https://gitter.im/kriasoft/babel-starter-kit) or + [Codementor](https://www.codementor.io/koistya) are better places to get help. + +* Please **do not** derail or troll issues. Keep the discussion on topic and respect the opinions of + others. + + + +### Bug reports + +A bug is a _demonstrable problem_ that is caused by the code in the repository. Good bug reports are +extremely helpful - thank you! + +Guidelines for bug reports: + +1. **Use the GitHub issue search** — check if the issue has already been reported. + +2. **Check if the issue has been fixed** — try to reproduce it using the latest `master` or + development branch in the repository. + +3. **Isolate the problem** — ideally create a reduced test case and a live example. + +A good bug report shouldn't leave others needing to chase you up for more information. Please try to +be as detailed as possible in your report. What is your environment? What steps will reproduce the +issue? What browser(s) and OS experience the problem? What would you expect to be the outcome? All +these details will help people to fix any potential bugs. + +Example: + +> Short and descriptive example bug report title +> +> A summary of the issue and the browser/OS environment in which it occurs. If suitable, include the +> steps required to reproduce the bug. +> +> 1. This is the first step +> 2. This is the second step +> 3. Further steps, etc. +> +> `` - a link to the reduced test case +> +> Any other information you want to share that is relevant to the issue being reported. This might +> include the lines of code that you have identified as causing the bug, and potential solutions +> (and your opinions on their merits). + + + +## Feature requests + +Feature requests are welcome. But take a moment to find out whether your idea fits with the scope +and aims of the project. It's up to *you* to make a strong case to convince the project's developers +of the merits of this feature. Please provide as much detail and context as possible. + + + +## Pull requests + +Good pull requests - patches, improvements, new features - are a fantastic help. They should remain +focused in scope and avoid containing unrelated commits. + +**Please ask first** before embarking on any significant pull request (e.g. implementing features, +refactoring code, porting to a different language), otherwise you risk spending a lot of time +working on something that the project's developers might not want to merge into the project. + +Please adhere to the coding conventions used throughout a project (indentation, accurate comments, +etc.) and any other requirements (such as test coverage). + +Adhering to the following process is the best way to get your work included in the project: + +1. [Fork](https://help.github.com/articles/fork-a-repo/) the project, clone your fork, and configure + the remotes: + + ```bash + # Clone your fork of the repo into the current directory + git clone https://github.com//babel-starter-kit.git + # Navigate to the newly cloned directory + cd babel-starter-kit + # Assign the original repo to a remote called "upstream" + git remote add upstream https://github.com/kriasoft/babel-starter-kit.git + ``` + +2. If you cloned a while ago, get the latest changes from upstream: + + ```bash + git checkout master + git pull upstream master + ``` + +3. Create a new topic branch (off the main project development branch) to contain your feature, + change, or fix: + + ```bash + git checkout -b + ``` + +4. Commit your changes in logical chunks. Please adhere to these [git commit message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) + or your code is unlikely be merged into the main project. Use Git's [interactive rebase](https://help.github.com/articles/about-git-rebase/) + feature to tidy up your commits before making them public. + +5. Locally merge (or rebase) the upstream development branch into your topic branch: + + ```bash + git pull [--rebase] upstream master + ``` + +6. Push your topic branch up to your fork: + + ```bash + git push origin + ``` + +7. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/) with a clear title + and description. + +**IMPORTANT**: By submitting a patch, you agree to allow the project owners to license your work +under the terms of the [MIT License](LICENSE.txt). diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..6d3b7d6 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,21 @@ + The MIT License + +Copyright (c) 2015-2016 Konstantin Tarkus, Kriasoft LLC. All rights reserved. + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..f6b9bea --- /dev/null +++ b/README.md @@ -0,0 +1,77 @@ + +# mobx-router5 + +## Warning +This is an early work-in-progress. +This is not published on npm yet. + +## Usage + +```javascript +import createRouter from 'router5'; +import loggerPlugin from 'router5/plugins/logger'; +import listenersPlugin from 'router5/plugins/listeners'; +import browserPlugin from 'router5/plugins/browser'; +import routes from './routes'; + +import mobxPlugin from 'mobx-router5/mobxPlugin'; +import RouterStore from 'mobx-router5/RouterStore'; + +// I instantiate it here because we could extend the class before invoking new +const routerStore = new RouterStore(); + +const routerOptions = { + defaultRoute: 'home', + strictQueryParams: true +}; + + +export default function configureRouter(useListenersPlugin = false) { + const router = createRouter(routes, routerOptions) + // Plugins + .usePlugin(loggerPlugin) + .usePlugin(mobxPlugin(routerStore, {storeNavigation: true})) + .usePlugin(browserPlugin({ + useHash: true + })); + + if (useListenersPlugin) { + router.usePlugin(listenersPlugin()); + } + + return router; +} +``` + +## Actions +The routerStore instance expose these actions/handlers automatically invoked by the plugin on transition Start/Success/Error. + +- onTransitionStart(route, previousRoute) +- onTransitionSuccess(route, previousRoute) +- onTransitionError(route, previousRoute, transitionError) + +This ensure that the observables are always up-to-date with the current route: + +- @observable route +- @observable previousRoute +- @observable transitionRoute +- @observable transitionError + +To be called manually (todo) +- clearErrors() + +### Manual actions (optional) +Only available if we pass the option `storeNavigation: true` on plugin creation. + +``` +.usePlugin(mobxPlugin(routerStore, {storeNavigation: true}) +``` + +In this case when the plugin is create it will use the `setRouter` method of the store to pass in the router so that router methods can be used directly. + +- navigateTo(routeName, routeParams = {}, routeOptions = {}) +- cancelTransition() +- canActivate(routeName, true | false) +- canDeactivate(routeName, true | false) + +If you use react and an HOC component like `RouterProvider` to inject the router instance into your components context this is not necessary because you can access the router methods directly. diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..81e8364 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,9 @@ +## Documentation + +* [Overview](index.md) +* [Getting Started](getting-started.md) +* Recipes + * [Testing with mocha and jsdom](recipes/testing-with-mocha-and-jsdom.md) + * [Throwing errors with FB's invariant library](recipes/throwing-errors-with-fbjs-invariant.md) + +See also [www.kriasoft.com/babel-starter-kit](https://www.kriasoft.com/babel-starter-kit/) diff --git a/docs/assets/favicon.ico b/docs/assets/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..977414b74a1bcd3998c7ba5c2f28cb41db4789a2 GIT binary patch literal 7406 zcmeHLcUY6x9)3d@VT26m8(@yMz4OFQKV# zfbhi|VV~0j2~Fo=VCM)yL;}Q1w;=!4bEKa92>Lem;5)e^=jzws>hNF@5{c0HYZ0^g zC~~iT3%zc(FbfDn*uo9Sk$r`3i5W!40p6pgA$0B<=voQkHKGb;ej!LYbQ#(2e?fHY z;9XIT!q0w1$n1J#H9vxmsW}q%oJYZ@Kf};fghKLk$SXxe{chxc@*MWr#YFx$BXCd@2EXyO(9qT)d;JKZ^BR!*;bZ7o z+aT%i`^dWV0EPE|BeJX8-_bvAZEJ&kq1*vq9PMl5m8N6X>X1a(y~xL19ML*W9^!Ok z*PuRf^K4WcpJ6NND^6|~;hAI>hxBXj^Mf@?61$}<4J3;_O5^$e?evxhX!g zOH=+}-%6MpLa35L5Gnp)sHy28lK3w{&lAe-Q@7T=KJv58jz z0;(4=e03jKiIn448Rq2?d>0KHkKoy>2nMfW_~|ur3OHOYGS1&c(Suj8icSKTrwiwv zgOIrQUHDC?C3cNq?CHm_JYdQKV(&u)O?>bF%Ye^vicNA3BG>GJ`+y20ANzpeb@YZq zB;SogaP3Ou-+4*$8d?9=6VMmhll(H7imQ!ioh-*BJ zcybFO6Ic#47Wol7rYuL~-F(LKX7H>PB*(shWmq(M?Huyqusq_J-<#z9P|6I zycoCR6f)ksM}DVTESDQPd%!w2g>eOO-8N|I=_7If1@fEqBDwq<#s{P~o)Y^4Vt)*R zW-e!W*7L1Nun3J(`cwS>HKptlHPtq8xkKfh*S|%Z_xG)wy0^NX8>LQW=(6aO*19IM z4^CXN_igU$>Qb*w@{L`g5k957zM}v)HKhSsIw=d612dhrd3Kzyh)CX-;9OjKG|6=z zvD0&I2Nx9vKu&DEsJ^~*yD!kAELK&Z!UCA&My-nK&3EsEWoV6xi~7~`;odqVFz#oK zEn`$-6dek}csr3?C#p|o!gB2$Dh8t7f!3&|)}i`Ty@s7GDiLtQhNI5E)qu2S6?Spj zq~%IO2O(wyS1OO8A`O_VqA%r|A3%Qhx(O{*zJ{lxtoRQ}d zf7bPMb=z9x;j`}{>v|yh^nh-T{R6pbrlq1Rvj*^&is}XGW{C+=wbc>$=y!-*$%Du= zI2j8x)mmp_qMFDM>|ANuad8S8qM?U(LU*#A%Ij6k(gt_>F^n9sN7PA-Qfa+m3E4jb z|4vN^?8ezPjCLP*rZWky+bo|Wg(atWXF72r5~MrZG&&?^zy20lW95p+81#E_`gHzMM)ZTh=kj#!+ZZmh(Xi zOuPeOlPZNRxhY5S7&MCTiV#x2g(G<83fN^8D|k!HrX!5E&fI7lw3%! zf5$jbRKs3S9%SkljG!6I85hzObYt~y%*Mlv6Q!NL$@q|^I99=jLKmz9t-r&_)4;)* zaigqD4-rmklX0ZnYmX7tu#fl(VLXY}z_eba{3z`-;e@32ZR1F^ zMz#!(CjK;ukM)c%QLf}Ox`uHj%9$u%;_~zuXL9K|SizYBrYwZEiJ5{s>5w+%Pn0|9 zT3VxxJDCTG72JuQ0krWYTF=vZwus!B7ay=XpK>Q!k5m5SJAM`` zn3yx(lzi+e<4!5$N%>Rs`UCJ7GDg9nJj*9B4rLJ*rQlJH1!b)Mre_xP{J}admGLNg zHXvEP9Y!AB4FMp-a$vu29I$MXN?C80d zfQvZX=jy@J%~X?Ircs@RBuvRDvBrRbq08%JXMT1{mdAGe{+v!ilIa`*u77`u1t1ib zrLJZ^ZvQz%y$4yGH(>YsgGKUyi-aSee@p^edcsV-1J1}DWICvQl4IGIQbepSY#&ov zyyWc#WO8Cl`_Lj8*O4k1w+|_|Bm>D@FXfR+nZSaKS@;Q6Mq4{AvsaQM&TB==bDUQz z1INNx?TRIbvjK-?N&!_?N{o*8-T>{zYF8k<^FDB?yNa=vUu&9R_mPT`wg5Qxw}HqU zm0y4)@g7-0|27fTr|`~Fpqg%9yN||EM1F};`+$;41jzxw)I3S~UBx_y?%LpKioTL~ zWu>fiGH}Q(^zO;Tx>gCvULrrtQ@y+-J%G&W4$8cI#caQf%Cu~HLPo|ns+eu>$i9 z6t)&nh4=P6Y9D)JOR{yR3sG27rS^ZKMpcqGoj_5^sH(q;y-inA*)0QTj@i;xg+-OC z!bnKB=1KlyGuu2=7R|OH3J?8%>B0^%CC&%r?}o|aJBM6_ZFxiHH-;!!8_Zs)f*Bp8 zl)ADWxfFFjeaE$n%jUc&pcwkY<6VtiTZP1OoCc6F_(|4c_IFcquD-d5BbwBN8N1i{ zp1<4DrLC16-kH(d&nE4+4_762Ng<-~f}ZoeSs~wyFt1V{M8{E?e(5LT$Dc3j>r>uw yN_}6#>2YAq=-)5i>{39~MiJ-fikX7NU3_s=LsBH^+Llsb)r-8sf3ClA2mTG*r-nfQ literal 0 HcmV?d00001 diff --git a/docs/assets/footer.css b/docs/assets/footer.css new file mode 100644 index 0000000..af21c36 --- /dev/null +++ b/docs/assets/footer.css @@ -0,0 +1,12 @@ +/** + * Babel Starter Kit (https://www.kriasoft.com/babel-starter-kit) + * + * Copyright © 2015-2016 Kriasoft, LLC. All rights reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +.footer { + +} diff --git a/docs/assets/footer.ejs b/docs/assets/footer.ejs new file mode 100644 index 0000000..e69de29 diff --git a/docs/assets/header.css b/docs/assets/header.css new file mode 100644 index 0000000..edfa55b --- /dev/null +++ b/docs/assets/header.css @@ -0,0 +1,124 @@ +/** + * Babel Starter Kit (https://www.kriasoft.com/babel-starter-kit) + * + * Copyright © 2015-2016 Kriasoft, LLC. All rights reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +.header { + padding: 1.5rem 0; + background: var(--header-bg-color); + color: var(--header-color); +} + +.header__logo { + color: var(--logo-color); + text-decoration: none; + text-shadow: 1px 1px 1px rgba(0, 0, 0, 1); + font-weight: 700; + font-style: italic; + font-size: 2.5rem; + font-family: 'Lato', sans-serif; +} + +.header__logo-img { + margin-right: 10px; + width: 164px; + height: 64px; + vertical-align: middle; +} + +.header__author { + float: right; + padding: 18px 0; + font-size: 18px; + color: rgba(255, 255, 255, .6); +} +.header__author a { + color: rgba(255, 255, 255, .8); + text-decoration: none; +} +.header__author a:hover { + color: rgba(255, 255, 255, 1); +} + +.header__hero { + padding: 50px 0 30px; +} + +.header__hero-title { + margin: 0; + padding: 0 0 15px; + font-weight: 400; + font-size: 2rem; + line-height: 1em; +} + +.header__hero-desc { + margin: 0; + padding: 0 0 30px; + letter-spacing: 1px; + font-weight: 300; + font-size: 1.5rem; +} + +.header__hero-img { + margin: -20px -20px 0 0; + float: right; + width: 256px; + height: 256px; +} + +.header__hero-btn { + display: inline-block; + margin: 1rem 1rem 0 0; + padding: .8rem 2rem .875rem 2rem; + border-radius: 3px; + background: rgba(249, 220, 62, .9); + color: var(--header-bg-color); + text-decoration: none; + box-shadow: 1px 1px 1px rgba(0, 0, 0, 1); +} + +.header__hero-btn:hover { + background: rgba(249, 220, 62, 1); +} + +.header__hero-btn--muted { + background: rgba(255, 255, 255, .5); +} + +.header__hero-btn--muted:hover { + background: rgba(255, 255, 255, .6); +} + +.header__hero-btn-icon { + width: 28px; + height: 28px; + vertical-align: middle; + margin: -4px 10px -4px 0; + fill: var(--header-bg-color); +} + +.header__version { + background: color(var(--header-bg-color) alpha(-90%)); + padding: 15px 0; + font-size: 16px; + color: var(--main-color); +} + +.header__version a { + color: var(--link-color); + text-decoration: none; +} + +.header__version a:hover, +.header__version a:active { + color: color(var(--link-color) blackness(10%)); +} + +.header__join { + float: right; +} diff --git a/docs/assets/header.ejs b/docs/assets/header.ejs new file mode 100644 index 0000000..b911023 --- /dev/null +++ b/docs/assets/header.ejs @@ -0,0 +1,31 @@ +
+
+ + + made with  ♥  by  + + <% if (path === '/') { %> +
+ Babel Starter Kit +

Create better NPM modules

+

Babel Starter Kit is a project template for
authoring and publishing JavaScript libraries

+ <%- include('stats'); %> + Get Started + + GitHub + View on GitHub + +
+ <% } %> +
+
+<% if (path === '/') { %> +
+
+ 2016-04-15   |   v1.1.3  (changelog) + Join #babel-starter-kit chat room on Gitter to stay up to date. +
+
+<% } %> diff --git a/docs/assets/img/babel.svg b/docs/assets/img/babel.svg new file mode 100644 index 0000000..3a957ae --- /dev/null +++ b/docs/assets/img/babel.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/docs/assets/img/github-icon.svg b/docs/assets/img/github-icon.svg new file mode 100644 index 0000000..0296b1a --- /dev/null +++ b/docs/assets/img/github-icon.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/docs/assets/img/hero.svg b/docs/assets/img/hero.svg new file mode 100644 index 0000000..9e2721a --- /dev/null +++ b/docs/assets/img/hero.svg @@ -0,0 +1,4 @@ + + + + diff --git a/docs/assets/js/onStats.js b/docs/assets/js/onStats.js new file mode 100644 index 0000000..6288433 --- /dev/null +++ b/docs/assets/js/onStats.js @@ -0,0 +1,70 @@ +/** + * Babel Starter Kit (https://www.kriasoft.com/babel-starter-kit) + * + * Copyright © 2015-2016 Kriasoft, LLC. All rights reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +/** + * Loads data asynchronously via JSONP. + */ +const load = (() => { + let index = 0; + const timeout = 5000; + + return url => new Promise((resolve, reject) => { + const callback = '__callback' + index++; + const timeoutID = window.setTimeout(() => { + reject(new Error('Request timeout.')); + }, timeout); + + window[callback] = response => { + window.clearTimeout(timeoutID); + resolve(response); + }; + + const script = document.createElement('script'); + script.type = 'text/javascript'; + script.async = true; + script.src = url + (url.indexOf('?') === -1 ? '?' : '&') + 'callback=' + callback; + document.getElementsByTagName('head')[0].appendChild(script); + }); +})(); + +/** + * Loads project stats from GitHub.com + */ +const onStats = (() => { + const key = 'github.repo'; + return async (callback) => { + const { value, timestamp } = JSON.parse(window.localStorage.getItem(key)) || {}; + if (value) { + callback(value); + } + if (!value || (new Date() - new Date(timestamp)) > 300000 /* 5 min */) { + const response = await load('https://api.github.com/repos/kriasoft/babel-starter-kit'); + if (response.meta.status === 200) { + const data = { + value: { + createdAt: response.data.created_at, + updatedAt: response.data.updated_at, + pushedAt: response.data.pushed_at, + forks: response.data.forks, + watchers: response.data.watchers, + subscribers: response.data.subscribers_count, + openIssues: response.data.open_issues, + }, + timestamp: new Date(), + }; + window.localStorage.setItem(key, JSON.stringify(data)); + callback(data.value); + } else { + throw new Error('Request failed. ' + response); + } + } + }; +})(); + +export default onStats; diff --git a/docs/assets/main.css b/docs/assets/main.css new file mode 100644 index 0000000..ccdbbb1 --- /dev/null +++ b/docs/assets/main.css @@ -0,0 +1,333 @@ +/** + * Babel Starter Kit (https://www.kriasoft.com/babel-starter-kit) + * + * Copyright © 2015-2016 Kriasoft, LLC. All rights reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +@import "vendor/normalize.css"; +@import "header.css"; +@import "stats.css"; +@import "nav.css"; +@import "footer.css"; + +/* ========================================================================== + Variables + ========================================================================== */ + +:root { + /* Layout */ + --max-content-width: 800px; + + /* Colors */ + --main-color: #222; + --main-bg-color: #fff; + --link-color: #337ab7; + --logo-color: rgb(249, 220, 62); + --header-color: #fff; + --header-bg-color: #323330; + --footer-color: #fff; + --footer-bg-color: black; +} + +/* ========================================================================== + Base styles + ========================================================================== */ + +html { + color: var(--main-color); + font-size: 1em; + line-height: 1.4; +} + +/* + * Remove text-shadow in selection highlight: + * https://twitter.com/miketaylr/status/12228805301 + * + * These selection rule sets have to be separate. + * Customize the background color to match your design. + */ + +::-moz-selection { + background: #b3d4fc; + text-shadow: none; +} + +::selection { + background: #b3d4fc; + text-shadow: none; +} + +/* + * A better looking default horizontal rule + */ + +hr { + display: block; + height: 1px; + border: 0; + border-top: 1px solid #ccc; + margin: 1em 0; + padding: 0; +} + +/* + * Remove the gap between audio, canvas, iframes, + * images, videos and the bottom of their containers: + * https://github.com/h5bp/html5-boilerplate/issues/440 + */ + +audio, +canvas, +iframe, +img, +svg, +video { + vertical-align: middle; +} + +/* + * Remove default fieldset styles. + */ + +fieldset { + border: 0; + margin: 0; + padding: 0; +} + +/* + * Allow only vertical resizing of textareas. + */ + +textarea { + resize: vertical; +} + +/* ========================================================================== + Browser Upgrade Prompt + ========================================================================== */ + +.browserupgrade { + margin: 0.2em 0; + background: #ccc; + color: #000; + padding: 0.2em 0; +} + +/* ========================================================================== + Custom styles + ========================================================================== */ + +body { + background-color: #f5fcff; + font-size: 18px; + font-family: 'Lato', sans-serif; +} + +.container { + margin: 0 auto; + width: var(--max-content-width); +} + +.content { + display: table; + margin: 0 auto; + width: var(--max-content-width); +} + +.content-left, +.content-right { + display: table-cell; + vertical-align: top; + padding-top: 40px; +} + +.content-left > h1:first-child, +.content-left > h2:first-child, +.content-left > h3:first-child, +.content-right > h1:first-child, +.content-right > h2:first-child, +.content-right > h3:first-child { + margin-top: 0; +} + +.content-left { + width: 160px; +} + +.content-right { + padding-left: 20px; +} + +/* ========================================================================== + Helper classes + ========================================================================== */ + +/* + * Hide visually and from screen readers + */ + +.hidden { + display: none !important; +} + +/* + * Hide only visually, but have it available for screen readers: + * http://snook.ca/archives/html_and_css/hiding-content-for-accessibility + */ + +.visuallyhidden { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} + +/* + * Extends the .visuallyhidden class to allow the element + * to be focusable when navigated to via the keyboard: + * https://www.drupal.org/node/897638 + */ + +.visuallyhidden.focusable:active, +.visuallyhidden.focusable:focus { + clip: auto; + height: auto; + margin: 0; + overflow: visible; + position: static; + width: auto; +} + +/* + * Hide visually and from screen readers, but maintain layout + */ + +.invisible { + visibility: hidden; +} + +/* + * Clearfix: contain floats + * + * For modern browsers + * 1. The space content is one way to avoid an Opera bug when the + * `contenteditable` attribute is included anywhere else in the document. + * Otherwise it causes space to appear at the top and bottom of elements + * that receive the `clearfix` class. + * 2. The use of `table` rather than `block` is only necessary if using + * `:before` to contain the top-margins of child elements. + */ + +.clearfix:before, +.clearfix:after { + content: " "; /* 1 */ + display: table; /* 2 */ +} + +.clearfix:after { + clear: both; +} + +/* ========================================================================== + EXAMPLE Media Queries for Responsive Design. + These examples override the primary ('mobile first') styles. + Modify as content requires. + ========================================================================== */ + +@media only screen and (min-width: 35em) { + /* Style adjustments for viewports that meet the condition */ +} + +@media print, +(-webkit-min-device-pixel-ratio: 1.25), +(min-resolution: 1.25dppx), +(min-resolution: 120dpi) { + /* Style adjustments for high resolution devices */ +} + +/* ========================================================================== + Print styles. + Inlined to avoid the additional HTTP request: + http://www.phpied.com/delay-loading-your-print-css/ + ========================================================================== */ + +@media print { + *, + *:before, + *:after, + *:first-letter, + *:first-line { + background: transparent !important; + color: #000 !important; /* Black prints faster: + http://www.sanbeiji.com/archives/953 */ + box-shadow: none !important; + text-shadow: none !important; + } + + a, + a:visited { + text-decoration: underline; + } + + a[href]:after { + content: " (" attr(href) ")"; + } + + abbr[title]:after { + content: " (" attr(title) ")"; + } + + /* + * Don't show links that are fragment identifiers, + * or use the `javascript:` pseudo protocol + */ + + a[href^="#"]:after, + a[href^="javascript:"]:after { + content: ""; + } + + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + + /* + * Printing Tables: + * http://css-discuss.incutio.com/wiki/Printing_Tables + */ + + thead { + display: table-header-group; + } + + tr, + img { + page-break-inside: avoid; + } + + img { + max-width: 100% !important; + } + + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + + h2, + h3 { + page-break-after: avoid; + } +} diff --git a/docs/assets/main.ejs b/docs/assets/main.ejs new file mode 100644 index 0000000..d6a0d8f --- /dev/null +++ b/docs/assets/main.ejs @@ -0,0 +1,46 @@ + + + + + + <%= title %> + + + + + + + + <%- include('header'); %> +
+
+ <%- include('nav'); %> +
+
+ <%- content %> + <% if (path !== '/') { %> +
+ + <% } %> +
+
+ + + + + + diff --git a/docs/assets/main.js b/docs/assets/main.js new file mode 100644 index 0000000..9b503b2 --- /dev/null +++ b/docs/assets/main.js @@ -0,0 +1,33 @@ +/** + * Babel Starter Kit (https://www.kriasoft.com/babel-starter-kit) + * + * Copyright © 2015-2016 Kriasoft, LLC. All rights reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +import 'babel/polyfill'; +import onStats from './js/onStats'; + +const run = async () => { + try { + console.log('Welcome to Babel Starter Kit!'); // eslint-disable-line no-console + if (document.querySelector('.stats')) { + onStats(stats => { + document.querySelector('.stats-forks span').innerText = stats.forks; + document.querySelector('.stats-stars span').innerText = stats.watchers; + document.querySelector('.stats-subscribers span').innerText = stats.subscribers; + document.querySelector('.stats-open-issues span').innerText = stats.openIssues; + }); + } + } catch (err) { + console.log(err); // eslint-disable-line no-console + } +}; + +if (window.addEventListener) { + window.addEventListener('DOMContentLoaded', run); +} else { + window.attachEvent('onload', run); +} diff --git a/docs/assets/nav.css b/docs/assets/nav.css new file mode 100644 index 0000000..55ccfa1 --- /dev/null +++ b/docs/assets/nav.css @@ -0,0 +1,44 @@ +/** + * Babel Starter Kit (https://www.kriasoft.com/babel-starter-kit) + * + * Copyright © 2015-2016 Kriasoft, LLC. All rights reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +.nav { + width: 160px; +} + +.nav__title { + text-transform: uppercase; + font-size: 16px; + margin-top: 10px; +} + +.nav__menu { + list-style-type: none; + padding-left: 0; +} + +.nav__menu-item { + font-size: 16px; +} + +.nav__menu-item--selected .nav__link { + color: #f26b00; +} + +.nav__link { + text-decoration: none; +} + +.nav__link:active, +.nav__link:hover { + color: #f26b00; +} + +pre { + font-size: 16px; +} diff --git a/docs/assets/nav.ejs b/docs/assets/nav.ejs new file mode 100644 index 0000000..caeb76c --- /dev/null +++ b/docs/assets/nav.ejs @@ -0,0 +1,20 @@ + diff --git a/docs/assets/robots.txt b/docs/assets/robots.txt new file mode 100644 index 0000000..d0e5f1b --- /dev/null +++ b/docs/assets/robots.txt @@ -0,0 +1,5 @@ +# www.robotstxt.org/ + +# Allow crawling of all content +User-agent: * +Disallow: diff --git a/docs/assets/stats.css b/docs/assets/stats.css new file mode 100644 index 0000000..3717825 --- /dev/null +++ b/docs/assets/stats.css @@ -0,0 +1,32 @@ +/** + * Babel Starter Kit (https://www.kriasoft.com/babel-starter-kit) + * + * Copyright © 2015-2016 Kriasoft, LLC. All rights reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +.stats { + font-size: 12px; + font-weight: normal; +} + +.stats__link { + color: rgba(255, 255, 255, .8); + text-decoration: none; + margin-right: 10px; +} + +.stats__link:hover { + color: rgba(255, 255, 255, 1); +} + +.stats__link:hover .stats__icon { + fill: rgba(255, 255, 255, 1); +} + +.stats__icon { + padding-right: 6px; + fill: rgba(255, 255, 255, .8); +} diff --git a/docs/assets/stats.ejs b/docs/assets/stats.ejs new file mode 100644 index 0000000..cfd2a3d --- /dev/null +++ b/docs/assets/stats.ejs @@ -0,0 +1,18 @@ +

+ + + <%= github.subscribers_count %> watchers + + + + <%= github.watchers %> stars + + + + <%= github.forks %> forks + + + + <%= github.open_issues_count %> open issues + +

diff --git a/docs/assets/vendor/highlight.css b/docs/assets/vendor/highlight.css new file mode 100644 index 0000000..e69de29 diff --git a/docs/assets/vendor/highlight.js b/docs/assets/vendor/highlight.js new file mode 100644 index 0000000..e69de29 diff --git a/docs/assets/vendor/normalize.css b/docs/assets/vendor/normalize.css new file mode 100644 index 0000000..5e5e3c8 --- /dev/null +++ b/docs/assets/vendor/normalize.css @@ -0,0 +1,424 @@ +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ + +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS and IE text size adjust after device orientation change, + * without disabling user zoom. + */ + +html { + font-family: sans-serif; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/** + * Remove default margin. + */ + +body { + margin: 0; +} + +/* HTML5 display definitions + ========================================================================== */ + +/** + * Correct `block` display not defined for any HTML5 element in IE 8/9. + * Correct `block` display not defined for `details` or `summary` in IE 10/11 + * and Firefox. + * Correct `block` display not defined for `main` in IE 11. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} + +/** + * 1. Correct `inline-block` display not defined in IE 8/9. + * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. + */ + +audio, +canvas, +progress, +video { + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ +} + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Address `[hidden]` styling not present in IE 8/9/10. + * Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22. + */ + +[hidden], +template { + display: none; +} + +/* Links + ========================================================================== */ + +/** + * Remove the gray background color from active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * Improve readability of focused elements when they are also in an + * active/hover state. + */ + +a:active, +a:hover { + outline: 0; +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Address styling not present in IE 8/9/10/11, Safari, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/** + * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +/** + * Address styling not present in Safari and Chrome. + */ + +dfn { + font-style: italic; +} + +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari, and Chrome. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/** + * Address styling not present in IE 8/9. + */ + +mark { + background: #ff0; + color: #000; +} + +/** + * Address inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove border when inside `a` element in IE 8/9/10. + */ + +img { + border: 0; +} + +/** + * Correct overflow not hidden in IE 9/10/11. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* Grouping content + ========================================================================== */ + +/** + * Address margin not present in IE 8/9 and Safari. + */ + +figure { + margin: 1em 40px; +} + +/** + * Address differences between Firefox and other browsers. + */ + +hr { + box-sizing: content-box; + height: 0; +} + +/** + * Contain overflow in all browsers. + */ + +pre { + overflow: auto; +} + +/** + * Address odd `em`-unit font size rendering in all browsers. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +/* Forms + ========================================================================== */ + +/** + * Known limitation: by default, Chrome and Safari on OS X allow very limited + * styling of `select`, unless a `border` property is set. + */ + +/** + * 1. Correct color not being inherited. + * Known issue: affects color of disabled elements. + * 2. Correct font properties not being inherited. + * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. + */ + +button, +input, +optgroup, +select, +textarea { + color: inherit; /* 1 */ + font: inherit; /* 2 */ + margin: 0; /* 3 */ +} + +/** + * Address `overflow` set to `hidden` in IE 8/9/10/11. + */ + +button { + overflow: visible; +} + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. + * Correct `select` style inheritance in Firefox. + */ + +button, +select { + text-transform: none; +} + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ +} + +/** + * Re-set default cursor for disabled elements. + */ + +button[disabled], +html input[disabled] { + cursor: default; +} + +/** + * Remove inner padding and border in Firefox 4+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +input { + line-height: normal; +} + +/** + * It's recommended that you don't attempt to style these elements. + * Firefox's implementation doesn't respect box-sizing, padding, or width. + * + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Fix the cursor style for Chrome's increment/decrement buttons. For certain + * `font-size` values of the `input`, it causes the cursor style of the + * decrement button to change from `default` to `text`. + */ + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Address `appearance` set to `searchfield` in Safari and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari and Chrome. + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + box-sizing: content-box; /* 2 */ +} + +/** + * Remove inner padding and search cancel button in Safari and Chrome on OS X. + * Safari (but not Chrome) clips the cancel button when the search input has + * padding (and `textfield` appearance). + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/** + * 1. Correct `color` not being inherited in IE 8/9/10/11. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ + +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Remove default vertical scrollbar in IE 8/9/10/11. + */ + +textarea { + overflow: auto; +} + +/** + * Don't inherit the `font-weight` (applied by a rule above). + * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + */ + +optgroup { + font-weight: bold; +} + +/* Tables + ========================================================================== */ + +/** + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} + +td, +th { + padding: 0; +} diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 0000000..59a517d --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,57 @@ +--- +id: bsk:getting-started +title: Getting Started ∙ Babel Starter Kit +--- + +# Getting Started + +For better experience, make sure that you have `npm v3+` installed. Start by cloning this repo and +installing project dependencies: + +```sh +$ git clone -o babel-starter-kit \ + -b master --single-branch \ + https://github.com/kriasoft/babel-starter-kit.git \ + +$ cd +$ npm install +``` + +Update your name in `LICENSE.txt` and project information in `package.json` and `README.md` files. +Write your code in `src` folder, write tests in `test` folder. Run `npm run build` to compile the +source code into a distributable format. Write documentation in markdown format in `docs` folder. +Run `npm start` to launch a development server with the documentation site. + +Alternatively, start a new project with **Yeoman**: + +```sh +$ npm install -g generator-javascript +$ mkdir +$ cd +$ yo javascript +``` + +### How to Build + +Running `npm run build` will compile source files to a distributable format (CommonJS, ES6 and UMD) +ready to be published to NPM from the `dist` folder. See `tools/build.js` for more info. + +### How to Test + +Run one, or a combination of the following commands to lint and test your code: + +* `npm run lint` — lint the source code with ESLint +* `npm test` — run unit tests with Mocha +* `npm run test:watch` — run unit tests with Mocha, and watch files for changes +* `npm run test:cover` — run unit tests with code coverage by Istanbul + +### How to Update + +Down the road you can fetch and merge the recent changes from this repo back into your project: + +```sh +$ git checkout master +$ git fetch babel-starter-kit +$ git merge babel-starter-kit/master +$ npm install +``` diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..3eb9873 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,29 @@ +--- +id: bsk:home +title: Babel Starter Kit ∙ A project template for authoring and publishing JavaScript libraries +--- + +# Babel Starter Kit + +Babel Starter Kit is a project template for authoring and publishing JavaScript libraries using +[ES2015](https://babeljs.io/docs/learn-es2015/)+ via [Babel](https://babeljs.io/) + +### Features + +    ✓ Author your code, including tests, in [ES2015](https://babeljs.io/docs/learn-es2015/)+ via [Babel](http://babeljs.io/)
+    ✓ Pre-configured unit tests with [Mocha](http://mochajs.org/), [Chai](http://chaijs.com/) and [Sinon](http://sinonjs.org/)
+    ✓ Pre-configured test coverage with [Istanbul](https://github.com/gotwarlost/istanbul) and [Coveralls](https://coveralls.io/)
+    ✓ Generate a static site for your project via [Easystatic](https://easystatic.com)
+    ✓ [Yeoman](http://yeoman.io/) generator ([generator-javascript](https://github.com/kriasoft/babel-starter-kit/tree/yeoman-generator))
+    ✓ Cross-platform, minimum dependencies
+ +### Backers + +♥ Babel Starter Kit? Help us keep it alive by [donating funds](https://www.patreon.com/tarkus) to cover project expenses! + + + + + + + diff --git a/docs/recipes/testing-with-mocha-and-jsdom.md b/docs/recipes/testing-with-mocha-and-jsdom.md new file mode 100644 index 0000000..70c8789 --- /dev/null +++ b/docs/recipes/testing-with-mocha-and-jsdom.md @@ -0,0 +1,75 @@ +--- +id: bsk:recipes:mocha-jsdom +title: Testing with mocha and jsdom ∙ Babel Starter Kit +--- + +# Testing with mocha and jsdom + +For browser-specific code, such as the one that relies on `document`, `window` global variables and +DOM manipulation, you may want to consider using [jsdom](https://github.com/tmpvar/jsdom) library +that emulates browser environment, and in combination with [mocha-jsdom](https://github.com/rstacruz/mocha-jsdom), +can be fast and reliable tool for testing such type of code. + +Let's see how it works on an example. Suppose you have a component that parses a URL string by +using [document.createElement](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement) +method as follows: + +#### `src/parseUrl.js` + +```js +function parseUrl(url) { + const link = document.createElement('a'); + link.href = url; + return { + protocol: link.protocol, + hostname: link.hostname, + port: link.port, + pathname: link.pathname, + search: link.search, + hash: link.hash, + host: link.host + }; +} + +export default parseUrl; +``` + +In order to create a unit test for this component, first we need to install `jsdom` and +`mocha-jsdom` npm modules by running: + +```sh +npm install jsdom mocha-jsdom --save-dev +``` + +Then create a unit test for the component above. + +#### `test/parseUrlSpec.js` + +```js +import jsdom from 'mocha-jsdom'; +import { expect } from 'chai'; +import parseUrl from '../src/parseUrl'; + +describe('parseUrl', function() { + + jsdom(); // Emulates the browser environment + + it('should be able to parse a URL string', function() { + const url = 'http://example.com:3000/pathname/?search=test#hash'; + const result = parseUrl(url); + expect(result).to.be.deep.equal({ + protocol: 'http:', + hostname: 'example.com', + port: '3000', + pathname: '/pathname/', + search: '?search=test', + hash: '#hash', + host: 'example.com:3000' + }); + }); + +}); +``` + +Now when you run `npm test`, the unit test above should pass just fine, as if it was executed in a +browser. diff --git a/docs/recipes/throwing-errors-with-fbjs-invariant.md b/docs/recipes/throwing-errors-with-fbjs-invariant.md new file mode 100644 index 0000000..97f06a0 --- /dev/null +++ b/docs/recipes/throwing-errors-with-fbjs-invariant.md @@ -0,0 +1,74 @@ +--- +id: bsk:recipes:invariant +title: Throwing errors with Facebook's invariant library ∙ Babel Starter Kit +--- + +# Throwing errors with FB's invariant library + +If you're familiar with Facebook's [React](https://github.com/facebook/react), +[React Native](https://github.com/facebook/react-native), [Flux](https://github.com/facebook/flux), +[Relay](https://github.com/facebook/relay) libraries, you might notice the extensive use of the +`invariant` function from `fbjs` npm module in their code bases. The goal of which is being able to +provide descriptive error messages for the development environment. These error messages are going +to be replaced by a single generic error when the project is compiled for production environments by +Babel and a module bundler, such as Webpack or Browserify. This allows to minimize the client-side +bundle size, and at the same time provide a good developer experience. + +Here is how it works. First, you need to install `fbjs` and `fbjs-scripts` npm modules by running: + +```sh +$ npm install fbjs@next --save +$ npm install fbjs-scripts@next --save-dev +``` + +Then update Babel configuration located in `pacakge.json` file by including `dev-expression` plugin +from the `fbjs-scripts` npm module: + +```json +{ + "babel": { + "presets": [ + "es2015", + "stage-0" + ], + "plugins": [ + "fbjs-scripts/babel-6/dev-expression", + "transform-runtime" + ] + } +} +``` + +Now you can use the `invariant` helper function in your code as follows: + +```js +import invariant from modules + +class Greeting { + + constructor(name) { + if (name) { + invariant( + typeof name === 'string' || name instanceof String, + 'The name argument must be a string' + ); + this.name = name; + } else { + this.name = 'Guest'; + } + this.name = name || 'Guest'; + } + + hello() { + return `Welcome, ${this.name}!`; + } + +} + +export default Greeting; +``` + +When you bundle your project for a production environment, you need to make sure that +`process.env.NODE_ENV` variable is set to `'production'`. Here is an example how to do it with +Webpack — [webpack.config.js#L28](https://github.com/kriasoft/react-starter-kit/blob/master/tools/webpack.config.js#L28) +in [React Starter Kit](https://www.reactstarterkit.com). diff --git a/package.json b/package.json new file mode 100644 index 0000000..f10fbea --- /dev/null +++ b/package.json @@ -0,0 +1,82 @@ +{ + "private": true, + "name": "mobx-router5-react", + "version": "0.0.0", + "description": "Router5 integration with mobX and react", + "homepage": "https://github.com/LeonardoGentile/mobx-router5-react", + "repository": { + "type": "git", + "url": "https://github.com/LeonardoGentile/mobx-router5-react.git" + }, + "author": "Leonardo Gentile", + "contributors": [], + "license": "MIT", + "keywords": [ + "router", + "mobx", + "react", + "router5", + "functional", + "routing" + ], + "bugs": { + "url": "https://github.com/LeonardoGentile/mobx-router5-react/issues" + }, + "main": "index.js", + "jsnext:main": "index.es.js", + "babel": { + "presets": [ + "latest", + "stage-0" + ], + "plugins": [ + "transform-runtime", + "transform-decorators-legacy" + ] + }, + "eslintConfig": { + "parser": "babel-eslint", + "extends": "airbnb-base" + }, + "dependencies": { + "babel-runtime": "^6.11.6" + }, + "devDependencies": { + "babel-cli": "^6.16.0", + "babel-core": "^6.17.0", + "babel-eslint": "^7.0.0", + "babel-plugin-transform-decorators-legacy": "^1.3.4", + "babel-plugin-transform-runtime": "^6.15.0", + "babel-preset-latest": "^6.16.0", + "babel-preset-stage-0": "^6.16.0", + "babel-register": "^6.16.3", + "chai": "^4.0.0-canary.1", + "coveralls": "^2.11.14", + "del": "^2.2.2", + "eslint": "^3.8.0", + "eslint-config-airbnb-base": "^10.0.1", + "eslint-plugin-import": "^2.2.0", + "istanbul": "^1.1.0-alpha.1", + "mocha": "^3.1.2", + "rollup": "^0.36.3", + "rollup-plugin-babel": "^2.6.1", + "sinon": "^2.0.0-pre.3" + }, + "peerDependencies": { + "react": "^15.0.0", + "mobx": "^3.1.0", + "mobx-router5": "^0.0.0", + "mobx-react": "^4.0.0" + }, + "scripts": { + "lint": "eslint src test tools", + "test": "mocha --compilers js:babel-register", + "test:watch": "mocha --compilers js:babel-register --reporter min --watch", + "test:cover": "babel-node ./node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha", + "coveralls": "cat ./coverage/lcov.info | coveralls", + "build": "node tools/build", + "prepublish": "npm run build", + "publish:docs": "easystatic deploy docs --repo kriasoft/babel-starter-kit", + "start": "easystatic start docs" + } +} diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..7b857a0 --- /dev/null +++ b/src/index.js @@ -0,0 +1,7 @@ +import routeNode from './modules/routeNode'; +import { getComponentFromRoutes } from './modules/utils.js'; + +export { + routeNode, + getComponentFromRoutes +}; diff --git a/src/modules/BaseLink.js b/src/modules/BaseLink.js new file mode 100644 index 0000000..b54f231 --- /dev/null +++ b/src/modules/BaseLink.js @@ -0,0 +1,94 @@ +import React, { Component } from 'react'; +import { observer, inject} from 'mobx-react'; + +@inject('routerStore') +class BaseLink extends Component { + + constructor(props, context) { + super(props, context); + + this.routerStore = props.routerStore; + + // get the router instance from the props (when explicitly passed) or from routerStore + this.router = this.props.router || this.routerStore.router || null; + + if (!this.router) { + console.error('[react-router5][BaseLink] missing router instance props'); + } + + if (!this.router.hasPlugin('BROWSER_PLUGIN')) { + console.error('[react-router5][BaseLink] missing browser plugin, href might be build incorrectly'); + } + + this.isActive = this.isActive.bind(this); + this.clickHandler = this.clickHandler.bind(this); + + this.state = { + active: this.isActive(), + route: this.routerStore.route, + previousRoute: this.routerStore.previousRoute + }; + } + + buildUrl(routeName, routeParams) { + // If browser plugin is active + if (this.router.buildUrl) { + return this.router.buildUrl(routeName, routeParams); + } + + return this.router.buildPath(routeName, routeParams); + } + + isActive() { + return this.routerStore.isActive(this.props.routeName, this.props.routeParams, this.props.activeStrict); + } + + clickHandler(evt) { + if (this.props.onClick) { + this.props.onClick(evt); + + if (evt.defaultPrevented) { + return; + } + } + + const comboKey = evt.metaKey || evt.altKey || evt.ctrlKey || evt.shiftKey; + + if (evt.button === 0 && !comboKey) { + evt.preventDefault(); + this.router.navigate(this.props.routeName, this.props.routeParams, this.props.routeOptions); + } + } + + render() { + const {routeName, routeParams, className, activeClassName, children} = this.props; + + const active = this.isActive(); + const href = this.buildUrl(routeName, routeParams); + const linkclassName = (className ? className.split(' ') : []) + .concat(active ? [activeClassName] : []).join(' '); + + const onClick = this.clickHandler; + + return React.createElement('a', {href, className: linkclassName, onClick}, children); + } +} + + +// BaseLink.propTypes = { +// routeName: React.PropTypes.string.isRequired, +// routeParams: React.PropTypes.object, +// routeOptions: React.PropTypes.object, +// activeClassName: React.PropTypes.string, +// activeStrict: React.PropTypes.bool, +// onClick: React.PropTypes.func +// }; + +BaseLink.defaultProps = { + activeClassName: 'active', + activeStrict: false, + routeParams: {}, + routeOptions: {} +}; + +export default BaseLink; diff --git a/src/modules/routeNode.js b/src/modules/routeNode.js new file mode 100644 index 0000000..040e314 --- /dev/null +++ b/src/modules/routeNode.js @@ -0,0 +1,56 @@ +import React, { Component, createElement } from 'react'; +import { getDisplayName } from './utils'; +import { autorun } from 'mobx'; +import { inject} from 'mobx-react'; + +//TODO: create another wrapper function to pass a custom store name +function routeNode(nodeName) { // route node Name + return function routeNodeWrapper(RouteSegment) { // component Name + + @inject('routerStore') + class RouteNode extends Component { + + constructor(props, context) { + super(props, context); + this.state = { + route: props.routerStore.route, + intersectionNode: props.routerStore.intersectionNode, + }; + } + + componentDidMount() { + this.autorunDisposer = autorun(() => { + this.setState({ + route: this.props.routerStore.route, + intersectionNode: this.props.routerStore.intersectionNode + }); + }); + } + + componentWillUnmount() { + this.autorunDisposer(); + } + // Re-render the route-node (wrapped component) only if + // it is the correct "transition node" + shouldComponentUpdate (newProps, newState) { + return (newState.intersectionNode === nodeName); + } + + render() { + const { props } = this; + const component = createElement( + RouteSegment, + { ...props } + ); + + return component; + } + } + + RouteNode.displayName = 'RouteNode[' + getDisplayName(RouteSegment) + ']'; + + return RouteNode; + }; +} + +export default routeNode; diff --git a/src/modules/utils.js b/src/modules/utils.js new file mode 100644 index 0000000..91ebfb9 --- /dev/null +++ b/src/modules/utils.js @@ -0,0 +1,43 @@ +export const getDisplayName = component => component.displayName || component.name || 'Component'; + +export const ifNot = (condition, errorMessage) => { + if (!condition) throw new Error(errorMessage); +}; + +/** + * Return a component to be rendered by a routeNode for the current route + * extracted from the custom (nested) routes definition (with 'component' field) + * @param {array} routes - nested routes def (with 'component' field) + * @param {object} routerStore - the mobx-router store. Used for getting the current route + * @param {string} routeNode - the name of the route for the React component from where to re-render (transition node) + * @returns {React.Component} - the component to be rendered + */ +export function getComponentFromRoutes(routes, routerStore, routeNode) { + let level = 0; + let currentLevel = 0; + // Break current route in segments (levels) + const routeSegments = routerStore.route.name.split('.'); + + // Set nesting level where to find routes for this routeNode + if (routeNode === '') level = 0; + else level = routeNode.split('.').length; + if (level === 0 && routeNode !== '') level = 1; + + // Recurse until it gets the relevant portion of the routes obj or the component itself + function getComponent(routesObj) { + for(const route of routesObj) { + const segment = routeSegments[currentLevel]; // going deeper every recursion + if(route.name === segment) { + + if(currentLevel >= level) { // Exit condition + return route.component; + } + else { + currentLevel += 1; + return getComponent(route.children); + } + } + } + } + return getComponent(routes); +} diff --git a/src/modules/withRoute.js b/src/modules/withRoute.js new file mode 100644 index 0000000..3e917df --- /dev/null +++ b/src/modules/withRoute.js @@ -0,0 +1,56 @@ +import React, { Component, createElement } from 'react'; +import { ifNot, getDisplayName } from './utils'; + +function withRoute(BaseComponent) { + class ComponentWithRoute extends Component { + constructor(props, context) { + super(props, context); + this.router = context.router; + this.state = { + previousRoute: null, + route: this.router.getState() + }; + this.listener = this.listener.bind(this); + } + + componentDidMount() { + ifNot( + this.router.hasPlugin('LISTENERS_PLUGIN'), + '[react-router5][withRoute] missing listeners plugin' + ); + + this.listener = (toState, fromState) => this.setState({ previousRoute: fromState, route: toState }); + this.router.addListener(this.listener); + } + + componentWillUnmount() { + this.router.removeListener(this.listener); + } + + listener(toState, fromState) { + this.setState({ + previousRoute: fromState, + route: toState + }); + } + + render() { + ifNot( + !this.props.router && !this.props.route && !this.props.previousRoute, + '[react-router5] prop names `router`, `route` and `previousRoute` are reserved.' + ); + + return createElement(BaseComponent, { ...this.props, ...this.state, router: this.router }); + } + } + + ComponentWithRoute.contextTypes = { + router: React.PropTypes.object.isRequired + }; + + ComponentWithRoute.displayName = 'WithRoute[' + getDisplayName(BaseComponent) + ']'; + + return ComponentWithRoute; +} + +export default withRoute; diff --git a/test/.eslintrc b/test/.eslintrc new file mode 100644 index 0000000..88e8b17 --- /dev/null +++ b/test/.eslintrc @@ -0,0 +1,16 @@ +{ + "env": { + "mocha": true + }, + "rules": { + "import/no-extraneous-dependencies": [ + "error", + { + "optionalDependencies": false, + "peerDependencies": false + } + ], + "no-unused-expressions": "off", + "padded-blocks": "off" + } +} diff --git a/test/GreetingSpec.js b/test/GreetingSpec.js new file mode 100644 index 0000000..f0a9272 --- /dev/null +++ b/test/GreetingSpec.js @@ -0,0 +1,31 @@ +/** + * Babel Starter Kit (https://www.kriasoft.com/babel-starter-kit) + * + * Copyright © 2015-2016 Kriasoft, LLC. All rights reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +import { expect } from 'chai'; +import Greeting from '../src/Greeting'; + +describe('Greeting', () => { + + describe('greeting.hello()', () => { + + it('should return welcome message for a guest user', () => { + const greeting = new Greeting(); + const message = greeting.hello(); + expect(message).to.be.equal('Welcome, Guest!'); + }); + + it('should return welcome message for a named user', () => { + const greeting = new Greeting('John'); + const message = greeting.hello(); + expect(message).to.be.equal('Welcome, John!'); + }); + + }); + +}); diff --git a/tools/.eslintrc b/tools/.eslintrc new file mode 100644 index 0000000..6a0afaa --- /dev/null +++ b/tools/.eslintrc @@ -0,0 +1,12 @@ +{ + "rules": { + "import/no-extraneous-dependencies": [ + "error", + { + "optionalDependencies": false, + "peerDependencies": false + } + ], + "strict": "off" + } +} diff --git a/tools/build.js b/tools/build.js new file mode 100644 index 0000000..f647b8f --- /dev/null +++ b/tools/build.js @@ -0,0 +1,53 @@ +/** + * Babel Starter Kit (https://www.kriasoft.com/babel-starter-kit) + * + * Copyright © 2015-2016 Kriasoft, LLC. All rights reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +'use strict'; + +const fs = require('fs'); +const del = require('del'); +const rollup = require('rollup'); +const babel = require('rollup-plugin-babel'); +const pkg = require('../package.json'); + +let promise = Promise.resolve(); + +// Clean up the output directory +promise = promise.then(() => del(['dist/*'])); + +// Compile source code into a distributable format with Babel +['es', 'cjs', 'umd'].forEach((format) => { + promise = promise.then(() => rollup.rollup({ + entry: 'src/index.js', + external: Object.keys(pkg.dependencies), + plugins: [babel(Object.assign(pkg.babel, { + babelrc: false, + exclude: 'node_modules/**', + runtimeHelpers: true, // because we use transform-runtime plugin (avoid repetition) + presets: pkg.babel.presets.map(x => (x === 'latest' ? ['latest', { es2015: { modules: false } }] : x)), + }))], + }).then(bundle => bundle.write({ + dest: `dist/${format === 'cjs' ? 'index' : `index.${format}`}.js`, + format, + sourceMap: true, + moduleName: format === 'umd' ? pkg.name : undefined, + }))); +}); + +// Copy package.json and LICENSE.txt +promise = promise.then(() => { + delete pkg.private; + delete pkg.devDependencies; + delete pkg.scripts; + delete pkg.eslintConfig; + delete pkg.babel; + fs.writeFileSync('dist/package.json', JSON.stringify(pkg, null, ' '), 'utf-8'); + fs.writeFileSync('dist/LICENSE.txt', fs.readFileSync('LICENSE.txt', 'utf-8'), 'utf-8'); +}); + +promise.catch(err => console.error(err.stack)); // eslint-disable-line no-console