diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..a5ec49122 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,9 @@ +**/node_modules/** +node_modules +**/vendor/** +vendor +**/test/** +**/dist/** + +// being refactored / removed +packages/uikit-workshop/src/scripts/components/styleguide.js diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..826a1702e --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,86 @@ +module.exports = { + root: true, + env: { + node: true, + builtin: true, + es6: true, + browser: true, + }, + parser: 'babel-eslint', + parserOptions: { + ecmaVersion: 2018, + sourceType: 'module', + allowImportExportEverywhere: true, + ecmaFeatures: { + jsx: true, + experimentalDecorators: true, + }, + }, + globals: {}, + plugins: ['prettier'], + extends: ['eslint-config-prettier'].map(require.resolve), + rules: { + 'prettier/prettier': 'error', + 'block-scoped-var': 0, + camelcase: 0, + 'consistent-return': 2, + curly: [2, 'all'], + 'dot-notation': [1, { allowKeywords: true }], + eqeqeq: [2, 'allow-null'], + 'global-strict': [0, 'never'], + 'guard-for-in': 2, + 'key-spacing': 0, + 'new-cap': 0, + 'no-alert': 2, + 'no-bitwise': 2, + 'no-caller': 2, + 'no-cond-assign': [2, 'except-parens'], + 'no-debugger': 2, + 'no-dupe-args': 2, + 'no-dupe-keys': 2, + 'no-empty': 2, + 'no-eval': 2, + 'no-extend-native': 2, + 'no-extra-bind': 2, + 'no-extra-parens': 0, + 'no-func-assign': 2, + 'no-implied-eval': 2, + 'no-invalid-regexp': 2, + 'no-irregular-whitespace': 1, + 'no-iterator': 2, + 'no-loop-func': 2, + 'no-mixed-requires': 0, + 'no-multi-str': 2, + 'no-native-reassign': 2, + 'no-new': 2, + 'no-param-reassign': 1, + 'no-proto': 2, + 'no-redeclare': 0, + 'no-script-url': 2, + 'no-self-assign': 2, + 'no-self-compare': 2, + 'no-sequences': 2, + 'no-shadow': 2, + 'no-undef': 2, + 'no-underscore-dangle': 0, + 'no-unreachable': 1, + 'no-unused-vars': 1, + 'no-use-before-define': 1, + 'no-useless-call': 2, + 'no-useless-concat': 2, + 'no-var': 2, + 'no-with': 2, + quotes: [0, 'single'], + radix: 2, + strict: 0, + 'valid-typeof': 2, + 'vars-on-top': 0, + 'prefer-const': [ + 'error', + { + destructuring: 'any', + ignoreReadBeforeAssign: false, + }, + ], + }, +}; diff --git a/.eslintrc b/.eslintrc.json similarity index 67% rename from .eslintrc rename to .eslintrc.json index d52103feb..335572829 100644 --- a/.eslintrc +++ b/.eslintrc.json @@ -1,29 +1,28 @@ { + "root": true, "env": { "node": true, - "builtin": true + "builtin": true, + "es6": true + }, + "parserOptions": { + "ecmaVersion": 2017, + "sourceType": "module" }, "globals": {}, + "extends": ["prettier"], + "plugins": ["prettier"], "rules": { + "prettier/prettier": "error", "block-scoped-var": 0, "camelcase": 0, - "comma-spacing": [1, {"before": false, "after": true}], "consistent-return": 2, "curly": [2, "all"], "dot-notation": [1, { "allowKeywords": true }], "eqeqeq": [2, "allow-null"], "global-strict": [0, "never"], "guard-for-in": 2, - "indent": [2, 2, {"SwitchCase": 1, "VariableDeclarator": 1}], - "lines-around-comment": [2, { - "beforeBlockComment": true, - "beforeLineComment": true, - "allowBlockStart": true, - "allowObjectStart": true, - "allowArrayStart": true - }], "key-spacing": 0, - "keyword-spacing": 1, "new-cap": 0, "no-alert": 2, "no-bitwise": 2, @@ -37,7 +36,6 @@ "no-extend-native": 2, "no-extra-bind": 2, "no-extra-parens": 0, - "no-extra-semi": 2, "no-func-assign": 2, "no-implied-eval": 2, "no-invalid-regexp": 2, @@ -46,7 +44,6 @@ "no-loop-func": 2, "no-mixed-requires": 0, "no-multi-str": 2, - "no-multi-spaces": 1, "no-native-reassign": 2, "no-new": 2, "no-param-reassign": 1, @@ -64,20 +61,19 @@ "no-use-before-define": 1, "no-useless-call": 2, "no-useless-concat": 2, + "no-var": 2, "no-with": 2, "quotes": [0, "single"], "radix": 2, - "semi": [0, "never"], "strict": 0, - "space-before-blocks": 1, - "space-before-function-paren": [1, { - "anonymous": "always", - "named": "never" - }], - "space-in-parens": [1, "never"], - "space-infix-ops": 1, "valid-typeof": 2, "vars-on-top": 0, - "wrap-iife": [2, "inside"] + "prefer-const": [ + "error", + { + "destructuring": "any", + "ignoreReadBeforeAssign": false + } + ] } } diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 8598cddb2..477f273af 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,15 +1,71 @@ -# Contributing to Patternlab Node +# Contributing to Pattern Lab Node + If you'd like to contribute to Pattern Lab Node, please do so! There is always a lot of ground to cover and something for your wheelhouse. -No pull request is too small. Check out any [up for grabs issues](https://github.com/pattern-lab/patternlab-node/labels/up%20for%20grabs) as a good way to get your feet wet, or add some more unit tests. +No pull request is too small. Check out any [help wanted 🆘](https://github.com/pattern-lab/patternlab-node/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted+%3Asos%3A%22) or [good first issues 🎓](https://github.com/pattern-lab/patternlab-node/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue+%3Amortar_board%3A%22)as a good way to get your feet wet, or add some more unit tests. + +## Prerequisites + +To get started, you'll need Node installed. Managing Node with [nvm](https://github.com/creationix/nvm) is recommended. Once installed, you can target the version of Node we specify within the [`.nvmrc`](https://github.com/pattern-lab/patternlab-node/blob/master/.nvmrc) file. + +```sh +nvm install <> +nvm use <> +``` + +## Developing Locally + +The best way to make changes to the Pattern Lab Node core and test them is through an edition. + +* Fork this repository on Github. +* `npm install && npm run bootstrap` +* Create a new branch in your fork and push your changes in that fork. +* `cd packages/edition-node` +* Test your changes with the edition's api + +### Cold start testing + +To ensure that developers can bootstrap the repo from a fresh clone, do this in your working copy: + +```sh +git reset --hard && git clean -dfx && npm install && npm run bootstrap +``` + +This ensures that any changes you've made will still result in a clean and functional developer experience. **Note**: be sure you've committed any outstanding work before doing this -- it will blow away whatever's still outstanding, including anything staged but not commited. ## Guidelines -1. Please keep your pull requests concise and limited to **ONE** substantive change at a time. This makes reviewing and testing so much easier. -2. _ALWAYS_ submit pull requests against the [dev branch](https://github.com/pattern-lab/patternlab-node/tree/dev). If this does not occur, I will first, try to redirect you gently, second, port over your contribution manually if time allows, and/or third, close your pull request. If you have a major feature to stabilize over time, talk to @bmuenzenmeyer about making a dedicated `feature-branch` -3. If you can, add some unit tests using the existing patterns in the `./test` directory -##Coding style -Two files combine within the project to define and maintain our coding style. +* _ALWAYS_ submit pull requests against the [dev branch](https://github.com/pattern-lab/patternlab-node/tree/dev). If this does not occur, I will first, try to redirect you gently, second, attempt to redirect the target branch myself, thirdly, port over your contribution manually if time allows, and/or lastly, close your pull request. If you have a major feature to stabilize over time, talk to @bmuenzenmeyer via an issue about making a dedicated `feature-branch` +* Keep your pull requests concise and limited to **ONE** substantive change at a time. This makes reviewing and testing so much easier. +* Commits should reference the issue you are adressing. For any Pull Request that you send, use the template provided. +* Commits are best formatted using the [conventional commits pattern](https://conventionalcommits.org/). +* If you can, add some unit tests using the existing patterns in the `.packages/core/test` directory +* Large enhancements should begin with opening an issue. This will result in a more systematic way for us to review your contribution and determine if a [specifcation discussion](https://github.com/pattern-lab/the-spec/issues) needs to occur. +* Mention the issue number in commits, so anyone can see to which issue your changes belong to. For instance: + * `fix(get): Resolve patterns correctly` + * `feat(version): Add ability to ask for version statically` + +## Coding style + +Formatting is automated via [Prettier](https://prettier.io/), setup to run on precommit. We suggest [editor integration](https://prettier.io/docs/en/editors.html) for this and for eslint. Prettier is further configured within `.prettierrc`. Eslint validates syntax and usage that Prettier doesn't handle. Configuration for both is found within the `.eslintrc.json` file. + +The `.editorconfig` controls spaces / tabs within supported editors. Check out their [site](http://editorconfig.org/). + +## Tests + +Add unit and integration tests if you can. It's always nice if our code coverage improves bit by bit (literally!). We are using [Node Tap](http://www.node-tap.org/) as test framework and [Rewire](https://github.com/jhnns/rewire) for mocking things like file system access. + +## Branching Scheme + +![branching scheme](branching-scheme.png) Currently Pattern Lab has the following branches: + +* **master** contains the latext stable, released version +* **dev**: for development. _Target pull requests against this branch._ +* **feature-branches** for larger changes. Allows merging all changes into both `dev` easily. +* **long running branches** for changes that involve major changes to the code, architecture and take a lot of time (i.e. making Pattern Lab async) + +New features are typically cut off of `dev` branch. When `dev` is stable cut releases by merging `dev` to `master` and creating a release tag. + +# Gitter.im Chat -* The `.editorconfig` controls spaces / tabs within supported editors. Check out their [site](http://editorconfig.org/). -* The `.eslintrc` defines our javascript standards. Some editors will evaluate this real-time - otherwise it's run using `grunt|gulp build` +If you have any questions or you would like to help, feel free to ask on [our Gitter.im channel](https://gitter.im/pattern-lab/node) :smiley: diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..5805c3f03 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +# These are supported funding model platforms + +patreon: patternlab diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 21e29ed60..9e5ad2464 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,9 +1,11 @@ -I am using Pattern Lab Node `vX.X.X` on `Windows|Mac|Linux`, using the `grunt|gulp` configuration. + -##### Expected Behavior + +I am using Pattern Lab Node `vX.X.X` on `Windows | Mac | Linux`, with Node `vX.X.X`, using a `Gulp | Grunt | Vanilla | Custom` Edition. -##### Actual Behavior +##### Expected Behavior +##### Actual Behavior ##### Steps to Reproduce diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 4ddf5e12d..0ca02b82c 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,5 +1,5 @@ -Addresses # +Closes # Summary of changes: diff --git a/.github/branching-scheme.png b/.github/branching-scheme.png new file mode 100644 index 000000000..9d7b7628a Binary files /dev/null and b/.github/branching-scheme.png differ diff --git a/.github/gitgraph/README.md b/.github/gitgraph/README.md new file mode 100644 index 000000000..02cc14ca4 --- /dev/null +++ b/.github/gitgraph/README.md @@ -0,0 +1,8 @@ +Generating a new graph +====================== + +This folder uses http://gitgraphjs.com/ for generating the git graph model. + +1. Change `patternlab-flow.js` to your needs according to the documentation on http://gitgraphjs.com/ +2. Open branching-scheme.html in browse, right click the graph and "Save as...". +3. Overwrite `/.github/branching-scheme.png` diff --git a/.github/gitgraph/branching-scheme.html b/.github/gitgraph/branching-scheme.html new file mode 100644 index 000000000..32d2ffb80 --- /dev/null +++ b/.github/gitgraph/branching-scheme.html @@ -0,0 +1,17 @@ + + + + + + + + + + + + diff --git a/.github/gitgraph/patternlab-flow.js b/.github/gitgraph/patternlab-flow.js new file mode 100644 index 000000000..a68910cee --- /dev/null +++ b/.github/gitgraph/patternlab-flow.js @@ -0,0 +1,213 @@ +var graphConfig = new GitGraph.Template({ + colors: [ + '#9993FF', + '#47E8D4', + '#6BDB52', + '#F85BB5', + '#FFA657', + '#FFCCAA', + '#F85BB5', + ], + branch: { + lineWidth: 3, + spacingX: 60, + mergeStyle: 'straight', + showLabel: true, // display branch names on graph + labelFont: 'normal 10pt Arial', + labelRotation: 0, + color: 'black', + }, + commit: { + spacingY: -30, + dot: { + size: 8, + strokeColor: '#000000', + strokeWidth: 4, + }, + tag: { + font: 'normal 10pt Arial', + color: 'yellow', + }, + message: { + color: 'black', + font: 'normal 12pt Arial', + displayAuthor: false, + displayBranch: false, + displayHash: false, + }, + }, + arrow: { + size: 8, + offset: 3, + }, +}); + +var config = { + template: graphConfig, + mode: 'extended', + orientation: 'horizontal', +}; + +var bugFixCommit = { + messageAuthorDisplay: false, + messageBranchDisplay: false, + messageHashDisplay: false, + message: 'Bug fix commit(s)', +}; + +var stabilizationCommit = { + messageAuthorDisplay: false, + messageBranchDisplay: false, + messageHashDisplay: false, + message: 'Release stabilization commit(s)', +}; + +// You can manually fix columns to control the display. +var i = 0; +var longRunningCol = i++; +var featureV3Col = i++; +var developV3Col = i++; +var featureCol = i++; +var developCol = i++; +var releaseCol = i++; +var masterCol = i++; + +var gitgraph = new GitGraph(config); + +var master = gitgraph.branch({ + name: 'master', + column: masterCol, +}); +master.commit('Initial commit'); + +var develop = gitgraph.branch({ + parentBranch: master, + name: 'dev', + column: developCol, +}); + +var developV3 = gitgraph.branch({ + parentBranch: master, + name: 'dev-3.0', + column: developV3Col, +}); + +var longRunning = gitgraph.branch({ + parentBranch: master, + name: 'long-running-improvement', + column: longRunningCol, +}); + +develop.commit({ + messageDisplay: false, +}); +developV3.commit({ + messageDisplay: false, +}); + +longRunning.commit({ + messageDisplay: false, +}); +longRunning.merge(developV3); + +var feature1 = gitgraph.branch({ + parentBranch: develop, + name: 'feature/1-description', + column: featureCol, +}); +feature1.commit('#1 A feature to go into v2.8.0').commit({ + messageDisplay: false, +}); +develop.merge(feature1); +feature1.commit('Small Bugfix').commit({ + messageDisplay: false, +}); +feature1.merge(develop); + +var feature3X = gitgraph.branch({ + parentBranch: developV3, + name: 'feature/42-feature-for-3-x-only', + column: featureV3Col, +}); +feature3X.commit('#42 A feature to go into v3.X').commit({ + messageDisplay: false, +}); +feature3X.merge(developV3); + +var feature2 = gitgraph.branch({ + parentBranch: develop, + name: 'feature/2-description', + column: featureCol, +}); +feature2.commit('#2 Another feature to go into v2.8.0').commit({ + messageDisplay: false, +}); +feature2.merge(develop); +feature2.merge(developV3); + +develop.merge(master, { + dotStrokeWidth: 10, + message: 'Release v2.8.1 tagged', + tag: 'v2.8.1', +}); + +develop.commit({ + messageDisplay: false, +}); + +longRunning.commit({ + messageDisplay: false, +}); + +developV3.merge(longRunning); + +longRunning.commit({ + messageDisplay: false, +}); + +var feature3 = gitgraph.branch({ + parentBranch: develop, + name: 'bugfix/3-description', + column: featureCol, +}); + +feature3.commit('A feature to go into v2.8.0').commit({ + messageDisplay: false, +}); +feature3.merge(develop); + +longRunning.merge(developV3); + +developV3.commit({ + messageDisplay: false, + dotStrokeWidth: 10, +}); + +develop.commit({ + messageDisplay: false, +}); + +develop.commit({ + messageDisplay: false, +}); + +develop.merge(master, { + dotStrokeWidth: 10, + message: 'Release v2.9.0 tagged', + tag: 'v2.9.0', +}); + +develop.commit({ + messageDisplay: false, + dotStrokeWidth: 10, +}); + +developV3.checkout(); + +/* +developV3.merge(master, { + dotStrokeWidth: 10, + message: "Release v3.0.0 tagged", + tag: "v3.0.0" +}); +*/ diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 000000000..5969a91e8 --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,17 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 60 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 30 +# Issues with these labels will never be considered stale +exemptLabels: + - "staged for next release 🏁" + - "pinned 📌" + - "triage 😰" +# Label to use when marking an issue as stale +staleLabel: "needs response 🤙" +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + It's hard to keep track of everything. This issue has been automatically marked as stale because it has not had recent activity, neither from the team nor the community. It will be closed if no further activity occurs. Please consider adding additional info, volunteering to contribute a fix for this issue, or making a further case that this is important to you, the team, and the project as a whole. Thanks! +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: > + Issue closed after going stale. It can be re-opened if still relevant. diff --git a/.gitignore b/.gitignore index 74ab03195..96232f92a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,17 @@ node_modules/ +pattern_exports/ .DS_Store -latest-change.txt -patternlab.json -.sass-cache/* -/sass-cache Thumbs.db -source/css/style.css.map +.nyc_output/ +.vscode/ .idea/ -public +.env +packages/core/test/public +packages/*/public +!packages/core/test/patterns/public/.gitkeep +!packages/core/test/patterns/testDependencyGraph.json +lerna-debug.log +packages/edition-node-gulp/dependencyGraph.json +packages/uikit-workshop/dist + +yarn-error.log diff --git a/.npmignore b/.npmignore new file mode 100644 index 000000000..13dae57b5 --- /dev/null +++ b/.npmignore @@ -0,0 +1,7 @@ +test/ +.DS_Store +.travis.yml +.nyc_output/ +.vscode/ +.idea/ + diff --git a/.npmrc b/.npmrc new file mode 100644 index 000000000..43c97e719 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 000000000..7f976a5ae --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +12.12.0 diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..f25d454d3 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,15 @@ +**/*.json +**/README.md +**/node_modules/ +**/bower_components/ +**/dist/ +**/public/ +**/*.min.js +packages/core/scripts/api.handlebars +packages/core/scripts/events.handlebars +packages/core/test/files/annotations.js +packages/**/annotations.js +**/uikit-workshop/src/js/**/* +*.json +*.md +*.scss diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..c1a6f6671 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +{ + "singleQuote": true, + "trailingComma": "es5" +} diff --git a/.travis.yml b/.travis.yml index 611cfd7d6..3fb4c3593 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,18 +1,34 @@ language: node_js -node_js: - - stable - - 4.0 - - 0.12 - - 0.11 +addons: + chrome: stable before_install: - - phantomjs --version + # version lifted from `.nvmrc` + - nvm install + - curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.19.0 + - export PATH="$HOME/.yarn/bin:$PATH" before_script: - - npm install -g grunt-cli + - yarn run setup + - npx lerna add @pattern-lab/engine-mustache --scope=@pattern-lab/core + - npx lerna add @pattern-lab/engine-handlebars --scope=@pattern-lab/core + - npx lerna add @pattern-lab/engine-underscore --scope=@pattern-lab/core + - npx lerna add @pattern-lab/engine-liquid --scope=@pattern-lab/core + - npx lerna add @pattern-lab/engine-twig --scope=@pattern-lab/core + - npx lerna add @pattern-lab/engine-react --scope=@pattern-lab/core + +script: travis_wait yarn run test branches: only: - master - dev + +notifications: + webhooks: + urls: + - https://webhooks.gitter.im/e/a14f537f16b0756d9470 + on_success: always + on_failure: always + on_start: never diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..ddc797b61 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,396 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [5.9.3](https://github.com/pattern-lab/patternlab-node/compare/v5.9.2...v5.9.3) (2020-05-01) + + +### Bug Fixes + +* **plugintabs:** enabling multiple file formats [#1163](https://github.com/pattern-lab/patternlab-node/issues/1163) ([bb5e817](https://github.com/pattern-lab/patternlab-node/commit/bb5e8179e6b8553a6e1af0bede26db412b6c0b68)) +* adjust UIKit Nav updates to account for the noViewAll config variation ([73eac97](https://github.com/pattern-lab/patternlab-node/commit/73eac976461f4e587b0c30668942c4895aea319f)) +* make sure the top-level Dropdown menus always open/close ([7a8b418](https://github.com/pattern-lab/patternlab-node/commit/7a8b418bfcbd200ef8b2802b1a07964a9995bf9f)) +* only allow one top level nav item to be open at a time while rendering as a dropdown menu ([409bef3](https://github.com/pattern-lab/patternlab-node/commit/409bef37165260d9b728013ac33e7aa67541c832)) +* re-try Netlify preview to debug local vs prod rendering differences ([6da41a1](https://github.com/pattern-lab/patternlab-node/commit/6da41a14feea034f891c745dfeb062fa3b196235)) +* Update dependency on twing JS engine ([cfe88c6](https://github.com/pattern-lab/patternlab-node/commit/cfe88c6cdbf2219b9955eaa0ffcfc0e4a7683511)) +* **cli:** fix test script glob ([ff18eb5](https://github.com/pattern-lab/patternlab-node/commit/ff18eb51ce24fc5423b009168e85ede366069139)) + + + + + +## [5.9.2](https://github.com/pattern-lab/patternlab-node/compare/v5.9.1...v5.9.2) (2020-04-24) + +**Note:** Version bump only for package pl-node + + + + + +## [5.9.1](https://github.com/pattern-lab/patternlab-node/compare/v5.9.0...v5.9.1) (2020-04-24) + + +### Bug Fixes + +* **cli:** ensure specified directory exists prior to scaffold ([cc3b696](https://github.com/pattern-lab/patternlab-node/commit/cc3b69624d486c94ee3b1f4b1bbb0334a514fa59)) + + + + + +# [5.9.0](https://github.com/pattern-lab/patternlab-node/compare/v5.8.0...v5.9.0) (2020-04-24) + + +### Bug Fixes + +* **cli:** set current working directory before scaffolded npm init ([6d2186d](https://github.com/pattern-lab/patternlab-node/commit/6d2186d8e8a74634198a4474ca8ae83221dd70a9)) +* **core:** do not warn about uikit-polyfills ([6bb68e7](https://github.com/pattern-lab/patternlab-node/commit/6bb68e763769969546542bf7aaf6d1f4235c6622)) +* actually exit build when Twig render fails ([5d28a24](https://github.com/pattern-lab/patternlab-node/commit/5d28a24a53011396289c1e29e0a715cd82470185)) +* Update packages/engine-twig-php/lib/engine_twig_php.js ([c67d50e](https://github.com/pattern-lab/patternlab-node/commit/c67d50ebb5d69816b7514e85f129f8ecde984ad3)) + + +### Features + +* **docs:** yarnify ([5a47dc7](https://github.com/pattern-lab/patternlab-node/commit/5a47dc7b90dc5c43c12a51143b41943dcbd8564c)) +* **README:** add netlify badges ([941df8a](https://github.com/pattern-lab/patternlab-node/commit/941df8a59b6b75bc1255646005f329e40be68106)) + + + + + +# [5.8.0](https://github.com/pattern-lab/patternlab-node/compare/v5.7.2...v5.8.0) (2020-04-03) + + +### Bug Fixes + +* the namespace notation should not be mixed with PatternLab shorthand pattern naming & name is not defined in the textarea macro ([8250fe8](https://github.com/pattern-lab/patternlab-node/commit/8250fe88231d03735424d597eae40496da2cb48c)) +* Updated the README to reflect which issues are resolved. ([d90c3c4](https://github.com/pattern-lab/patternlab-node/commit/d90c3c4605f9a5bcd1153996e3f4d1a17d58bd92)) + + +### Features + +* switch engine-twig to use twing rather than node-twig ([daca95c](https://github.com/pattern-lab/patternlab-node/commit/daca95c4ffa48916fb6c67c5184bde9b624acd76)) + + + + + +## [5.7.2](https://github.com/pattern-lab/patternlab-node/compare/v5.7.1...v5.7.2) (2020-03-24) + + +### Bug Fixes + +* update iframe resizer UI to be hidden when iframe is full width ([9797c1a](https://github.com/pattern-lab/patternlab-node/commit/9797c1a047d746d21b88a1f57b57f618a03a54df)) + + + + + +## [5.7.1](https://github.com/pattern-lab/patternlab-node/compare/v5.7.0...v5.7.1) (2020-02-24) + + +### Bug Fixes + +* update twig-renderer ([46f53b7](https://github.com/pattern-lab/patternlab-node/commit/46f53b79f8bb0bb64a9c55fd32f29459cea6e28c)) + + + + + +# [5.7.0](https://github.com/pattern-lab/patternlab-node/compare/v5.6.0...v5.7.0) (2020-02-17) + + +### Features + +* **cli:** make options more user friendly ([ad845b3](https://github.com/pattern-lab/patternlab-node/commit/ad845b394ef81f90895ebb5bc6f12cc608e5e3d4)) + + + + + +# [5.6.0](https://github.com/pattern-lab/patternlab-node/compare/v5.5.0...v5.6.0) (2020-01-18) + + +### Bug Fixes + +* a11y fix on text contrast ([6d75b22](https://github.com/pattern-lab/patternlab-node/commit/6d75b226ce27228025b2915e5d402f7080faee31)) +* a11y issue on a missing description of that complementary icon ([4f13807](https://github.com/pattern-lab/patternlab-node/commit/4f13807cb93df33435088de3a51170b9c4515889)) + + +### Features + +* pass additional configuration into twig-php engine ([dff5a78](https://github.com/pattern-lab/patternlab-node/commit/dff5a7830918fa46e2692d9f9daed4121f803461)) + + + + + + +# [5.5.0](https://github.com/pattern-lab/patternlab-node/compare/v5.4.2...v5.5.0) (2019-12-19) + + +### Features + +* upgrade Twig to use new filter, map, reduce ([4218a5a](https://github.com/pattern-lab/patternlab-node/commit/4218a5a04b06027548afd9f417486297dd25fef8)) + + + + + +## [5.4.2](https://github.com/pattern-lab/patternlab-node/compare/v5.4.1...v5.4.2) (2019-11-27) + +**Note:** Version bump only for package pl-node-pr + + + + + +## [5.4.1](https://github.com/pattern-lab/patternlab-node/compare/v5.4.0...v5.4.1) (2019-11-26) + + +### Bug Fixes + +* temp workaround to address instance where the latest version of Edge supports ES modules but NOT Custom Elements ([ada3d82](https://github.com/pattern-lab/patternlab-node/commit/ada3d829019345fd33ed949f306972efdcb4fa57)) + + + + + +# [5.4.0](https://github.com/pattern-lab/patternlab-node/compare/v5.3.3...v5.4.0) (2019-11-26) + + +### Bug Fixes + +* re-add popstate listener ([6dbbd6a](https://github.com/pattern-lab/patternlab-node/commit/6dbbd6aae3709cc17544c12dd10588120eb9e71a)) +* **script:** remove quotes around starterkit ([e4897fb](https://github.com/pattern-lab/patternlab-node/commit/e4897fb6e4d4cd0985ab72397abd03ff04be514b)) +* add a new method to check if PL is currently compiling + add new method to get the config PL is using ([26e886c](https://github.com/pattern-lab/patternlab-node/commit/26e886c93db5d135c91de648724f7278c4d5b3e9)) +* check if dependency graph file exists before trying to remove ([f9af6a9](https://github.com/pattern-lab/patternlab-node/commit/f9af6a95025a22041e7ff8a4bfb19e4727385e98)) +* comment out example config to disable viewAll links ([ddb3fad](https://github.com/pattern-lab/patternlab-node/commit/ddb3fad5770d1d66432c4b583ae9af09a3a47d48)) + + +### Features + +* add the ability to disable Pattern Lab viewall links in the navigation ([156e609](https://github.com/pattern-lab/patternlab-node/commit/156e609a92e7f7e7ebd8f4f5cd77b5d695db8bad)) +* major improvements to local UIKit workflow ([4dc9173](https://github.com/pattern-lab/patternlab-node/commit/4dc9173a5a44b422e9677824de3728048b7c4f05)) +* test adding cross-env to Twig Edition test ([3f8bb01](https://github.com/pattern-lab/patternlab-node/commit/3f8bb01bc4e96a0aba61c213ea1619c02593defc)) + + + + + +## [5.3.3](https://github.com/pattern-lab/patternlab-node/compare/v5.3.2...v5.3.3) (2019-11-22) + + +### Bug Fixes + +* simplify overflow fix ([378cf42](https://github.com/pattern-lab/patternlab-node/commit/378cf4282a3e5b4f597287eb538270e3358c8c69)) +* testing potential FF fix for https://github.com/pattern-lab/patternlab-node/issues/1100 ([613bba1](https://github.com/pattern-lab/patternlab-node/commit/613bba104f2082be507938db78f1db7a07f6b8be)) + + + + + + +## [5.3.2](https://github.com/pattern-lab/patternlab-node/compare/v5.3.1...v5.3.2) (2019-11-14) + +**Note:** Version bump only for package pl-node + + + + + +## [5.3.1](https://github.com/pattern-lab/patternlab-node/compare/v5.3.0...v5.3.1) (2019-11-13) + + +### Bug Fixes + +* CSS fix to properly highlight the correct active page / link in the Nav; improve dropdown open / close animation ([ec4ab84](https://github.com/pattern-lab/patternlab-node/commit/ec4ab84ddc8007796c9012a3f493822d76f039a7)) +* small UI fixes for the sticky Tabs header on smaller screens + drawer content collapsing on smaller screens + better handling of Nav link cleanup when changing pages ([347e2fe](https://github.com/pattern-lab/patternlab-node/commit/347e2fe29a78a1d168005a07c656b4f9f1124c7f)) +* tweak header and drawer padding when viewing on a device with curved edges ([98e9baf](https://github.com/pattern-lab/patternlab-node/commit/98e9baf649eceb9124218a924b6b08097b910e86)) +* uikit fixes and minor CSS updates intended for the v5.3.0 release ([26c4ced](https://github.com/pattern-lab/patternlab-node/commit/26c4ceddaae09fa4fa4873f092c924274498c5da)) + + + + + +# [5.3.0](https://github.com/pattern-lab/patternlab-node/compare/v5.2.0...v5.3.0) (2019-11-13) + + +### Bug Fixes + +* add PluginTab workaround for Safari ([2fa9367](https://github.com/pattern-lab/patternlab-node/commit/2fa936769be65484af52f242dca2536a3382462c)) +* **core:** re-add cleanPublic fix ([c100bbc](https://github.com/pattern-lab/patternlab-node/commit/c100bbca3f339e9132acb9c482e98c1c8a66b8b5)) +* **plugin-tab:** defensively call addPanels ([b82bd12](https://github.com/pattern-lab/patternlab-node/commit/b82bd129fdbe48de95b62d75fb7fe95cea896b7e)) +* port over missing UIKit Sass that wasn't added in the original PR ([f7659e6](https://github.com/pattern-lab/patternlab-node/commit/f7659e64d0eee13be20921dd5afc48ac20ae93e6)) + + +### Features + +* port latest UIKit updates + fixes upstream ([d07952c](https://github.com/pattern-lab/patternlab-node/commit/d07952cb07e3792b995dda2e589262ecf4153fdc)) + + + + + +# [5.2.0](https://github.com/pattern-lab/patternlab-node/compare/v5.1.0...v5.2.0) (2019-11-12) + + +### Bug Fixes + +* **deploy:** add setup command ([7c1d8d1](https://github.com/pattern-lab/patternlab-node/commit/7c1d8d14842a467bb301e2ede2ec83074ff35ae2)) +* add missing $ ([c95a06e](https://github.com/pattern-lab/patternlab-node/commit/c95a06ece78631b068f8721666caf33452e57a7a)) +* address bug causing viewport width to progressively decrease in size when resizing your screen / refreshing on certain devices ([41b11af](https://github.com/pattern-lab/patternlab-node/commit/41b11af8aaaf066fcf99abd2513eae8706122d32)) +* configure the Logo's `altText` config option when used as an HTML attribute ([ade34a2](https://github.com/pattern-lab/patternlab-node/commit/ade34a29435f5112f0449ad020bee7e9dc2c81e1)) +* fix classname typo ([da3c5f1](https://github.com/pattern-lab/patternlab-node/commit/da3c5f144d22b1ac3ad99680a264433d4438ebb2)) +* temp workaround to fix content exceeding the height of drawer container ([435243c](https://github.com/pattern-lab/patternlab-node/commit/435243cbfbd000a7d96a0e9fa7beff1a988ede64)) +* update drawer UI to not collapse content on smaller screen sizes ([7147085](https://github.com/pattern-lab/patternlab-node/commit/71470856b8b389421348366afd247a599d1e9c86)) +* update package.json description in `@pattern-lab/uikit-polyfills` ([22fc44a](https://github.com/pattern-lab/patternlab-node/commit/22fc44a4b3683753a469a98abfcdad8f1234f28a)) +* **engine_twig_php:** Allow additional flexibility with twig namespaces. ([07bfaa3](https://github.com/pattern-lab/patternlab-node/commit/07bfaa35a00ff62fd2016cc9f34e09cf5af36559)) + + +### Features + +* add lit-element, basic Typescript support to Webpack ([611f705](https://github.com/pattern-lab/patternlab-node/commit/611f705be85eea8a31091169750d64e988798cee)) +* add local copy of new Slotify library till published to NPM ([63b9d83](https://github.com/pattern-lab/patternlab-node/commit/63b9d833908151ce5cb5aa5184c72254125c7ed1)) +* add new component to make Button-like styles more reusable ([5e7b014](https://github.com/pattern-lab/patternlab-node/commit/5e7b0140622eb89154c38925769a6def6d669fb3)) +* add new component ([e8ce2a9](https://github.com/pattern-lab/patternlab-node/commit/e8ce2a927365b8d5316a7d8229c979ff31b04907)) +* add support for auto-closing Nav when clicking inside of the rendered iframe ([9d602fe](https://github.com/pattern-lab/patternlab-node/commit/9d602fe335a5d3b5bca5cac258c2465934d9a46a)) +* add support for optional chaining syntax via Babel plugin ([c8886b6](https://github.com/pattern-lab/patternlab-node/commit/c8886b6d9d91fea246fa3ab7947f289509dc26d5)) +* major refactoring + UI updates to address cross browser support; UI cleanup and conversion of the majority of the remaining components over to lit-element ([2ff8e1c](https://github.com/pattern-lab/patternlab-node/commit/2ff8e1c98cdd02e8077064c48eca5f7754a3db02)) +* refactor + convert pl-toggle-info to lit-element ([85cd9c5](https://github.com/pattern-lab/patternlab-node/commit/85cd9c50ca814066bf999badf2071d84964f00cc)) +* refactor + convert pl-toggle-layout to lit-element ([46009d9](https://github.com/pattern-lab/patternlab-node/commit/46009d91b1cb9ed613baa5a7626cba4f42883465)) +* refactor + convert pl-toggle-theme to lit-element ([95a3b21](https://github.com/pattern-lab/patternlab-node/commit/95a3b21a89dacd2d5b4df8c134ce438d4efdbd04)) +* refactor Drawer to render via lit-element + massively improve rendering performance ([28d47eb](https://github.com/pattern-lab/patternlab-node/commit/28d47eb3cbbce038204203e786e5188b4cefe64f)) +* remove mixin that was causing outlines to be removed from default UI styles ([622ed76](https://github.com/pattern-lab/patternlab-node/commit/622ed76d435b3b2e31e412266c3090506f98051b)) +* temp add unsafe-svg directive till upstream PR merged ([34de61c](https://github.com/pattern-lab/patternlab-node/commit/34de61ccd9c7bb3b48ca5ef386a87efc8e84babc)) +* update the Nav design to not bold the active item in order to not shift the layout ([0eda431](https://github.com/pattern-lab/patternlab-node/commit/0eda4312ba9f4c61afa6322c3ff45f9cda0efc9e)) +* update Webpack config to use the latest Style Loader + new SVG icon system ([2ed70e7](https://github.com/pattern-lab/patternlab-node/commit/2ed70e79d8656c7314d8b3109aa1c34160ad24f9)) + + + + + + +# [5.1.0](https://github.com/pattern-lab/patternlab-node/compare/v5.0.2...v5.1.0) (2019-10-29) + + +### Features + +* **config:** add new default pattern export options ([a7487a0](https://github.com/pattern-lab/patternlab-node/commit/a7487a0681cb11e6f3c5c8eaefd62e5648ad5ea3)) + + + + + +## [5.0.2](https://github.com/pattern-lab/patternlab-node/compare/v5.0.1...v5.0.2) (2019-10-28) + + +### Bug Fixes + +* **uikit-workshop:** add template files to published bundle ([9005fce](https://github.com/pattern-lab/patternlab-node/commit/9005fcee9e129fb41d509f706195e1437bddc710)) +* **uikit-workshop:** add webpack config to published bundle ([060a573](https://github.com/pattern-lab/patternlab-node/commit/060a573cbddce9ee3d270d39337d0c8cac8372fa)) + + + + + +## [5.0.1](https://github.com/pattern-lab/patternlab-node/compare/v5.0.0...v5.0.1) (2019-10-28) + + +### Bug Fixes + +* add missing “dist” folder to array of files / folders published to NPM ([8829429](https://github.com/pattern-lab/patternlab-node/commit/88294296c438352570befd2eb6b9e1ca2ae3b750)) + + + + + +# [5.0.0](https://github.com/pattern-lab/patternlab-node/compare/v3.0.0-beta.3...v5.0.0) (2019-10-25) + + +### Bug Fixes + +* **1049:** Treat folders like patterns only if they're subfolders of pattern groupings ([4eb79ab](https://github.com/pattern-lab/patternlab-node/commit/4eb79ab48b335a35b2e5ed3b7053974b8e8bb6b6)) +* **cli:** add custom install logic to edition-node ([f04fd26](https://github.com/pattern-lab/patternlab-node/commit/f04fd266429cd806987dab747e6d69bff9b926a4)) +* **cli:** allow any package to be installed as a starterkit ([d2aa1be](https://github.com/pattern-lab/patternlab-node/commit/d2aa1be810a0a7473dcc52391a2263dacfdda0b8)), closes [#1067](https://github.com/pattern-lab/patternlab-node/issues/1067) +* **cli:** merge config arrays via overwrite instead of concatenate ([42e5f7b](https://github.com/pattern-lab/patternlab-node/commit/42e5f7b42a26b4fc1f262c68ee4b474b546f2eac)) +* **cli:** proper path resolution to helpers ([a18fe5e](https://github.com/pattern-lab/patternlab-node/commit/a18fe5ef4d1c074a5eba8bfa255ebbee2261bf74)) +* **cli:** re-order and clarify engines ([e39e301](https://github.com/pattern-lab/patternlab-node/commit/e39e301a33306c6615fabf64262f1893ca682b97)) +* **core:** allow plugin resolution to follow normal algorithm ([3f6b83b](https://github.com/pattern-lab/patternlab-node/commit/3f6b83be080c88aec1d8b73bececb76f0f57a79d)) +* **core:** find plugins from config only and with simpler args ([fe7351c](https://github.com/pattern-lab/patternlab-node/commit/fe7351cba346425512cbb2ef3a1b7728ab06ae60)) +* **deploy:** add setup command ([74dd314](https://github.com/pattern-lab/patternlab-node/commit/74dd3142bf48873a9f1ec4e8dccb8aa2fef9001d)) +* **engine_twig_php:** Pseudo patterns Twig PHP ([226aa8b](https://github.com/pattern-lab/patternlab-node/commit/226aa8bbaaf5e418530ccf54a28f6c5657ee6dea)), closes [#1045](https://github.com/pattern-lab/patternlab-node/issues/1045) +* **engine_twig_php:** Twig incremental rebuilds ([1ade945](https://github.com/pattern-lab/patternlab-node/commit/1ade9451840b2645706a0b01129e2b697dc22d4b)), closes [#1015](https://github.com/pattern-lab/patternlab-node/issues/1015) +* **engine_twig_php:** Twig incremental rebuilds ([5d33f24](https://github.com/pattern-lab/patternlab-node/commit/5d33f24f156ebe50900701513a855de7de608dcf)), closes [#1015](https://github.com/pattern-lab/patternlab-node/issues/1015) +* **lerna:** typo in config ([525a47b](https://github.com/pattern-lab/patternlab-node/commit/525a47b51fba91c1bf5b7439735f48eb7dfa073e)) +* **lint:** Use const instead of var ([ad1e782](https://github.com/pattern-lab/patternlab-node/commit/ad1e782ef71295eb610f56d019eaa35499fb3f85)) +* **plugin:** correct spelling error and function locations ([d4abd88](https://github.com/pattern-lab/patternlab-node/commit/d4abd88cb017550002407241b5045a2ad1adb1dc)) +* **plugin-tab:** bump lodash from 4.17.5 to 4.17.15 in /packages/plugin-tab ([#1081](https://github.com/pattern-lab/patternlab-node/issues/1081)) ([3f89dda](https://github.com/pattern-lab/patternlab-node/commit/3f89dda1685874e251f9777f969c0943e0080881)) +* **plugin-tab:** handle params correctly ([d248993](https://github.com/pattern-lab/patternlab-node/commit/d2489939bb0db1a1d67b0e7f47dfb1838b88b0a0)) +* **starterkit:** add css output and build command ([ccb2d35](https://github.com/pattern-lab/patternlab-node/commit/ccb2d3569b741220324a3fa738ab3d4d2eb97ffe)) +* add better pre-rendering support ([8ecd615](https://github.com/pattern-lab/patternlab-node/commit/8ecd6159a89232f42e0a9dc3c688b6e21de8fc30)) +* add eslint fixes ([00d7bbe](https://github.com/pattern-lab/patternlab-node/commit/00d7bbe319ea77a6ee8cc9cd0348856feaaf13ad)) +* add missing @babel/runtime package to address silent error getting thrown on Travis ([1918d04](https://github.com/pattern-lab/patternlab-node/commit/1918d042d7e90cc8aaa2fdfcd8649961c0a5dd50)) +* add missing preact-render-to-string library ([881296a](https://github.com/pattern-lab/patternlab-node/commit/881296a2c256424beac28bd560c5b1a5e1fed005)) +* add repo info to root package.json so Auto knows what repo to configure for ([85142e8](https://github.com/pattern-lab/patternlab-node/commit/85142e8e94549edd7980459e5975d0639c34864d)) +* address unrelated eslint errors from PL core ([6ada00d](https://github.com/pattern-lab/patternlab-node/commit/6ada00d396eb436837f7453664bfa50522a2ec10)) +* correct typo in build logging ([96d989f](https://github.com/pattern-lab/patternlab-node/commit/96d989f8869630ba9f59705bfca66755f20e35ab)) +* fall back to seeing the current pattern's query string to `all` or the defaultPattern value if undefined when the iframe page initially loads ([a368459](https://github.com/pattern-lab/patternlab-node/commit/a3684590fca02cf96b99421b87a0ad0a711893ad)) +* fix incorrect Webpack version in package.json ([9788e89](https://github.com/pattern-lab/patternlab-node/commit/9788e8977921e31fe43f2a1ec19d4684dd4709c5)) +* fix issue with viewport height exceeding the space available ([95cd1cf](https://github.com/pattern-lab/patternlab-node/commit/95cd1cfa57f086ecb84ac2e996ecda81f0c6a1a6)) +* fix Prism.js typo so languages not found / supported don't throw a JS error ([a8c19f9](https://github.com/pattern-lab/patternlab-node/commit/a8c19f9f9b11d4abbdcd9e573fb0cb418d665660)) +* fix Twig Edition examples by adding missing Twig namespaces to config ([b4c20ef](https://github.com/pattern-lab/patternlab-node/commit/b4c20ef88ee0d3010760584c6f05ff7f92b711a6)) +* minor CSS fixes + fresh prod build ([8ac2c1f](https://github.com/pattern-lab/patternlab-node/commit/8ac2c1fa1c7558ed2ac50755f599a438d682ee2a)) +* re-enable displaying the top level `All` link if PL isn't configured to hide this specific link in the ishControlsHide config option. Addresses [#1048](https://github.com/pattern-lab/patternlab-node/issues/1048) ([6bb4e1a](https://github.com/pattern-lab/patternlab-node/commit/6bb4e1ac6f38b47f93030c8c5bca62d5db2132e4)) +* re-enable using the defaultPattern config for the initial iframe page load if defined ([d645ea1](https://github.com/pattern-lab/patternlab-node/commit/d645ea15150061d7ad13741d2dc37b12b9786411)) +* regenerate fresh UIKit build after fixing main JS issues ([9ea34d2](https://github.com/pattern-lab/patternlab-node/commit/9ea34d2efe43cafacb3729ac113121ba51126344)) +* Rename Handlebars and Nunjucks extension setting to "extend" ([74e5af2](https://github.com/pattern-lab/patternlab-node/commit/74e5af28c4e714fdfc1db535b94c52f3dc14a3a4)) +* squashing minor UI bugs ([a8a606c](https://github.com/pattern-lab/patternlab-node/commit/a8a606cfb224f7041f53ff5026a84e13fa17914c)) +* temporarily disable Random and Disco viewport controls until the full JS logic for these is re-enabled ([14b9a19](https://github.com/pattern-lab/patternlab-node/commit/14b9a19e4dee9462f3784eae28066893cc893624)) +* temporarily downgrade Preact version so tooltip used for displaying viewport sizes renders correctly ([52dcf85](https://github.com/pattern-lab/patternlab-node/commit/52dcf85e756ee171ca993288d98f5b5ef9a0a24b)) +* update autoprefixer browserslist config to address warning messages ([5e52f2b](https://github.com/pattern-lab/patternlab-node/commit/5e52f2b0ed02e2002ca867368636c3c0dc79ff0a)) +* update initial PL iframe path default ([a26fbb9](https://github.com/pattern-lab/patternlab-node/commit/a26fbb956e13901d1751c435b76de65637191ca4)) +* update Javascript to address merge conflict issue with previous PR merge / recent release ([cf2ecc1](https://github.com/pattern-lab/patternlab-node/commit/cf2ecc154383c3e8abd56dc88484370bc58ac30b)) +* update styles for pattern state dots ([7728acc](https://github.com/pattern-lab/patternlab-node/commit/7728accc9a6e5cd83be451f7d74e522dfe721cad)) +* update the default pattern that displays in the Handlebars demo ([ff1d85f](https://github.com/pattern-lab/patternlab-node/commit/ff1d85f2852fc4f210841e8e0aaf14b55165ce58)) +* **starterkit:** remove config file ([f90e38a](https://github.com/pattern-lab/patternlab-node/commit/f90e38aa873dcff0dd08fe4dabc3b71bf95080b6)) +* **starterkit:** use handlebars meta files ([d8f5e12](https://github.com/pattern-lab/patternlab-node/commit/d8f5e12471bd783bd3755626701ecc17669fc761)) +* updates to address eslint / prettier issues ([d945acc](https://github.com/pattern-lab/patternlab-node/commit/d945acc13b8e4e36f3815b017fbc12266c323d1f)) +* updates to fix eslint / prettier issues; update packages/core to reuse root .eslintrc.js file ([5b7a057](https://github.com/pattern-lab/patternlab-node/commit/5b7a057d46ccd16b5832af1441030c7b76f237a8)) +* use 100% of the screen available when JS is disabled / the first time the iframe loads up ([c0c5bff](https://github.com/pattern-lab/patternlab-node/commit/c0c5bff7a63b157d5b81dc2bcecee9e732ecfd4e)) +* **uikit:** clear out "404" responses when loading tabs ([73874b1](https://github.com/pattern-lab/patternlab-node/commit/73874b1b0b66ca6425c2b74331d417efdb529e2e)) +* **uikit-workshop:** fix merge problem ([d245b3b](https://github.com/pattern-lab/patternlab-node/commit/d245b3bca044c29f281052bf2feb95eeffafcf6b)) + + +### Features + +* **core:** invoke registered plugin hooks ([a54d775](https://github.com/pattern-lab/patternlab-node/commit/a54d7753b6939fe6a58da543f4fb34f64dd8901a)) +* **edition-node:** switch to engine-handlebars ([b481e22](https://github.com/pattern-lab/patternlab-node/commit/b481e22dc1f41ddd4da709621640a15190fba257)) +* **engine-handlebars:** Default location for helpers, like engine-nunjucks ([11c4180](https://github.com/pattern-lab/patternlab-node/commit/11c41805e0c3dbebb7109719c4f3c780d32feab5)) +* **engine-handlebars:** Demonstration of custom Handlebars helper ([f330b5b](https://github.com/pattern-lab/patternlab-node/commit/f330b5bca72f2f34bfafe5c2c64e6b0b8823eb1c)) +* **engine-handlebars:** Document the Helpers feature ([a01e040](https://github.com/pattern-lab/patternlab-node/commit/a01e040429a7f77dfeb28d67c690e835b97881de)) +* **engine-handlebars:** Load Handlebars helpers specified in the config ([a12df36](https://github.com/pattern-lab/patternlab-node/commit/a12df36d2a644dfac8ded1dfd94b987e99c29d79)) +* **engine-nunjucks:** Configurable extension locations; Use usePatternlabConfig() ([e54e3b3](https://github.com/pattern-lab/patternlab-node/commit/e54e3b3d48f934d3a4d44b9f4ff262f742a4aaf9)) +* **engine-react:** set package to private ([3aea881](https://github.com/pattern-lab/patternlab-node/commit/3aea8815f19df5b527cdda0b75cf99a9a8c3bc1e)) +* **plugin-tab:** pivot to using hook functions ([d4b2598](https://github.com/pattern-lab/patternlab-node/commit/d4b25984fc2a2646cc1876a5c635f57593c35f09)) +* **plugin-tab, core:** initial plugin hook exploration ([2f3d39a](https://github.com/pattern-lab/patternlab-node/commit/2f3d39ac6b125ad4c6b872e27ee224ce2ea33a12)) +* **starterkits:** add starterkit-handlebars-demo ([384d2cf](https://github.com/pattern-lab/patternlab-node/commit/384d2cfa3440c1e6f456d39f56ca6381f82f7689)) +* **uikit-workshop:** add plugin-loader ([fc966d6](https://github.com/pattern-lab/patternlab-node/commit/fc966d6b151e24055bc2f4146d6a90b5fb392765)) +* introduce netlify preview ([6c5d332](https://github.com/pattern-lab/patternlab-node/commit/6c5d332479fb6836bd8bd5530a074d13440f8ae4)) +* remove pre-built uikit dist folder and switch to auto-building when bootstrapping OR when publishing to NPM ([b5dd553](https://github.com/pattern-lab/patternlab-node/commit/b5dd5538ee00ddf1da321851865fa1c223cedb43)) +* switch to Yarn + Yarn workspaces ([f4c4ec3](https://github.com/pattern-lab/patternlab-node/commit/f4c4ec33cd30d372c87ffa904fbe7d5b819ee14e)) +* update Node to v12 ([fcbb970](https://github.com/pattern-lab/patternlab-node/commit/fcbb970648cdd775c9a88078f14c1f24c5b62d73)) + + +### Reverts + +* don't flatten folders containing only one item inside ([77f1f46](https://github.com/pattern-lab/patternlab-node/commit/77f1f46595328bd96fba46347b532295c65802d1)) + + +### BREAKING CHANGES + +* **core:** plugins now use async functions instead of events +* **plugin-tab:** event based listeners replaced with functions +* **cli:** previously, we concatenated arrays, which is unlikely to be intended +* **edition-node:** use handlebars over mustache diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 000000000..75ecbe287 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,17 @@ +# This is a comment. +# Each line is a file pattern followed by one or more owners. + +# These owners will be the default owners for everything in +# the repo. Unless a later match takes precedence, +# @global-owner1 and @global-owner2 will be requested for +# review when someone opens a pull request. +@pattern-lab/trusted-committers + +# CLI owner +/packages/cli @raphaelokon + +# uikit-workshop owner +/packages/uikit-workshop @sghoweri + +# engine-nunjucks owner +/packages/engine-nunjucks @danwhite85 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..9f536bcc4 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at brian.muenzenmeyer@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/Gruntfile.js b/Gruntfile.js deleted file mode 100644 index 2fbe7d31f..000000000 --- a/Gruntfile.js +++ /dev/null @@ -1,168 +0,0 @@ -module.exports = function (grunt) { - - var path = require('path'); - - function paths() { - return require('./patternlab-config.json').paths; - } - - // Project configuration. - grunt.initConfig({ - pkg: grunt.file.readJSON('package.json'), - concat: { - options: { - stripBanners: true, - banner: '/* \n * <%= pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy") %> \n * \n * <%= pkg.author %>, and the web community.\n * Licensed under the <%= pkg.license %> license. \n * \n * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. \n *\n */\n\n', - }, - patternlab: { - src: './core/lib/patternlab.js', - dest: './core/lib/patternlab.js' - }, - object_factory: { - src: './core/lib/object_factory.js', - dest: './core/lib/object_factory.js' - }, - lineage: { - src: './core/lib/lineage_hunter.js', - dest: './core/lib/lineage_hunter.js' - }, - media_hunter: { - src: './core/lib/media_hunter.js', - dest: './core/lib/media_hunter.js' - }, - patternlab_grunt: { - src: './core/lib/patternlab_grunt.js', - dest: './core/lib/patternlab_grunt.js' - }, - patternlab_gulp: { - src: './core/lib/patternlab_gulp.js', - dest: './core/lib/patternlab_gulp.js' - }, - parameter_hunter: { - src: './core/lib/parameter_hunter.js', - dest: './core/lib/parameter_hunter.js' - }, - pattern_exporter: { - src: './core/lib/pattern_exporter.js', - dest: './core/lib/pattern_exporter.js' - }, - pattern_assembler: { - src: './core/lib/pattern_assembler.js', - dest: './core/lib/pattern_assembler.js' - }, - pseudopattern_hunter: { - src: './core/lib/pseudopattern_hunter.js', - dest: './core/lib/pseudopattern_hunter.js' - }, - list_item_hunter: { - src: './core/lib/list_item_hunter.js', - dest: './core/lib/list_item_hunter.js' - }, - style_modifier_hunter: { - src: './core/lib/style_modifier_hunter.js', - dest: './core/lib/style_modifier_hunter.js' - } - }, - copy: { - main: { - files: [ - { expand: true, cwd: path.resolve(paths().source.js), src: '*.js', dest: path.resolve(paths().public.js) }, - { expand: true, cwd: path.resolve(paths().source.css), src: '*.css', dest: path.resolve(paths().public.css) }, - { expand: true, cwd: path.resolve(paths().source.images), src: ['**/*.png', '**/*.jpg', '**/*.gif', '**/*.jpeg'], dest: path.resolve(paths().public.images) }, - { expand: true, cwd: path.resolve(paths().source.fonts), src: '*', dest: path.resolve(paths().public.fonts) }, - { expand: true, cwd: path.resolve(paths().source.data), src: 'annotations.js', dest: path.resolve(paths().public.data) } - ] - }, - styleguide: { - files: [ - { expand: true, cwd: path.resolve(paths().source.styleguide), src: ['*.*', '**/*.*'], dest: path.resolve(paths().public.styleguide) } - ] - } - }, - watch: { - all: { - files: [ - path.resolve(paths().source.css + '**/*.css'), - path.resolve(paths().source.styleguide + 'css/*.css'), - path.resolve(paths().source.patterns + '**/*.mustache'), - path.resolve(paths().source.patterns + '**/*.json'), - path.resolve(paths().source.fonts + '/*'), - path.resolve(paths().source.images + '/*'), - path.resolve(paths().source.data + '*.json'), - path.resolve(paths().source.js + '/*.js') - ], - tasks: ['default', 'bsReload:css'] - } - }, - nodeunit: { - all: ['test/*_tests.js'] - }, - browserSync: { - dev: { - options: { - server: path.resolve(paths().public.root), - watchTask: true, - watchOptions: { - ignoreInitial: true, - ignored: '*.html' - }, - snippetOptions: { - // Ignore all HTML files within the templates folder - blacklist: ['/index.html', '/', '/?*'] - }, - plugins: [ - { - module: 'bs-html-injector', - options: { - files: [path.resolve(paths().public.root + '/index.html'), path.resolve(paths().public.styleguide + '/styleguide.html')] - } - } - ], - notify: { - styles: [ - 'display: none', - 'padding: 15px', - 'font-family: sans-serif', - 'position: fixed', - 'font-size: 1em', - 'z-index: 9999', - 'bottom: 0px', - 'right: 0px', - 'border-top-left-radius: 5px', - 'background-color: #1B2032', - 'opacity: 0.4', - 'margin: 0', - 'color: white', - 'text-align: center' - ] - } - } - } - }, - eslint: { - options: { - configFile: './.eslintrc' - }, - target: ['./core/lib/*'] - }, - bsReload: { - css: path.resolve(paths().public.root + '**/*.css') - } - }); - - // load all grunt tasks - require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks); - - //load the patternlab task - grunt.task.loadTasks('./core/lib/'); - - grunt.registerTask('default', ['patternlab', 'copy:main', 'copy:styleguide']); - - //travis CI task - grunt.registerTask('travis', ['nodeunit', 'eslint', 'patternlab']); - - grunt.registerTask('serve', ['patternlab', 'copy:main', 'copy:styleguide', 'browserSync', 'watch:all']); - - grunt.registerTask('build', ['nodeunit', 'eslint', 'concat']); - -}; diff --git a/LICENSE b/LICENSE index 44cbb3e41..c9b8c1daa 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2013 Brad Frost, http://bradfrostweb.com & Dave Olsen, http://dmolsen.com & Brian Muenzenmeyer, http://brianmuenzenmeyer.com +Copyright (c) 2018 Brian Muenzenmeyer, http://brianmuenzenmeyer.com & Brad Frost, http://bradfrostweb.com 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 @@ -17,4 +17,4 @@ 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. \ No newline at end of file +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 307a5bd06..cd621433a 100644 --- a/README.md +++ b/README.md @@ -1,425 +1,74 @@ -[![Build Status](https://travis-ci.org/pattern-lab/patternlab-node.png?branch=master)](https://travis-ci.org/pattern-lab/patternlab-node) +

+ Pattern Lab Logo +

-## About the Node Version of Pattern Lab +# Pattern Lab -The Node version of [Pattern Lab](http://patternlab.io/) is, at its core, a static site generator. It combines platform-agnostic assets, like the Mustache-based patterns, the JavaScript-based viewer, and the self-contained webserver, with a Node-based "builder" that transforms and dynamically builds the Pattern Lab site. +This monorepo contains the core of Pattern Lab / Node and all related engines, UI kits, plugins and utilities. Pattern Lab helps you and your team build thoughtful, pattern-driven user interfaces using atomic design principles. -This repository contains the vanilla builder logic, grunt and gulp configurations, and some sample template/css/data to illustrate the power and flexibility of the tool. +If you'd like to see what a front-end project built with Pattern Lab looks like, check out this [online demo of Pattern Lab output](http://demo.patternlab.io/). -###### Core Team +[![Build Status](https://travis-ci.org/pattern-lab/patternlab-node.svg?branch=master)](https://travis-ci.org/pattern-lab/patternlab-node) +![current release](https://img.shields.io/npm/v/@pattern-lab/core.svg) +![license](https://img.shields.io/github/license/pattern-lab/patternlab-node.svg) +[![Coverage Status](https://coveralls.io/repos/github/pattern-lab/patternlab-node/badge.svg?branch=master)](https://coveralls.io/github/pattern-lab/patternlab-node?branch=master) +[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier) +[![node (scoped)](https://img.shields.io/node/v/@pattern-lab/patternlab-node.svg)]() +[![Join the chat at Gitter](https://badges.gitter.im/pattern-lab/node.svg)](https://gitter.im/pattern-lab/node) -* [@bmuenzenmeyer](https://github.com/bmuenzenmeyer) - Lead Maintainer -* [@geoffp](https://github.com/geoffp) - Core Contributor +Docs @ [![Netlify Status](https://api.netlify.com/api/v1/badges/d454dbde-02c5-4bd4-8393-4ab75e862b03/deploy-status)](https://app.netlify.com/sites/patternlab-docs-preview/deploys) -### Prerequisites +Pattern Lab Preview @ [![Netlify Status](https://api.netlify.com/api/v1/badges/a6db1666-cb4f-4d26-82d4-9d88d875f286/deploy-status)](https://app.netlify.com/sites/patternlab-handlebars-preview/deploys) -Make sure Node and npm are installed. A great guide can be found here: [https://docs.npmjs.com/getting-started/installing-node](https://docs.npmjs.com/getting-started/installing-node) +## Using Pattern Lab -### Download +Refer to the [core usage guidelines](https://github.com/pattern-lab/patternlab-node/blob/master/packages/core/README.md#usage) -* Download the [latest release of patternlab-node](https://github.com/pattern-lab/patternlab-node/releases/latest) from Github -* Via npm, run `npm install patternlab-node` (Note this will auto install the grunt version currently. see below) -* **NOTE** Node version 4.X and 5.X have tentative support, citing [a lot of Windows issues](https://github.com/nodejs/node-gyp/issues/629), including [mine](https://github.com/pattern-lab/patternlab-node/issues/162). Upgrade node at your own risk until otherwise stated. I've tried to catalog some issues and troubleshooting steps on the [wiki](https://github.com/pattern-lab/patternlab-node/wiki/Windows-Issues). +### Installation -### Troubleshooting Installs +As of Pattern Lab Node 3.0.0, installation of [Editions](http://patternlab.io/docs/advanced-ecosystem-overview.html) is accomplished via the command line interface. -Make sure you are running your terminal/command line session as administrator. This could mean `sudo`, or opening the window with a right-click option. +The below assumes a new directory and project is required. This is likely what you want to do if starting from scratch. You could also run this within an existing project. The CLI will ask you for the installation location. -### Choose Your Adventure! Now Vanilla, Grunt & Gulp +1. Open a terminal window and following along below: + ```bash + mkdir new-project + cd new-project + npm create pattern-lab + ``` + > If you get an error stating that `npx` is not installed, ensure you are on `npm 5.2.0` or later by running `npm -v` or install it globally with `npm install -g npx`. [Learn more about npx.](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b) +1. Follow the on-screen prompts to choose your Edition and a Starterkit should you want one. + - If you chose `edition-node`, new commands in the "scripts" will be added in your `package.json`. + - If you chose `edition-node-gulp`, a `gulpfile.js` will be added to your project. -This repository ships with two `package.json` files, a `Gruntfile.js`, and a `gulpfile.js`. The default is grunt currently. The core builder is not dependent on either. + > Notice that `@pattern-lab/cli` was installed as a depdendency. Learn how to further [use the cli in your own project](https://github.com/pattern-lab/patternlab-node/blob/dev/packages/cli/readme.md#configuring-your-project-to-use-the-cli). -### Getting Started - Grunt -To run patternlab-node using grunt, do the following in the directory you downloaded and extracted the zipped release: +## Ecosystem -1. Run `npm install` from the command line -2. Optionally, delete `package.gulp.json`, `gulpfile.js`, and `core/lib/patternlab_gulp.js` files if you are certain you don't need it. -* Not deleting `core/lib/patternlab_gulp.js` may cause a harmless error when running grunt. Delete it. -3. Run `grunt` or `grunt serve` from the command line +![Pattern Lab Ecosystem](http://patternlab.io/assets/pattern-lab-2-image_18-large-opt.png) -This creates all patterns, the styleguide, and the pattern lab site. It's strongly recommended to run `grunt serve` to have BrowserSync spin up and serve the files to you. +Core, and Editions, are part of the [Pattern Lab Ecosystem](http://patternlab.io/docs/advanced-ecosystem-overview.html). With this architecture, we encourage people to write and maintain their own Editions, Starterkits, and even PatternEngines. -### Getting Started - Gulp +## Changelog -To run patternlab-node using gulp, you need to swap out the default grunt configuration. Do the following in the directory you downloaded and extracted the zipped release: +[Each package within this monorepo](https://github.com/pattern-lab/patternlab-node/tree/master/packages) has its own changelog. Below are the main ones to watch: -1. Rename `package.json` to `package.grunt.json` or delete it if you don't intend on going back -2. Rename `package.gulp.json` to `package.json` -3. Run `npm install` from the command line -4. Run `gulp` or `gulp serve` from the command line +* [@pattern-lab/core changelog ](https://github.com/pattern-lab/patternlab-node/blob/master/packages/core/CHANGELOG.md) +* [@pattern-lab/cli changelog ](https://github.com/pattern-lab/patternlab-node/blob/master/packages/cli/CHANGELOG.md) -This creates all patterns, the styleguide, and the pattern lab site. It's strongly recommended to run `gulp serve` to have BrowserSync spin up and serve the files to you. +## Support for Pattern Lab -### There and Back Again, or Switching Between Grunt and Gulp +Pattern Lab / Node wouldn't be what it is today without the support of the community. It will always be free and open source. Continued development is made possible in part from the support of [these wonderful project supporters](https://github.com/pattern-lab/patternlab-node/wiki/Thanks). If you want to learn more about supporting the project, visit the [Pattern Lab / Node Patreon page](https://www.patreon.com/patternlab). -It's not expected to toggle between the two build systems, but for those migrating between the two configs, here's some general guidelines: +**:100: Thanks for support from the following:** -* Make sure your `package.json` files are correct per the Getting Started sections. -* Run `npm cache clear` before installation -* Delete the contents of `./node_modules` if you want a cleaner installation. -* Regarding speed, Gulp is faster. BrowserSync takes a bit longer than the old static server to spin up, but its capabilities far outweigh the startup cost. +* **[Brad Frost](http://bradfrost.com/)** +* Jan Ditze +* [Marcos Peebles](https://twitter.com/marcospeebles) +* [Maximilian Franzke](https://twitter.com/maedmaex) +* [Susan Simkins](https://twitter.com/susanmsimkins) -### Upgrading +## Contributing -You can find instructions on how to upgrade from version to version of Pattern Lab Node here: [https://github.com/pattern-lab/patternlab-node/wiki/Upgrading](https://github.com/pattern-lab/patternlab-node/wiki/Upgrading) - -### Command Line Interface - -The following are grunt/gulp task arguments you may execute: - -##### `patternlab` -With no arguments, patternlab runs the full builder, compiling patterns, and constructing the front-end site. - -##### `patternlab:only_patterns` -Compile the patterns only, outputting to ./public/patterns - -##### `patternlab:v` -Retrieve the version of patternlab-node you have installed - -##### `patternlab:help` -Get more information about patternlab-node, pattern lab in general, and where to report issues. - -### Further Configuration - -##### Watching Changes -To have patternlab-node watch for changes to either a mustache template, data, or stylesheets, run `grunt|gulp watch` or `grunt|gulp serve`. The `Gruntfile|Gulpfile` governs what is watched. It should be easy to add scss or whatever preprocessor you fancy. - -##### Configurable Paths -Pattern Lab Node ships with a particular source and public workflow intended to separate the code you work on with the code generated for consumption elsewhere. If you wish to change any paths, you may do so within `patternlab-config.json`. The contents are here: - -``` -"paths" : { - "source" : { - "root": "./source/", - "patterns" : "./source/_patterns/", - "data" : "./source/_data/", - "styleguide" : "./core/styleguide/", - "patternlabFiles" : "./source/_patternlab-files/", - "js" : "./source/js", - "images" : "./source/images", - "fonts" : "./source/fonts", - "css" : "./source/css/" - }, - "public" : { - "root" : "./public/", - "patterns" : "./public/patterns/", - "data" : "./public/data/", - "styleguide" : "./public/styleguide/", - "js" : "./public/js", - "images" : "./public/images", - "fonts" : "./public/fonts", - "css" : "./public/css" - } -} -``` - -Note the intentional repitition of the nested structure, made this way for maximum flexibility. Relative paths are default but absolute paths should work too. You may also use these paths within Grunt or Gulp files by referring to the paths() object. - -##### Nav Bar Controls -If you don't have a need for some of the nav-bar tools in the Pattern Lab frontend, you can turn them off in `patternlab-config.json`. - -The current selection is as follows. - -``` -"ishControlsVisible": { - "s": true, - "m": true, - "l": true, - "full": true, - "random": true, - "disco": true, - "hay": true, - "mqs": false, - "find": false, - "views-all": true, - "views-annotations": true, - "views-code": true, - "views-new": true, - "tools-all": true, - "tools-follow": false, - "tools-reload": false, - "tools-shortcuts": false, - "tools-docs": true -} -``` -##### Pattern States -You can set the state of a pattern by including its key in the `patternStates` object in `patternlab-config.json`, along with a style defined inside `patternStateCascade`. The out of the box styles are in progress (orange), in review (yellow), and complete (green). -``` -"patternStates": { - "atoms-colors" : "complete", - "molecules-primary-nav" : "inreview", - "organisms-header" : "inprogress" -} -``` - -Note that patterns inherit the lowest common denominator pattern state of their lineage. -Consider: -``` -"patternStates": { - "molecules-single-comment" : "complete", - "organisms-sticky-comment" : "inreview", - "templates-article" : "complete" -} -``` -In this case, two things are of note: - -* templates-article will display inreview since it inherits `organisms-sticky-comment` -* pages-article will not display any pattern state, as it does not define one - -The `patternStateCascade` array is important in that the order is hierarchical. -The default is below: - -``` -"patternStateCascade": ["inprogress", "inreview", "complete"], -``` - -which correspond to classes defined inside `./core/styleguide/css/styleguide.css` - -``` -/* pattern states */ -.inprogress:before { - color: #FF4136 !important; -} - -.inreview:before { - color: #FFCC00 !important; -} - -.complete:before { - color: #2ECC40 !important; -} -``` - -##### Pattern Export -`patternlab-config.json` also has two properties that work together to export completed patterns for use in a production environment. Provide an array of keys and an output directory. Pattern Lab doesn't ship with any pattern export keys, but the default directory is `"./pattern_exports/"` created inside the install directory. - -``` -"patternExportKeys": ["molecules-primary-nav", "organisms-header", "organisms-header"], -"patternExportDirectory": "./pattern_exports/" -``` - -Coupled with exported css (much easier to extract with existing tools like [grunt-contrib-copy](https://github.com/gruntjs/grunt-contrib-copy)), pattern export can help to maintain the relevancy of the design system by directly placing partials in a directory of your choosing. - -##### cacheBust -`patternlab-config.json` has this flag to instruct Pattern Lab to append a unique query string to Javascript and CSS assets throughout the frontend. - -``` -"cacheBust": true -``` - -Default: true - -##### defaultPattter -`patternlab-config.json` has an entry that allows you to specifiy a specific pattern upon launch of the main site. It works even without BrowserSync running. Set it like this: - -``` -"defaultPattern": "pages-homepage", -``` -Default: "all" -If running with BrowserSync, you may also set [this BrowserSync options](https://www.browsersync.io/docs/options/#option-startPath) to achieve the same result via your Gruntfile or Gulpfile. - -``` -startPath: '/?p=pages-homepage', -``` - -##### baseurl - -If your instance of Pattern Lab lives in a subdirectory of your server, for instance on github pages (ex: yourusername.github.io/patterns-demo/), then add the baseurl here. The baseurl is everything after the hostname - ie: `patterns-demo` - -``` -"baseurl" : "/patterns-demo" -``` - -Default: blank - -##### excluding patterns - -If you'd like to exclude an individual pattern you can do so by prepending the filename with an underscore, like: `_filename.mustache` - -You can also exclude complete directories by prepending the directory name with an underscore, like: `/_experiment/...` - -##### Style Guide Excludes - -Exclude whole pattern types from the "All patterns" styleguide by adding entries to `patternlab-config.json`. This is quite useful to make speedier. Pattern Lab Node ships with the following: - -``` -"styleGuideExcludes": [ - "templates", - "pages" -] -``` - - -##### Debug Mode -`patternlab.json` is a file created for debugging purposes. Set `debug` to true in `.patternlab-config.json` to see all the secrets. - -##### Server & BrowserSync -Running `grunt serve` or `gulp serve` will compile the Pattern Lab frontend and host it by default on http://localhost:3000 via [BrowserSync](http://www.browsersync.io/docs/). After it starts, templates, `data.json`, and scss/css changes in your source code will be automatically injected into the page. - -You'll notice that if you have this open across different browsers, we do our best to keep the frontend in sync, but there is a known issue with synced navigation using the main menu. - -### Roadmap - - -A roadmap exists for Pattern Lab Node. Check it out [here](https://github.com/pattern-lab/patternlab-node/issues/134). The Node version of Pattern Lab is maintained by [@bmuenzenmeyer](https://twitter.com/bmuenzenmeyer) and contributors. Pull requests welcome, but please take a moment to read the [guidelines](https://github.com/pattern-lab/patternlab-node/blob/master/CONTRIBUTING.md). - -Dave Olsen has also published the [specification](https://github.com/pattern-lab/the-spec/blob/draft/SPEC.md) for Pattern Lab ports. Development will be oriented toward compliance with this as the spec and the port mature together. Post v1 work will focus on other pattern engines and a plugin architecture. - -### Advanced Pattern Library Features - -##### Pattern Parameters -Pattern parameters are a simple mechanism for replacing Mustache variables via attributes on a pattern partial tag rather than having to use a pattern-specific json file. They are especially useful when you want to supply distinct values for Mustache variables in a specific pattern partial instance that may be included multiple times in a molecule, template, or page. - -The basic syntax is this: - -``` -{{> molecules-single-comment(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }} -``` - -The attributes listed in the pattern parameters should match Mustache variable names in your pattern. The values listed for each attribute will replace the Mustache variables. Again, pattern parameters are a simple find and replace of Mustache variables with the supplied values. - -Pattern parameters **do not** currently support the following: - -* sub-lists (e.g. iteration of a section), -* and the use of long strings of text can be unwieldy -* nested properties within the parameter data, such as `{{> molecules-single-comment(foo.bar: 'baz') }}` - -You can read the full documentation on pattern parameters here: [Using Pattern Parameters](http://patternlab.io/docs/pattern-parameters.html) - -##### Pattern Style Modifiers -Style Modifiers allow you to create a base pattern that you can easily modify by adding a class name to the pattern partial. Read more about them [here](http://patternlab.io/docs/pattern-stylemodifier.html), including support with pattern parameters. Below is the gist. - -The basic syntax is this: - -``` -{{> atoms-message:error }} -``` - -This works by using a reserved mustache variable of sorts called {{ styleModifier }} applied to the atoms-message mustache file itself: - -``` -
{{ message }}
-``` - -Once rendered, it looks like this: - -``` -
-
-
-``` - -You may also specify multiple classes using a pipe character (|). - -``` -{{> atoms-message:error|is-on }} -``` - - - -##### Pseudo-Patterns -Pseudo-patterns are meant to give developers the ability to build multiple and unique **rendered** patterns off of one base pattern and its mark-up while giving them control over the data that is injected into the base pattern. This feature is especially useful when developing template- and page-style patterns. - -Pseudo-patterns are, essentially, the pattern-specific JSON files that would accompany a pattern. Rather than require a Mustache pattern, though, pseudo-patterns are hinted so a developer can reference a shared pattern. The basic syntax: - -`patternName~pseudoPatternName.json` - -The tilde, `~`, and JSON extension denotes that this is a pseudo-pattern. `patternName` is the parent pattern that will be used when rendering the pseudo-pattern. `patternName` and `pseudoPatternName` are combined when adding the pseudo-pattern to the navigation. - -The JSON file itself works exactly like the [pattern-specific JSON file](http://patternlab.io/docs/data-pattern-specific.html). It has the added benefit that the pseudo-pattern will also import any values from the parent pattern's pattern-specific JSON file. Here is an example (which ships with the package) where we want to show an emergency notification on our homepage template. Our `03-templates/` directory looks like this: - -``` -00-homepage.mustache -01-blog.mustache -02-article.mustache -``` - -Our `00-homepage.mustache` template might look like this: - -``` -
- {{# emergency }} -
Oh Noes! Emergency!
- {{/ emergency }} - { ...a bunch of other content... } -
-``` - -If our `_data.json` file doesn't give a value for `emergency` that section will never show up when `00-homepage.mustache` is rendered. - -We want to show both the regular and emergency states of the homepage but we don't want to duplicate the entire `00-homepage.mustache` template. That would be a maintenance nightmare. So let's add our pseudo-pattern: - -``` -00-homepage.mustache -00-homepage~emergency.json -01-blog.mustache -02-article.mustache -``` - -In our pseudo-pattern, `00-homepage~emergency.json`, we add our `emergency` attribute: - -``` -{ - "emergency": true -} -``` - -Now when we generate our site we'll have our homepage template rendered twice. Once as the regular template and once as a pseudo-pattern showing the emergency section. Note that the pseudo-pattern will show up in our navigation as `Homepage Emergency`. - -##### Pattern Linking -You can build patterns that link to one another to help simulate using a real website. This is especially useful when working with the Pages and Templates pattern types. The basic format is: - -`{{ link.pattern-name }}` - -For example, if you wanted to add a link to the `home page` template from your `blog` template you could write the following: - -`Home` - -This would compile to: - -`Home` - -As you can see, it's a much easier way of linking patterns to one another. - -=== - -## Working with Patterns - -(The following documentation is built for the PHP version of Pattern Lab, but most applies to the node version too. If you find omissions or mistakes please open an issue.) - -Patterns are the core element of Pattern Lab. Understanding how they work is the key to getting the most out of the system. Patterns use [Mustache](http://mustache.github.io/) so please read [Mustache's docs](http://mustache.github.io/mustache.5.html) as well. - -* [How Patterns Are Organized](http://patternlab.io/docs/pattern-organization.html) -* [Adding New Patterns](http://patternlab.io/docs/pattern-add-new.html) -* [Reorganizing Patterns](http://patternlab.io/docs/pattern-reorganizing.html) -* [Including One Pattern Within Another via Partials](http://patternlab.io/docs/pattern-including.html) -* [Managing Assets for a Pattern: JavaScript, images, CSS, etc.](http://patternlab.io/docs/pattern-managing-assets.html) -* [Modifying the Pattern Header and Footer](http://patternlab.io/docs/pattern-header-footer.html) -* [Using Pattern Parameters](http://patternlab.io/docs/pattern-parameters.html) -* [Using Pattern State](http://patternlab.io/docs/pattern-states.html) -* ["Hiding" Patterns in the Navigation](http://patternlab.io/docs/pattern-hiding.html) -* [Adding Annotations](http://patternlab.io/docs/pattern-adding-annotations.html) -* [Viewing Patterns on a Mobile Device](http://patternlab.io/docs/pattern-mobile-view.html) - -## Creating & Working With Dynamic Data for a Pattern - -The Node version of Pattern Lab utilizes Mustache as the template language for patterns. In addition to allowing for the [inclusion of one pattern within another](http://patternlab.io/docs/pattern-including.html) it also gives pattern developers the ability to include variables. This means that attributes like image sources can be centralized in one file for easy modification across one or more patterns. The Node version of Pattern Lab uses a JSON file, `source/_data/data.json`, to centralize many of these attributes. - -* [Introduction to JSON & Mustache Variables](http://patternlab.io/docs/data-json-mustache.html) -* [Overriding the Central `data.json` Values with Pattern-specific Values](http://patternlab.io/docs/data-pattern-specific.html) -* [Linking to Patterns with Pattern Lab's Default `link` Variable](http://patternlab.io/docs/data-link-variable.html) -* [Creating Lists with Pattern Lab's Default `listItems` Variable](http://patternlab.io/docs/data-listitems.html) - -## Using Pattern Lab's Advanced Features - -By default, the Pattern Lab assets can be manually generated and the Pattern Lab site manually refreshed but who wants to waste time doing that? Here are some ways that Pattern Lab can make your development workflow a little smoother: - -* [Watching for Changes and Auto-Regenerating Patterns](http://patternlab.io/docs/advanced-auto-regenerate.html) - Node version coming soon -* [Auto-Reloading the Browser Window When Changes Are Made](http://patternlab.io/docs/advanced-reload-browser.html) - Node version coming soon -* [Multi-browser & Multi-device Testing with Page Follow](http://patternlab.io/docs/advanced-page-follow.html) -* [Keyboard Shortcuts](http://patternlab.io/docs/advanced-keyboard-shortcuts.html) -* [Special Pattern Lab-specific Query String Variables ](http://patternlab.io/docs/pattern-linking.html) -* [Preventing the Cleaning of public/](http://patternlab.io/docs/advanced-clean-public.html) - Node version coming soon -* [Modifying the Pattern Lab Nav](http://patternlab.io/docs/advanced-pattern-lab-nav.html) - Node version coming soon -* [Editing the config.ini Options](http://patternlab.io/docs/advanced-config-options.html) - Node version coming soon +Refer to the [contribution guidelines](https://github.com/pattern-lab/patternlab-node/blob/master/.github/CONTRIBUTING.md). diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 000000000..6960ccf61 --- /dev/null +++ b/babel.config.js @@ -0,0 +1,27 @@ +module.exports = { + presets: [ + [ + '@babel/preset-env', + { + targets: { + node: 'current', + }, + }, + ], + ], + plugins: [ + /** + * 1. Helps with our Web Component Preact renderer + */ + '@babel/plugin-syntax-jsx' /* [1] */, + [ + '@babel/plugin-transform-react-jsx' /* [1] */, + { + pragma: 'h', + pragmaFrag: '"span"', + throwIfNamespace: false, + useBuiltIns: false, + }, + ], + ], +}; diff --git a/core/lib/lineage_hunter.js b/core/lib/lineage_hunter.js deleted file mode 100644 index e5367f2e0..000000000 --- a/core/lib/lineage_hunter.js +++ /dev/null @@ -1,158 +0,0 @@ -/* - * patternlab-node - v1.2.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - -"use strict"; - -var lineage_hunter = function () { - - var pa = require('./pattern_assembler'); - - function findlineage(pattern, patternlab) { - - var pattern_assembler = new pa(); - - //find the {{> template-name }} within patterns - var matches = pattern_assembler.find_pattern_partials(pattern); - if (matches !== null) { - matches.forEach(function (match) { - //strip out the template cruft - var foundPatternKey = match - .replace("{{> ", "") - .replace(" }}", "") - .replace("{{>", "") - .replace("}}", ""); - - // remove any potential pattern parameters. this and the above are - // rather brutish but I didn't want to do a regex at the time - if (foundPatternKey.indexOf('(') > 0) { - foundPatternKey = foundPatternKey.substring(0, foundPatternKey.indexOf('(')); - } - - //remove any potential stylemodifiers. - foundPatternKey = foundPatternKey.split(':')[0]; - - //get the ancestorPattern - var ancestorPattern = pattern_assembler.get_pattern_by_key(foundPatternKey, patternlab); - - if (ancestorPattern && pattern.lineageIndex.indexOf(ancestorPattern.key) === -1) { - - //add it since it didnt exist - pattern.lineageIndex.push(ancestorPattern.key); - - //create the more complex patternLineage object too - var l = { - "lineagePattern": ancestorPattern.key, - "lineagePath": "../../patterns/" + ancestorPattern.patternLink - }; - if (ancestorPattern.patternState) { - l.lineageState = ancestorPattern.patternState; - } - - pattern.lineage.push(l); - - //also, add the lineageR entry if it doesn't exist - if (ancestorPattern.lineageRIndex.indexOf(pattern.key) === -1) { - ancestorPattern.lineageRIndex.push(pattern.key); - - //create the more complex patternLineage object in reverse - var lr = { - "lineagePattern": pattern.key, - "lineagePath": "../../patterns/" + pattern.patternLink - }; - if (pattern.patternState) { - lr.lineageState = pattern.patternState; - } - - ancestorPattern.lineageR.push(lr); - } - } - }); - } - } - - function setPatternState(direction, pattern, targetPattern) { - // if the request came from the past, apply target pattern state to current pattern lineage - if (direction === 'fromPast') { - for (var i = 0; i < pattern.lineageIndex.length; i++) { - if (pattern.lineageIndex[i] === targetPattern.key) { - pattern.lineage[i].lineageState = targetPattern.patternState; - } - } - } else { - //the request came from the future, apply target pattern state to current pattern reverse lineage - for (var i = 0; i < pattern.lineageRIndex.length; i++) { - if (pattern.lineageRIndex[i] === targetPattern.key) { - pattern.lineageR[i].lineageState = targetPattern.patternState; - } - } - } - } - - - function cascadePatternStates(patternlab) { - - var pattern_assembler = new pa(); - - for (var i = 0; i < patternlab.patterns.length; i++) { - var pattern = patternlab.patterns[i]; - - //for each pattern with a defined state - if (pattern.patternState) { - - if (pattern.lineageIndex && pattern.lineageIndex.length > 0) { - - //find all lineage - patterns being consumed by this one - for (var h = 0; h < pattern.lineageIndex.length; h++) { - var lineagePattern = pattern_assembler.get_pattern_by_key(pattern.lineageIndex[h], patternlab); - setPatternState('fromFuture', lineagePattern, pattern); - } - } - - if (pattern.lineageRIndex && pattern.lineageRIndex.length > 0) { - - //find all reverse lineage - that is, patterns consuming this one - for (var j = 0; j < pattern.lineageRIndex.length; j++) { - - var lineageRPattern = pattern_assembler.get_pattern_by_key(pattern.lineageRIndex[j], patternlab); - - //only set patternState if pattern.patternState "is less than" the lineageRPattern.patternstate - //this makes patternlab apply the lowest common ancestor denominator - if (patternlab.config.patternStateCascade.indexOf(pattern.patternState) - < patternlab.config.patternStateCascade.indexOf(lineageRPattern.patternState)) { - - if (patternlab.config.debug) { - console.log('Found a lower common denominator pattern state: ' + pattern.patternState + ' on ' + pattern.key + '. Setting reverse lineage pattern ' + lineageRPattern.key + ' from ' + lineageRPattern.patternState); - } - - lineageRPattern.patternState = pattern.patternState; - - //take this opportunity to overwrite the lineageRPattern's lineage state too - setPatternState('fromPast', lineageRPattern, pattern); - } else { - setPatternState('fromPast', pattern, lineageRPattern); - } - } - } - } - } - } - - return { - find_lineage: function (pattern, patternlab) { - findlineage(pattern, patternlab); - }, - cascade_pattern_states : function (patternlab) { - cascadePatternStates(patternlab); - } - }; - -}; - -module.exports = lineage_hunter; diff --git a/core/lib/list_item_hunter.js b/core/lib/list_item_hunter.js deleted file mode 100644 index 2b08ef2f1..000000000 --- a/core/lib/list_item_hunter.js +++ /dev/null @@ -1,115 +0,0 @@ -/* - * patternlab-node - v1.2.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - -"use strict"; - -var list_item_hunter = function () { - - var extend = require('util')._extend, - pa = require('./pattern_assembler'), - smh = require('./style_modifier_hunter'), - pattern_assembler = new pa(), - style_modifier_hunter = new smh(), - items = [ 'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen', 'twenty']; - - function processListItemPartials(pattern, patternlab) { - //find any listitem blocks - var matches = pattern_assembler.find_list_items(pattern, patternlab); - if (matches !== null) { - matches.forEach(function (liMatch) { - - if (patternlab.config.debug) { - console.log('found listItem of size ' + liMatch + ' inside ' + pattern.key); - } - - //find the boundaries of the block - var loopNumberString = liMatch.split('.')[1].split('}')[0].trim(); - var end = liMatch.replace('#', '/'); - var patternBlock = pattern.template.substring(pattern.template.indexOf(liMatch) + liMatch.length, pattern.template.indexOf(end)).trim(); - - //build arrays that repeat the block, however large we need to - var repeatedBlockTemplate = []; - var repeatedBlockHtml = ''; - var i; // for loops - - for (i = 0; i < items.indexOf(loopNumberString); i++) { - repeatedBlockTemplate.push(patternBlock); - } - - //check for a local listitems.json file - var listData = JSON.parse(JSON.stringify(patternlab.listitems)); - listData = pattern_assembler.merge_data(listData, pattern.listitems); - - //iterate over each copied block, rendering its contents along with pattenlab.listitems[i] - for (i = 0; i < repeatedBlockTemplate.length; i++) { - var thisBlockTemplate = repeatedBlockTemplate[i]; - var thisBlockHTML = ""; - - //combine listItem data with pattern data with global data - var itemData = listData['' + items.indexOf(loopNumberString)]; //this is a property like "2" - var globalData = JSON.parse(JSON.stringify(patternlab.data)); - var localData = JSON.parse(JSON.stringify(pattern.jsonFileData)); - - var allData = pattern_assembler.merge_data(globalData, localData); - allData = pattern_assembler.merge_data(allData, itemData !== undefined ? itemData[i] : {}); //itemData could be undefined if the listblock contains no partial, just markup - allData.link = extend({}, patternlab.data.link); - - //check for partials within the repeated block - var foundPartials = pattern_assembler.find_pattern_partials({ 'template' : thisBlockTemplate }); - - if (foundPartials && foundPartials.length > 0) { - for (var j = 0; j < foundPartials.length; j++) { - //get the partial - var partialName = foundPartials[j].match(/([\w\-\.\/~]+)/g)[0]; - var partialPattern = pattern_assembler.get_pattern_by_key(partialName, patternlab); - - //create a copy of the partial so as to not pollute it after the get_pattern_by_key call. - var cleanPartialPattern = JSON.parse(JSON.stringify(partialPattern)); - - //if partial has style modifier data, replace the styleModifier value - if (foundPartials[j].indexOf(':') > -1) { - style_modifier_hunter.consume_style_modifier(cleanPartialPattern, foundPartials[j], patternlab); - } - - //replace its reference within the block with the extended template - thisBlockTemplate = thisBlockTemplate.replace(foundPartials[j], cleanPartialPattern.extendedTemplate); - } - - //render with data - thisBlockHTML = pattern_assembler.renderPattern(thisBlockTemplate, allData, patternlab.partials); - } else { - //just render with mergedData - thisBlockHTML = pattern_assembler.renderPattern(thisBlockTemplate, allData, patternlab.partials); - } - - //add the rendered HTML to our string - repeatedBlockHtml = repeatedBlockHtml + thisBlockHTML; - } - - //replace the block with our generated HTML - var repeatingBlock = pattern.extendedTemplate.substring(pattern.extendedTemplate.indexOf(liMatch), pattern.extendedTemplate.indexOf(end) + end.length); - pattern.extendedTemplate = pattern.extendedTemplate.replace(repeatingBlock, repeatedBlockHtml); - - //update the extendedTemplate in the partials object in case this pattern is consumed later - patternlab.partials[pattern.key] = pattern.extendedTemplate; - - }); - } - } - - return { - process_list_item_partials: function (pattern, patternlab) { - processListItemPartials(pattern, patternlab); - } - }; - -}; - -module.exports = list_item_hunter; diff --git a/core/lib/media_hunter.js b/core/lib/media_hunter.js deleted file mode 100644 index 62a02ad5a..000000000 --- a/core/lib/media_hunter.js +++ /dev/null @@ -1,51 +0,0 @@ -/* - * patternlab-node - v1.2.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - -"use strict"; - -var diveSync = require('diveSync'), - path = require('path'), - fs = require('fs-extra'); - -var media_hunter = function () { - - function findMediaQueries(dir, patternlab) { - patternlab.mediaQueries = []; - - diveSync(dir, function (err, file) { - if (path.extname(file) === '.css') { - var contents = fs.readFileSync(file, 'utf8'); - var safeContents = contents.replace("\r", " ").replace("\n", " "); - var matches = safeContents.match(/\((min|max)-width:([ ]+)?(([0-9]{1,5})(\.[0-9]{1,20}|)(px|em))/g); - for (var i = 0; i < matches.length; i++) { - var breakpoint = matches[i].substring(matches[i].indexOf(':') + 1).trimLeft(); - if (patternlab.mediaQueries.indexOf(breakpoint) === -1) { - patternlab.mediaQueries.push(breakpoint); - } - } - } - }); - patternlab.mediaQueries.sort(function (a, b) { - a.match(/(?:\d*\.)?\d+/g); - b.match(/(?:\d*\.)?\d+/g); - return parseInt(a, 10) > parseInt(b, 10); - }); - } - - return { - find_media_queries: function (dir, patternlab) { - findMediaQueries(dir, patternlab); - } - }; - -}; - -module.exports = media_hunter; - diff --git a/core/lib/object_factory.js b/core/lib/object_factory.js deleted file mode 100644 index 28a4af057..000000000 --- a/core/lib/object_factory.js +++ /dev/null @@ -1,70 +0,0 @@ -/* - * patternlab-node - v1.2.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - -"use strict"; - -var oPattern = function (abspath, subdir, filename, data) { - this.fileName = filename.substring(0, filename.indexOf('.')); - this.abspath = abspath; - this.subdir = subdir; - this.name = subdir.replace(/[\/\\]/g, '-') + '-' + this.fileName; //this is the unique name with the subDir - this.jsonFileData = data || {}; - this.patternName = this.fileName.replace(/^\d*\-/, ''); - this.patternDisplayName = this.patternName.split('-').reduce(function (val, working) { - return val.charAt(0).toUpperCase() + val.slice(1) + ' ' + working.charAt(0).toUpperCase() + working.slice(1); - }, '').trim(); //this is the display name for the ui. strip numeric + hyphen prefixes - this.patternLink = this.name + '/' + this.name + '.html'; - this.patternGroup = this.name.substring(this.name.indexOf('-') + 1, this.name.indexOf('-', 4) + 1 - this.name.indexOf('-') + 1); - this.patternSubGroup = subdir.substring(subdir.indexOf('/') + 4); - this.flatPatternPath = subdir.replace(/[\/\\]/g, '-'); - this.key = this.patternGroup + '-' + this.patternName; - this.template = ''; - this.patternPartial = ''; - this.lineage = []; - this.lineageIndex = []; - this.lineageR = []; - this.lineageRIndex = []; -}; - -var oBucket = function (name) { - this.bucketNameLC = name; - this.bucketNameUC = name.split('-').reduce(function (val, working) { - return val.charAt(0).toUpperCase() + val.slice(1) + ' ' + working.charAt(0).toUpperCase() + working.slice(1); - }, '').trim(); - this.navItems = []; - this.navItemsIndex = []; - this.patternItems = []; - this.patternItemsIndex = []; -}; - -var oNavItem = function (name) { - this.sectionNameLC = name; - this.sectionNameUC = name.split('-').reduce(function (val, working) { - return val.charAt(0).toUpperCase() + val.slice(1) + ' ' + working.charAt(0).toUpperCase() + working.slice(1); - }, '').trim(); - this.navSubItems = []; - this.navSubItemsIndex = []; -}; - -var oNavSubItem = function (name) { - this.patternPath = ''; - this.patternPartial = ''; - this.patternName = name.split(' ').reduce(function (val, working) { - return val.charAt(0).toUpperCase() + val.slice(1) + ' ' + working.charAt(0).toUpperCase() + working.slice(1); - }, '').trim(); -}; - -module.exports = { - oPattern: oPattern, - oBucket: oBucket, - oNavItem: oNavItem, - oNavSubItem: oNavSubItem -}; - diff --git a/core/lib/parameter_hunter.js b/core/lib/parameter_hunter.js deleted file mode 100644 index 9567f2a46..000000000 --- a/core/lib/parameter_hunter.js +++ /dev/null @@ -1,189 +0,0 @@ -/* - * patternlab-node - v1.2.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - -"use strict"; - -var parameter_hunter = function () { - - var extend = require('util')._extend, - pa = require('./pattern_assembler'), - smh = require('./style_modifier_hunter'), - style_modifier_hunter = new smh(), - pattern_assembler = new pa(); - - function paramToJson(pString) { - var paramStringWellFormed = ''; - var paramStringTmp; - var colonPos; - var delimitPos; - var quotePos; - var paramString = pString; - - do { - - //if param key is wrapped in single quotes, replace with double quotes. - paramString = paramString.replace(/(^\s*[\{|\,]\s*)'([^']+)'(\s*\:)/, '$1"$2"$3'); - - //if params key is not wrapped in any quotes, wrap in double quotes. - paramString = paramString.replace(/(^\s*[\{|\,]\s*)([^\s"'\:]+)(\s*\:)/, '$1"$2"$3'); - - //move param key to paramStringWellFormed var. - colonPos = paramString.indexOf(':'); - - //except to prevent infinite loops. - if (colonPos === -1) { - colonPos = paramString.length - 1; - } - else { - colonPos += 1; - } - paramStringWellFormed += paramString.substring(0, colonPos); - paramString = paramString.substring(colonPos, paramString.length).trim(); - - //if param value is wrapped in single quotes, replace with double quotes. - if (paramString[0] === '\'') { - quotePos = paramString.search(/[^\\]'/); - - //except for unclosed quotes to prevent infinite loops. - if (quotePos === -1) { - quotePos = paramString.length - 1; - } - else { - quotePos += 2; - } - - //prepare param value for move to paramStringWellFormed var. - paramStringTmp = paramString.substring(0, quotePos); - - //unescape any escaped single quotes. - paramStringTmp = paramStringTmp.replace(/\\'/g, '\''); - - //escape any double quotes. - paramStringTmp = paramStringTmp.replace(/"/g, '\\"'); - - //replace the delimiting single quotes with double quotes. - paramStringTmp = paramStringTmp.replace(/^'/, '"'); - paramStringTmp = paramStringTmp.replace(/'$/, '"'); - - //move param key to paramStringWellFormed var. - paramStringWellFormed += paramStringTmp; - paramString = paramString.substring(quotePos, paramString.length).trim(); - } - - //if param value is wrapped in double quotes, just move to paramStringWellFormed var. - else if (paramString[0] === '"') { - quotePos = paramString.search(/[^\\]"/); - - //except for unclosed quotes to prevent infinite loops. - if (quotePos === -1) { - quotePos = paramString.length - 1; - } - else { - quotePos += 2; - } - - //move param key to paramStringWellFormed var. - paramStringWellFormed += paramString.substring(0, quotePos); - paramString = paramString.substring(quotePos, paramString.length).trim(); - } - - //if param value is not wrapped in quotes, move everthing up to the delimiting comma to paramStringWellFormed var. - else { - delimitPos = paramString.indexOf(','); - - //except to prevent infinite loops. - if (delimitPos === -1) { - delimitPos = paramString.length - 1; - } - else { - delimitPos += 1; - } - paramStringWellFormed += paramString.substring(0, delimitPos); - paramString = paramString.substring(delimitPos, paramString.length).trim(); - } - - //break at the end. - if (paramString.length === 1) { - paramStringWellFormed += paramString.trim(); - paramString = ''; - break; - } - - } while (paramString); - - return paramStringWellFormed; - } - - function findparameters(pattern, patternlab) { - - if (pattern.parameteredPartials && pattern.parameteredPartials.length > 0) { - - //compile this partial immeadiately, essentially consuming it. - pattern.parameteredPartials.forEach(function (pMatch) { - //find the partial's name and retrieve it - var partialName = pMatch.match(/([\w\-\.\/~]+)/g)[0]; - var partialPattern = pattern_assembler.get_pattern_by_key(partialName, patternlab); - - //if we retrieved a pattern we should make sure that its extendedTemplate is reset. looks to fix #190 - partialPattern.extendedTemplate = partialPattern.template; - - if (patternlab.config.debug) { - console.log('found patternParameters for ' + partialName); - } - - //strip out the additional data, convert string to JSON. - var leftParen = pMatch.indexOf('('); - var rightParen = pMatch.indexOf(')'); - var paramString = '{' + pMatch.substring(leftParen + 1, rightParen) + '}'; - var paramStringWellFormed = paramToJson(paramString); - - var paramData = {}; - var globalData = {}; - var localData = {}; - - try { - paramData = JSON.parse(paramStringWellFormed); - globalData = JSON.parse(JSON.stringify(patternlab.data)); - localData = JSON.parse(JSON.stringify(pattern.jsonFileData || {})); - } catch (e) { - console.log(e); - } - - var allData = pattern_assembler.merge_data(globalData, localData); - allData = pattern_assembler.merge_data(allData, paramData); - - //if partial has style modifier data, replace the styleModifier value - if (pattern.stylePartials && pattern.stylePartials.length > 0) { - style_modifier_hunter.consume_style_modifier(partialPattern, pMatch, patternlab); - } - - //extend pattern data links into link for pattern link shortcuts to work. we do this locally and globally - allData.link = extend({}, patternlab.data.link); - - var renderedPartial = pattern_assembler.renderPattern(partialPattern.extendedTemplate, allData, patternlab.partials); - - //remove the parameter from the partial and replace it with the rendered partial + paramData - pattern.extendedTemplate = pattern.extendedTemplate.replace(pMatch, renderedPartial); - - //update the extendedTemplate in the partials object in case this pattern is consumed later - patternlab.partials[pattern.key] = pattern.extendedTemplate; - }); - } - } - - return { - find_parameters: function (pattern, patternlab) { - findparameters(pattern, patternlab); - } - }; - -}; - -module.exports = parameter_hunter; diff --git a/core/lib/pattern_assembler.js b/core/lib/pattern_assembler.js deleted file mode 100644 index 869b1986c..000000000 --- a/core/lib/pattern_assembler.js +++ /dev/null @@ -1,414 +0,0 @@ -/* - * patternlab-node - v1.2.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - -"use strict"; - -var pattern_assembler = function () { - - // returns any patterns that match {{> value:mod }} or {{> value:mod(foo:"bar") }} within the pattern - function findPartialsWithStyleModifiers(pattern) { - var matches = pattern.template.match(/{{>([ ])?([\w\-\.\/~]+)(?!\()(\:[A-Za-z0-9-_|]+)+(?:(| )\(.*)?([ ])?}}/g); - return matches; - } - - // returns any patterns that match {{> value(foo:"bar") }} or {{> value:mod(foo:"bar") }} within the pattern - function findPartialsWithPatternParameters(pattern) { - var matches = pattern.template.match(/{{>([ ])?([\w\-\.\/~]+)(?:\:[A-Za-z0-9-_|]+)?(?:(| )\(.*)+([ ])?}}/g); - return matches; - } - - //find and return any {{> template-name* }} within pattern - function findPartials(pattern) { - var matches = pattern.template.match(/{{>([ ])?([\w\-\.\/~]+)(?:\:[A-Za-z0-9-_|]+)?(?:(| )\(.*)?([ ])?}}/g); - return matches; - } - - function findListItems(pattern) { - var matches = pattern.template.match(/({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g); - return matches; - } - - function setState(pattern, patternlab) { - if (patternlab.config.patternStates && patternlab.config.patternStates[pattern.key]) { - pattern.patternState = patternlab.config.patternStates[pattern.key]; - } else { - pattern.patternState = ""; - } - } - - function addPattern(pattern, patternlab) { - //add the link to the global object - patternlab.data.link[pattern.patternGroup + '-' + pattern.patternName] = '/patterns/' + pattern.patternLink; - - //only push to array if the array doesn't contain this pattern - var isNew = true, i; - for (i = 0; i < patternlab.patterns.length; i++) { - //so we need the identifier to be unique, which patterns[i].abspath is - if (pattern.abspath === patternlab.patterns[i].abspath) { - //if abspath already exists, overwrite that element - patternlab.patterns[i] = pattern; - patternlab.partials[pattern.key] = pattern.extendedTemplate || pattern.template; - isNew = false; - break; - } - } - - //if the pattern is new, just push to the array - if (isNew) { - patternlab.patterns.push(pattern); - patternlab.partials[pattern.key] = pattern.extendedTemplate || pattern.template; - } - } - - function renderPattern(template, data, partials) { - var mustache = require('mustache'); - - if (partials) { - return mustache.render(template, data, partials); - } else { - return mustache.render(template, data); - } - } - - //http://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array-in-javascript - function shuffle(o) { - for (var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x); //eslint-disable-line curly - return o; - } - - function buildListItems(container) { - //combine all list items into one structure - var list = []; - for (var item in container.listitems) { - if (container.listitems.hasOwnProperty(item)) { - list.push(container.listitems[item]); - } - } - container.listItemArray = shuffle(list); - - for (var i = 1; i <= container.listItemArray.length; i++) { - var tempItems = []; - if (i === 1) { - tempItems.push(container.listItemArray[0]); - container.listitems['' + i] = tempItems; - } else { - for (var c = 1; c <= i; c++) { - tempItems.push(container.listItemArray[c - 1]); - container.listitems['' + i] = tempItems; - } - } - } - } - - function getpatternbykey(key, patternlab) { - var i; // for the for loops - - //look for exact key matches - for (i = 0; i < patternlab.patterns.length; i++) { - if (patternlab.patterns[i].key === key) { - return patternlab.patterns[i]; - } - } - - //else look by verbose syntax - for (i = 0; i < patternlab.patterns.length; i++) { - switch (key) { - case patternlab.patterns[i].subdir + '/' + patternlab.patterns[i].fileName: - case patternlab.patterns[i].subdir + '/' + patternlab.patterns[i].fileName + '.mustache': - return patternlab.patterns[i]; - } - } - - //return the fuzzy match if all else fails - for (i = 0; i < patternlab.patterns.length; i++) { - var keyParts = key.split('-'), - keyType = keyParts[0], - keyName = keyParts.slice(1).join('-'); - - if (patternlab.patterns[i].key.split('-')[0] === keyType && patternlab.patterns[i].key.indexOf(keyName) > -1) { - return patternlab.patterns[i]; - } - } - throw 'Could not find pattern with key ' + key; - } - - function processPatternIterative(file, patternlab) { - var fs = require('fs-extra'), - of = require('./object_factory'), - path = require('path'); - - //extract some information - var subdir = path.dirname(path.relative(patternlab.config.paths.source.patterns, file)).replace('\\', '/'); - var filename = path.basename(file); - var ext = path.extname(filename); - - //ignore dotfiles, underscored files, and non-variant .json files - if (filename.charAt(0) === '.' || (ext === '.json' && filename.indexOf('~') === -1)) { - return; - } - - //make a new Pattern Object - var currentPattern = new of.oPattern(file, subdir, filename); - - //if file is named in the syntax for variants, no need to process further - //processPatternRecursive() will run find_pseudopatterns() and look at each pattern for a variant - if (ext === '.json' && filename.indexOf('~') > -1) { - return; - } - - //can ignore all non-mustache files at this point - if (ext !== '.mustache') { - return; - } - - //see if this file has a state - setState(currentPattern, patternlab); - - //look for a json file for this template - try { - var jsonFilename = path.resolve(patternlab.config.paths.source.patterns, currentPattern.subdir, currentPattern.fileName + ".json"); - currentPattern.jsonFileData = fs.readJSONSync(jsonFilename); - if (patternlab.config.debug) { - console.log('found pattern-specific data.json for ' + currentPattern.key); - } - } - catch (error) { - // do nothing - } - - //look for a listitems.json file for this template - try { - var listJsonFileName = path.resolve(patternlab.config.paths.source.patterns, currentPattern.subdir, currentPattern.fileName + ".listitems.json"); - currentPattern.listitems = fs.readJSONSync(listJsonFileName); - buildListItems(currentPattern); - if (patternlab.config.debug) { - console.log('found pattern-specific listitems.json for ' + currentPattern.key); - } - } - catch (err) { - // do nothing - } - - //add the raw template to memory - currentPattern.template = fs.readFileSync(file, 'utf8'); - - //find any stylemodifiers that may be in the current pattern - currentPattern.stylePartials = findPartialsWithStyleModifiers(currentPattern); - - //find any pattern parameters that may be in the current pattern - currentPattern.parameteredPartials = findPartialsWithPatternParameters(currentPattern); - - //add currentPattern to patternlab.patterns array - addPattern(currentPattern, patternlab); - } - - function processPatternRecursive(file, patternlab) { - var lh = require('./lineage_hunter'), - ph = require('./parameter_hunter'), - pph = require('./pseudopattern_hunter'), - lih = require('./list_item_hunter'), - smh = require('./style_modifier_hunter'); - - var parameter_hunter = new ph(), - lineage_hunter = new lh(), - list_item_hunter = new lih(), - style_modifier_hunter = new smh(), - pseudopattern_hunter = new pph(); - - //find current pattern in patternlab object using var file as a key - var currentPattern, - i; - - for (i = 0; i < patternlab.patterns.length; i++) { - if (patternlab.patterns[i].abspath === file) { - currentPattern = patternlab.patterns[i]; - break; - } - } - - //return if processing an ignored file - if (typeof currentPattern === 'undefined') { - return; - } - - currentPattern.extendedTemplate = currentPattern.template; - - //find how many partials there may be for the given pattern - var foundPatternPartials = findPartials(currentPattern); - - if (foundPatternPartials !== null && foundPatternPartials.length > 0) { - - if (patternlab.config.debug) { - console.log('found partials for ' + currentPattern.key); - } - - //find any listItem blocks - list_item_hunter.process_list_item_partials(currentPattern, patternlab); - - //determine if the template contains any pattern parameters. if so they must be immediately consumed - parameter_hunter.find_parameters(currentPattern, patternlab); - - //do something with the regular old partials - for (i = 0; i < foundPatternPartials.length; i++) { - var partialKey = foundPatternPartials[i].replace(/{{>([ ])?([\w\-\.\/~]+)(:[A-z0-9-_|]+)?(?:\:[A-Za-z0-9-_]+)?(?:(| )\(.*)?([ ])?}}/g, '$2'); - - var partialPath; - - //identify which pattern this partial corresponds tou - for (var j = 0; j < patternlab.patterns.length; j++) { - if (patternlab.patterns[j].key === partialKey || - patternlab.patterns[j].abspath.indexOf(partialKey) > -1) { - partialPath = patternlab.patterns[j].abspath; - } - } - - //recurse through nested partials to fill out this extended template. - processPatternRecursive(partialPath, patternlab); - - //complete assembly of extended template - var partialPattern = getpatternbykey(partialKey, patternlab); - - //if partial has style modifier data, replace the styleModifier value - if (currentPattern.stylePartials && currentPattern.stylePartials.length > 0) { - style_modifier_hunter.consume_style_modifier(partialPattern, foundPatternPartials[i], patternlab); - } - - currentPattern.extendedTemplate = currentPattern.extendedTemplate.replace(foundPatternPartials[i], partialPattern.extendedTemplate); - - //update the extendedTemplate in the partials object in case this pattern is consumed later - patternlab.partials[currentPattern.key] = currentPattern.extendedTemplate; - } - - } else { - //find any listItem blocks that within the pattern, even if there are no partials - list_item_hunter.process_list_item_partials(currentPattern, patternlab); - } - - //find pattern lineage - lineage_hunter.find_lineage(currentPattern, patternlab); - - //add to patternlab object so we can look these up later. - addPattern(currentPattern, patternlab); - - //look for a pseudo pattern by checking if there is a file containing same name, with ~ in it, ending in .json - pseudopattern_hunter.find_pseudopatterns(currentPattern, patternlab); - } - - function mergeData(obj1, obj2) { - if (typeof obj2 === 'undefined') { - obj2 = {}; //eslint-disable-line no-param-reassign - } - - for (var p in obj1) { //eslint-disable-line guard-for-in - try { - // Only recurse if obj1[p] is an object. - if (obj1[p].constructor === Object) { - // Requires 2 objects as params; create obj2[p] if undefined. - if (typeof obj2[p] === 'undefined') { - obj2[p] = {}; - } - obj2[p] = mergeData(obj1[p], obj2[p]); - - // Pop when recursion meets a non-object. If obj1[p] is a non-object, - // only copy to undefined obj2[p]. This way, obj2 maintains priority. - } else if (typeof obj2[p] === 'undefined') { - obj2[p] = obj1[p]; - } - } catch (e) { - // Property in destination object not set; create it and set its value. - if (typeof obj2[p] === 'undefined') { - obj2[p] = obj1[p]; - } - } - } - return obj2; - } - - function parseDataLinksHelper(patternlab, obj, key) { - var linkRE, dataObjAsString, linkMatches, expandedLink; - - linkRE = /link\.[A-z0-9-_]+/g; - dataObjAsString = JSON.stringify(obj); - linkMatches = dataObjAsString.match(linkRE); - - if (linkMatches) { - for (var i = 0; i < linkMatches.length; i++) { - expandedLink = patternlab.data.link[linkMatches[i].split('.')[1]]; - if (expandedLink) { - if (patternlab.config.debug) { - console.log('expanded data link from ' + linkMatches[i] + ' to ' + expandedLink + ' inside ' + key); - } - dataObjAsString = dataObjAsString.replace(linkMatches[i], expandedLink); - } - } - } - return JSON.parse(dataObjAsString); - } - - //look for pattern links included in data files. - //these will be in the form of link.* WITHOUT {{}}, which would still be there from direct pattern inclusion - function parseDataLinks(patternlab) { - //look for link.* such as link.pages-blog as a value - - patternlab.data = parseDataLinksHelper(patternlab, patternlab.data, 'data.json'); - - //loop through all patterns - for (var i = 0; i < patternlab.patterns.length; i++) { - patternlab.patterns[i].jsonFileData = parseDataLinksHelper(patternlab, patternlab.patterns[i].jsonFileData, patternlab.patterns[i].key); - } - } - - return { - find_pattern_partials: function (pattern) { - return findPartials(pattern); - }, - find_pattern_partials_with_style_modifiers: function (pattern) { - return findPartialsWithStyleModifiers(pattern); - }, - find_pattern_partials_with_parameters: function (pattern) { - return findPartialsWithPatternParameters(pattern); - }, - find_list_items: function (pattern) { - return findListItems(pattern); - }, - setPatternState: function (pattern, patternlab) { - setState(pattern, patternlab); - }, - addPattern: function (pattern, patternlab) { - addPattern(pattern, patternlab); - }, - renderPattern: function (template, data, partials) { - return renderPattern(template, data, partials); - }, - process_pattern_iterative: function (file, patternlab) { - processPatternIterative(file, patternlab); - }, - process_pattern_recursive: function (file, patternlab, additionalData) { - processPatternRecursive(file, patternlab, additionalData); - }, - get_pattern_by_key: function (key, patternlab) { - return getpatternbykey(key, patternlab); - }, - merge_data: function (existingData, newData) { - return mergeData(existingData, newData); - }, - combine_listItems: function (patternlab) { - buildListItems(patternlab); - }, - parse_data_links: function (patternlab) { - parseDataLinks(patternlab); - } - }; - -}; - -module.exports = pattern_assembler; - - diff --git a/core/lib/pattern_exporter.js b/core/lib/pattern_exporter.js deleted file mode 100644 index ff53cac6c..000000000 --- a/core/lib/pattern_exporter.js +++ /dev/null @@ -1,40 +0,0 @@ -/* - * patternlab-node - v1.2.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - -"use strict"; - -var fs = require('fs-extra'); - -var pattern_exporter = function () { - - function exportPatterns(patternlab) { - //read the config export options - var exportKeys = patternlab.config.patternExportKeys; - - //find the chosen patterns to export - for (var i = 0; i < exportKeys.length; i++) { - for (var j = 0; j < patternlab.patterns.length; j++) { - if (exportKeys[i] === patternlab.patterns[j].key) { - //write matches to the desired location - fs.outputFileSync(patternlab.config.patternExportDirectory + patternlab.patterns[j].key + '.html', patternlab.patterns[j].patternPartial); - } - } - } - } - - return { - export_patterns: function (patternlab) { - exportPatterns(patternlab); - } - }; - -}; - -module.exports = pattern_exporter; diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js deleted file mode 100644 index cc910a5bc..000000000 --- a/core/lib/patternlab.js +++ /dev/null @@ -1,596 +0,0 @@ -/* - * patternlab-node - v1.2.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - -var patternlab_engine = function (config) { - 'use strict'; - - var path = require('path'), - fs = require('fs-extra'), - diveSync = require('diveSync'), - of = require('./object_factory'), - pa = require('./pattern_assembler'), - mh = require('./media_hunter'), - pe = require('./pattern_exporter'), - lh = require('./lineage_hunter'), - he = require('html-entities').AllHtmlEntities, - patternlab = {}; - - patternlab.package = fs.readJSONSync('./package.json'); - patternlab.config = config || fs.readJSONSync(path.resolve(__dirname, '../../patternlab-config.json')); - - var paths = patternlab.config.paths; - - - function getVersion() { - console.log(patternlab.package.version); - } - - function help() { - console.log('Patternlab Node Help'); - console.log('==============================='); - console.log('Command Line Arguments'); - console.log('patternlab:only_patterns'); - console.log(' > Compiles the patterns only, outputting to config.patterns.public'); - console.log('patternlab:v'); - console.log(' > Retrieve the version of patternlab-node you have installed'); - console.log('patternlab:help'); - console.log(' > Get more information about patternlab-node, pattern lab in general, and where to report issues.'); - console.log('==============================='); - console.log('Visit http://patternlab.io/docs/index.html for general help on pattern-lab'); - console.log('Visit https://github.com/pattern-lab/patternlab-node/issues to open a bug.'); - } - - function printDebug() { - //debug file can be written by setting flag on patternlab-config.json - if (patternlab.config.debug) { - console.log('writing patternlab debug file to ./patternlab.json'); - fs.outputFileSync('./patternlab.json', JSON.stringify(patternlab, null, 3)); - } - } - - function setCacheBust() { - if (patternlab.config.cacheBust) { - if (patternlab.config.debug) { - console.log('setting cacheBuster value for frontend assets.'); - } - patternlab.cacheBuster = new Date().getTime(); - } else { - patternlab.cacheBuster = 0; - } - } - - function buildPatterns(deletePatternDir) { - patternlab.data = fs.readJSONSync(path.resolve(paths.source.data, 'data.json')); - patternlab.listitems = fs.readJSONSync(path.resolve(paths.source.data, 'listitems.json')); - patternlab.header = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/pattern-header-footer/header.html'), 'utf8'); - patternlab.footerPattern = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/pattern-header-footer/footer-pattern.html'), 'utf8'); - patternlab.footer = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/pattern-header-footer/footer.html'), 'utf8'); - patternlab.patterns = []; - patternlab.partials = {}; - patternlab.data.link = {}; - - setCacheBust(); - - var pattern_assembler = new pa(), - entity_encoder = new he(), - pattern_exporter = new pe(), - lineage_hunter = new lh(), - patterns_dir = paths.source.patterns; - - pattern_assembler.combine_listItems(patternlab); - - //diveSync once to perform iterative populating of patternlab object - diveSync( - patterns_dir, - { - filter: function (filePath, dir) { - if (dir) { - var remainingPath = filePath.replace(patterns_dir, ''); - var isValidPath = remainingPath.indexOf('/_') === -1; - return isValidPath; - } - return true; - } - }, - function (err, file) { - //log any errors - if (err) { - console.log(err); - return; - } - pattern_assembler.process_pattern_iterative(path.resolve(file), patternlab); - } - ); - - //diveSync again to recursively include partials, filling out the - //extendedTemplate property of the patternlab.patterns elements - diveSync( - patterns_dir, - { - filter: function (filePath, dir) { - if (dir) { - var remainingPath = filePath.replace(patterns_dir, ''); - var isValidPath = remainingPath.indexOf('/_') === -1; - return isValidPath; - } - return true; - } - }, - function (err, file) { - //log any errors - if (err) { - console.log(err); - return; - } - pattern_assembler.process_pattern_recursive(path.resolve(file), patternlab); - }); - - //set user defined head and foot if they exist - try { - patternlab.userHead = pattern_assembler.get_pattern_by_key('atoms-head', patternlab); - } - catch (ex) { - if (patternlab.config.debug) { - console.log(ex); - console.log('Could not find optional user-defined header, atoms-head pattern. It was likely deleted.'); - } - } - try { - patternlab.userFoot = pattern_assembler.get_pattern_by_key('atoms-foot', patternlab); - } - catch (ex) { - if (patternlab.config.debug) { - console.log(ex); - console.log('Could not find optional user-defined footer, atoms-foot pattern. It was likely deleted.'); - } - } - - //now that all the main patterns are known, look for any links that might be within data and expand them - //we need to do this before expanding patterns & partials into extendedTemplates, otherwise we could lose the data -> partial reference - pattern_assembler.parse_data_links(patternlab); - - //cascade any patternStates - lineage_hunter.cascade_pattern_states(patternlab); - - //delete the contents of config.patterns.public before writing - if (deletePatternDir) { - fs.emptyDirSync(paths.public.patterns); - } - - //set pattern-specific header if necessary - var head; - if (patternlab.userHead) { - head = patternlab.userHead.extendedTemplate.replace('{% pattern-lab-head %}', patternlab.header); - } else { - head = patternlab.header; - } - - //render all patterns last, so lineageR works - patternlab.patterns.forEach(function (pattern) { - - pattern.header = head; - - //json stringify lineage and lineageR - var lineageArray = []; - for (var i = 0; i < pattern.lineage.length; i++) { - lineageArray.push(JSON.stringify(pattern.lineage[i])); - } - pattern.lineage = lineageArray; - - var lineageRArray = []; - for (var i = 0; i < pattern.lineageR.length; i++) { - lineageRArray.push(JSON.stringify(pattern.lineageR[i])); - } - pattern.lineageR = lineageRArray; - - //render the pattern, but first consolidate any data we may have - var allData = JSON.parse(JSON.stringify(patternlab.data)); - allData = pattern_assembler.merge_data(allData, pattern.jsonFileData); - - //also add the cachebuster value. slight chance this could collide with a user that has defined cacheBuster as a value - allData.cacheBuster = patternlab.cacheBuster; - pattern.cacheBuster = patternlab.cacheBuster; - - //render the pattern-specific header - var headHtml = pattern_assembler.renderPattern(pattern.header, allData); - - //render the extendedTemplate with all data - pattern.patternPartial = pattern_assembler.renderPattern(pattern.extendedTemplate, allData); - - //set the pattern-specific footer if necessary - if (patternlab.userFoot) { - var userFooter = patternlab.userFoot.extendedTemplate.replace('{% pattern-lab-foot %}', patternlab.footerPattern + patternlab.footer); - pattern.footer = pattern_assembler.renderPattern(userFooter, pattern); - } else { - pattern.footer = pattern_assembler.renderPattern(patternlab.footerPattern, pattern); - } - - //write the compiled template to the public patterns directory - fs.outputFileSync(paths.public.patterns + pattern.patternLink, headHtml + pattern.patternPartial + pattern.footer); - - //write the mustache file too - fs.outputFileSync(paths.public.patterns + pattern.patternLink.replace('.html', '.mustache'), entity_encoder.encode(pattern.template)); - - //write the encoded version too - fs.outputFileSync(paths.public.patterns + pattern.patternLink.replace('.html', '.escaped.html'), entity_encoder.encode(pattern.patternPartial)); - }); - - //export patterns if necessary - pattern_exporter.export_patterns(patternlab); - } - - function addToPatternPaths(bucketName, pattern) { - //this is messy, could use a refactor. - patternlab.patternPaths[bucketName][pattern.patternName] = pattern.subdir.replace(/\\/g, '/') + "/" + pattern.fileName; - } - - //todo: refactor this as a method on the pattern object itself once we merge dev with pattern-engines branch - function isPatternExcluded(pattern) { - // returns whether or not the first character of the pattern filename is an underscore, or excluded - return pattern.fileName.charAt(0) === '_'; - } - - function buildFrontEnd() { - var pattern_assembler = new pa(), - media_hunter = new mh(), - styleGuideExcludes = patternlab.config.styleGuideExcludes, - styleguidePatterns = [], - i; // for loops - - patternlab.buckets = []; - patternlab.bucketIndex = []; - patternlab.patternPaths = {}; - patternlab.viewAllPaths = {}; - - //sort all patterns explicitly. - patternlab.patterns = patternlab.patterns.sort(function (a, b) { - if (a.name > b.name) { return 1; } - if (a.name < b.name) { return -1; } - - // a must be equal to b - return 0; - }); - - //find mediaQueries - media_hunter.find_media_queries('./source/css', patternlab); - - // check if patterns are excluded, if not add them to styleguidePatterns - if (styleGuideExcludes && styleGuideExcludes.length) { - for (i = 0; i < patternlab.patterns.length; i++) { - - // skip underscore-prefixed files - if (isPatternExcluded(patternlab.patterns[i])) { - if (patternlab.config.debug) { - console.log('Omitting ' + patternlab.patterns[i].key + " from styleguide pattern exclusion."); - } - continue; - } - - var key = patternlab.patterns[i].key; - var typeKey = key.substring(0, key.indexOf('-')); - var isExcluded = (styleGuideExcludes.indexOf(typeKey) > -1); - if (!isExcluded) { - styleguidePatterns.push(patternlab.patterns[i]); - } - } - } else { - styleguidePatterns = patternlab.patterns; - } - - //also add the cachebuster value. slight chance this could collide with a user that has defined cacheBuster as a value - patternlab.data.cacheBuster = patternlab.cacheBuster; - - //get the main page head and foot - var mainPageHead = patternlab.userHead.extendedTemplate.replace('{% pattern-lab-head %}', patternlab.header); - var mainPageHeadHtml = pattern_assembler.renderPattern(mainPageHead, patternlab.data); - var mainPageFoot = patternlab.userFoot.extendedTemplate.replace('{% pattern-lab-foot %}', patternlab.footer); - var mainPageFootHtml = pattern_assembler.renderPattern(mainPageFoot, patternlab.data); - - //build the styleguide - var styleguideTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/styleguide.mustache'), 'utf8'), - styleguideHtml = pattern_assembler.renderPattern(styleguideTemplate, {partials: styleguidePatterns, cacheBuster: patternlab.cacheBuster}); - - fs.outputFileSync(path.resolve(paths.public.styleguide, 'html/styleguide.html'), mainPageHeadHtml + styleguideHtml + mainPageFootHtml); - - //build the viewall pages - var prevSubdir = '', - prevGroup = ''; - - for (i = 0; i < patternlab.patterns.length; i++) { - // skip underscore-prefixed files - if (isPatternExcluded(patternlab.patterns[i])) { - if (patternlab.config.debug) { - console.log('Omitting ' + patternlab.patterns[i].key + " from view all rendering."); - } - continue; - } - - var pattern = patternlab.patterns[i]; - - //create the view all for the section - // check if the current section is different from the previous one - if (pattern.patternGroup !== prevGroup) { - prevGroup = pattern.patternGroup; - - var viewAllPatterns = [], - patternPartial = "viewall-" + pattern.patternGroup, - j; - - for (j = 0; j < patternlab.patterns.length; j++) { - if (patternlab.patterns[j].patternGroup === pattern.patternGroup) { - //again, skip any sibling patterns to the current one that may have underscores - if (isPatternExcluded(patternlab.patterns[j])) { - if (patternlab.config.debug) { - console.log('Omitting ' + patternlab.patterns[j].key + " from view all sibling rendering."); - } - continue; - } - - viewAllPatterns.push(patternlab.patterns[j]); - } - } - - var viewAllTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/viewall.mustache'), 'utf8'); - var viewAllHtml = pattern_assembler.renderPattern(viewAllTemplate, {partials: viewAllPatterns, patternPartial: patternPartial, cacheBuster: patternlab.cacheBuster }); - fs.outputFileSync(paths.public.patterns + pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length) + '/index.html', mainPageHead + viewAllHtml + mainPageFoot); - } - - // create the view all for the subsection - // check if the current sub section is different from the previous one - if (pattern.subdir !== prevSubdir) { - prevSubdir = pattern.subdir; - - var viewAllPatterns = [], - patternPartial = "viewall-" + pattern.patternGroup + "-" + pattern.patternSubGroup, - j; - - for (j = 0; j < patternlab.patterns.length; j++) { - if (patternlab.patterns[j].subdir === pattern.subdir) { - //again, skip any sibling patterns to the current one that may have underscores - if (isPatternExcluded(patternlab.patterns[j])) { - if (patternlab.config.debug) { - console.log('Omitting ' + patternlab.patterns[j].key + " from view all sibling rendering."); - } - continue; - } - viewAllPatterns.push(patternlab.patterns[j]); - } - } - - var viewAllTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/viewall.mustache'), 'utf8'); - var viewAllHtml = pattern_assembler.renderPattern(viewAllTemplate, {partials: viewAllPatterns, patternPartial: patternPartial, cacheBuster: patternlab.cacheBuster}); - fs.outputFileSync(paths.public.patterns + pattern.flatPatternPath + '/index.html', mainPageHeadHtml + viewAllHtml + mainPageFootHtml); - } - } - - //build the patternlab website - var patternlabSiteTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/index.mustache'), 'utf8'); - - //loop through all patterns.to build the navigation - //todo: refactor this someday - for (i = 0; i < patternlab.patterns.length; i++) { - - var pattern = patternlab.patterns[i]; - var bucketName = pattern.name.replace(/\\/g, '-').split('-')[1]; - - //check if the bucket already exists - var bucketIndex = patternlab.bucketIndex.indexOf(bucketName); - if (bucketIndex === -1) { - - // skip underscore-prefixed files. don't create a bucket on account of an underscored pattern - if (isPatternExcluded(pattern)) { - continue; - } - - //add the bucket - var bucket = new of.oBucket(bucketName); - - //add patternPath and viewAllPath - patternlab.patternPaths[bucketName] = {}; - patternlab.viewAllPaths[bucketName] = {}; - - //get the navItem - var navItemName = pattern.subdir.split('/').pop(); - navItemName = navItemName.replace(/(\d).(-)/g, ''); - - //get the navSubItem - var navSubItemName = pattern.patternName.replace(/-/g, ' '); - - //test whether the pattern struture is flat or not - usually due to a template or page - var flatPatternItem = false; - if (navItemName === bucketName) { - flatPatternItem = true; - } - - //assume the navItem does not exist. - var navItem = new of.oNavItem(navItemName); - - //assume the navSubItem does not exist. - var navSubItem = new of.oNavSubItem(navSubItemName); - navSubItem.patternPath = pattern.patternLink; - navSubItem.patternPartial = bucketName + "-" + pattern.patternName; //add the hyphenated name - - //add the patternState if it exists - if (pattern.patternState) { - navSubItem.patternState = pattern.patternState; - } - - //if it is flat - we should not add the pattern to patternPaths - if (flatPatternItem) { - bucket.patternItems.push(navSubItem); - - //add to patternPaths - addToPatternPaths(bucketName, pattern); - - } else { - bucket.navItems.push(navItem); - bucket.navItemsIndex.push(navItemName); - navItem.navSubItems.push(navSubItem); - navItem.navSubItemsIndex.push(navSubItemName); - - //add to patternPaths - addToPatternPaths(bucketName, pattern); - - //add the navViewAllItem - var navViewAllItem = new of.oNavSubItem("View All"); - navViewAllItem.patternPath = pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length) + "/index.html"; - navViewAllItem.patternPartial = "viewall-" + pattern.patternGroup; - - bucket.patternItems.push(navViewAllItem); - patternlab.viewAllPaths[bucketName].viewall = pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length); - } - - //add the bucket. - patternlab.buckets.push(bucket); - patternlab.bucketIndex.push(bucketName); - - //done - - } else { - //find the bucket - var bucket = patternlab.buckets[bucketIndex]; - - //get the navItem - //if there is one or more slashes in the subdir, get everything after - //the last slash. if no slash, get the whole subdir string and strip - //any numeric + hyphen prefix - var navItemName = pattern.subdir.split('/').pop().replace(/^\d*\-/, ''); - - //get the navSubItem - var navSubItemName = pattern.patternName.replace(/-/g, ' '); - - //assume the navSubItem does not exist. - var navSubItem = new of.oNavSubItem(navSubItemName); - navSubItem.patternPath = pattern.patternLink; - navSubItem.patternPartial = bucketName + "-" + pattern.patternName; //add the hyphenated name - - //add the patternState if it exists - if (pattern.patternState) { - navSubItem.patternState = pattern.patternState; - } - - //test whether the pattern struture is flat or not - usually due to a template or page - var flatPatternItem = false; - if (navItemName === bucketName) { - flatPatternItem = true; - } - - //if it is flat - we should not add the pattern to patternPaths - if (flatPatternItem) { - - // skip underscore-prefixed files - if (isPatternExcluded(pattern)) { - continue; - } - - //add the navItem to patternItems - bucket.patternItems.push(navSubItem); - - //add to patternPaths - addToPatternPaths(bucketName, pattern); - - } else { - - // only do this if pattern is included - if (!isPatternExcluded(pattern)) { - //check to see if navItem exists - var navItemIndex = bucket.navItemsIndex.indexOf(navItemName); - if (navItemIndex === -1) { - var navItem = new of.oNavItem(navItemName); - - //add the navItem and navSubItem - navItem.navSubItems.push(navSubItem); - navItem.navSubItemsIndex.push(navSubItemName); - bucket.navItems.push(navItem); - bucket.navItemsIndex.push(navItemName); - - } else { - //add the navSubItem - var navItem = bucket.navItems[navItemIndex]; - navItem.navSubItems.push(navSubItem); - navItem.navSubItemsIndex.push(navSubItemName); - } - } - - //check if we are moving to a new sub section in the next loop - if (!patternlab.patterns[i + 1] || pattern.patternSubGroup !== patternlab.patterns[i + 1].patternSubGroup) { - - //add the navViewAllSubItem - var navViewAllSubItem = new of.oNavSubItem(""); - navViewAllSubItem.patternName = "View All"; - navViewAllSubItem.patternPath = pattern.flatPatternPath + "/index.html"; - navViewAllSubItem.patternPartial = "viewall-" + pattern.patternGroup + "-" + pattern.patternSubGroup; - - navItem.navSubItems.push(navViewAllSubItem); - navItem.navSubItemsIndex.push("View All"); - } - - // just add to patternPaths - addToPatternPaths(bucketName, pattern); - } - - } - - patternlab.viewAllPaths[bucketName][pattern.patternSubGroup] = pattern.flatPatternPath; - - } - - //the patternlab site requires a lot of partials to be rendered. - //patternNav - var patternNavTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/patternNav.mustache'), 'utf8'); - var patternNavPartialHtml = pattern_assembler.renderPattern(patternNavTemplate, patternlab); - - //ishControls - var ishControlsTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/ishControls.mustache'), 'utf8'); - patternlab.config.mqs = patternlab.mediaQueries; - var ishControlsPartialHtml = pattern_assembler.renderPattern(ishControlsTemplate, patternlab.config); - - //patternPaths - var patternPathsTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/patternPaths.mustache'), 'utf8'); - var patternPathsPartialHtml = pattern_assembler.renderPattern(patternPathsTemplate, {'patternPaths': JSON.stringify(patternlab.patternPaths)}); - - //viewAllPaths - var viewAllPathsTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/viewAllPaths.mustache'), 'utf8'); - var viewAllPathsPartialHtml = pattern_assembler.renderPattern(viewAllPathsTemplate, {'viewallpaths': JSON.stringify(patternlab.viewAllPaths)}); - - //render the patternlab template, with all partials - var patternlabSiteHtml = pattern_assembler.renderPattern(patternlabSiteTemplate, { - defaultPattern: patternlab.config.defaultPattern || 'all', - cacheBuster: patternlab.cacheBuster - }, { - 'ishControls': ishControlsPartialHtml, - 'patternNav': patternNavPartialHtml, - 'patternPaths': patternPathsPartialHtml, - 'viewAllPaths': viewAllPathsPartialHtml - }); - fs.outputFileSync(path.resolve(paths.public.root, 'index.html'), patternlabSiteHtml); - } - - return { - version: function () { - return getVersion(); - }, - build: function (deletePatternDir) { - buildPatterns(deletePatternDir); - buildFrontEnd(); - printDebug(); - }, - help: function () { - help(); - }, - build_patterns_only: function (deletePatternDir) { - buildPatterns(deletePatternDir); - printDebug(); - } - }; - -}; - -module.exports = patternlab_engine; diff --git a/core/lib/patternlab_grunt.js b/core/lib/patternlab_grunt.js deleted file mode 100644 index d124a7e0e..000000000 --- a/core/lib/patternlab_grunt.js +++ /dev/null @@ -1,38 +0,0 @@ -/* - * patternlab-node - v1.2.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - -var patternlab_engine = require('./patternlab.js'); - -module.exports = function (grunt) { - grunt.registerTask('patternlab', 'create design systems with atomic design', function (arg) { - var patternlab = patternlab_engine(); - - if (arguments.length === 0) { - patternlab.build(true); - } - - if (arg && arg === 'v') { - patternlab.version(); - } - - if (arg && arg === "only_patterns") { - patternlab.build_patterns_only(true); - } - - if (arg && arg === "help") { - patternlab.help(); - } - - if (arg && (arg !== "v" && arg !== "only_patterns" && arg !== "help")) { - patternlab.help(); - } - }); - -}; diff --git a/core/lib/patternlab_gulp.js b/core/lib/patternlab_gulp.js deleted file mode 100644 index be02179cf..000000000 --- a/core/lib/patternlab_gulp.js +++ /dev/null @@ -1,35 +0,0 @@ -/* - * patternlab-node - v1.2.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - -var patternlab_engine = require('./patternlab.js'); - -module.exports = function (gulp) { - - gulp.task('patternlab', ['clean'], function (cb) { - var patternlab = patternlab_engine(); - patternlab.build(false); - cb(); - }); - - gulp.task('patternlab:version', function () { - var patternlab = patternlab_engine(); - patternlab.version(); - }); - - gulp.task('patternlab:only_patterns', ['clean'], function () { - var patternlab = patternlab_engine(); - patternlab.build_patterns_only(false); - }); - - gulp.task('patternlab:help', function () { - var patternlab = patternlab_engine(); - patternlab.help(); - }); -}; diff --git a/core/lib/pseudopattern_hunter.js b/core/lib/pseudopattern_hunter.js deleted file mode 100644 index 053e520c3..000000000 --- a/core/lib/pseudopattern_hunter.js +++ /dev/null @@ -1,76 +0,0 @@ -/* - * patternlab-node - v1.2.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - -"use strict"; - -var pseudopattern_hunter = function () { - - function findpseudopatterns(currentPattern, patternlab) { - var glob = require('glob'), - fs = require('fs-extra'), - pa = require('./pattern_assembler'), - lh = require('./lineage_hunter'), - of = require('./object_factory'), - path = require('path'); - - var pattern_assembler = new pa(); - var lineage_hunter = new lh(); - var paths = patternlab.config.paths; - - //look for a pseudo pattern by checking if there is a file containing same name, with ~ in it, ending in .json - var needle = currentPattern.subdir + '/' + currentPattern.fileName + '~*.json'; - var pseudoPatterns = glob.sync(needle, { - cwd: paths.source.patterns, - debug: false, - nodir: true - }); - - if (pseudoPatterns.length > 0) { - for (var i = 0; i < pseudoPatterns.length; i++) { - if (patternlab.config.debug) { - console.log('found pseudoPattern variant of ' + currentPattern.key); - } - - //we want to do everything we normally would here, except instead read the pseudoPattern data - var variantFileData = fs.readJSONSync(path.resolve(paths.source.patterns, pseudoPatterns[i])); - - //extend any existing data with variant data - variantFileData = pattern_assembler.merge_data(currentPattern.jsonFileData, variantFileData); - - var variantName = pseudoPatterns[i].substring(pseudoPatterns[i].indexOf('~') + 1).split('.')[0]; - var variantFilePath = path.resolve(paths.source.patterns, currentPattern.subdir, currentPattern.fileName + '~' + variantName + '.json'); - var variantFileName = currentPattern.fileName + '-' + variantName + '.'; - var patternVariant = new of.oPattern(variantFilePath, currentPattern.subdir, variantFileName, variantFileData); - - //see if this file has a state - pattern_assembler.setPatternState(patternVariant, patternlab); - - //use the same template as the non-variant - patternVariant.template = currentPattern.template; - patternVariant.extendedTemplate = currentPattern.extendedTemplate; - - //find pattern lineage - lineage_hunter.find_lineage(patternVariant, patternlab); - - //add to patternlab object so we can look these up later. - pattern_assembler.addPattern(patternVariant, patternlab); - } - } - } - - return { - find_pseudopatterns: function (pattern, patternlab) { - findpseudopatterns(pattern, patternlab); - } - }; - -}; - -module.exports = pseudopattern_hunter; diff --git a/core/lib/style_modifier_hunter.js b/core/lib/style_modifier_hunter.js deleted file mode 100644 index b6f870074..000000000 --- a/core/lib/style_modifier_hunter.js +++ /dev/null @@ -1,43 +0,0 @@ -/* - * patternlab-node - v1.2.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - -"use strict"; - -var style_modifier_hunter = function () { - - function consumestylemodifier(pattern, partial, patternlab) { - //extract the classname from the stylemodifier which comes in the format of :className - var styleModifier = partial.match(/:([\w\-_|])+/g) ? partial.match(/:([\w\-_|])+/g)[0].slice(1) : null; - - if (styleModifier) { - //replace the special character pipe | used to separate multiple classes with a space - styleModifier = styleModifier.replace(/\|/g, ' '); - - if (patternlab.config.debug) { - console.log('found partial styleModifier within pattern ' + pattern.key); - } - - //replace the stylemodifier placeholder with the class name - pattern.extendedTemplate = pattern.extendedTemplate.replace(/{{[ ]?styleModifier[ ]?}}/i, styleModifier); - - //update the extendedTemplate in the partials object in case this pattern is consumed later - patternlab.partials[pattern.key] = pattern.extendedTemplate; - } - } - - return { - consume_style_modifier: function (pattern, partial, patternlab) { - consumestylemodifier(pattern, partial, patternlab); - } - }; - -}; - -module.exports = style_modifier_hunter; diff --git a/core/styleguide/css/static.css b/core/styleguide/css/static.css deleted file mode 100644 index e23eaf41e..000000000 --- a/core/styleguide/css/static.css +++ /dev/null @@ -1,459 +0,0 @@ -@charset "UTF-8"; -/* -colors -red: $orange; rgb(229,24,55) -gray: #808080; -*/ -/************Reset**************/ -* { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} - -html, body, div, object, iframe, fieldset { - margin: 0; - padding: 0; - border: 0; -} - -ol, ul { - list-style: none; - margin: 0; - padding: 0; -} - -table { - border-collapse: collapse; - border-spacing: 0; -} - -header, footer, nav, section, article, hgroup, figure { - display: block; -} - -legend { - display: none; -} - -/************End Reset**************/ -/************Global**************/ -body { - background: #fff; - color: #000; - font: 100%/1.4 "HelveticaNeue", "Helvetica", "Arial", sans-serif; - padding: 0; - -webkit-text-size-adjust: 100%; - border-top: 20px solid #000; - border-bottom: 20px solid #000; -} - -a { - color: #808080; - text-decoration: none; -} - -a:hover, a:focus { - color: #bededf; -} - -p { - margin: 0 0 1em; -} - -img, object, video { - max-width: 100%; - border: 0; -} - -a img { - border: 0; - outline: 0; -} - -h1 { - font-size: 3em; - line-height: 1; - letter-spacing: -0.02em; - margin-bottom: 0.2em; -} - -h2 { - font-size: 2em; - line-height: 1.1; - margin-bottom: 0.2em; -} - -h3 { - font-weight: normal; - line-height: 1.1; - padding-bottom: 0.4em; - border-bottom: 1px solid #ccc; -} - -h1 a, h2 a, h3 a { - display: block; - color: #000; -} - -h1 a:hover, h2 a:hover, h3 a:hover { - color: #bededf; -} - -blockquote { - border-left: 0.5em solid #ddd; - padding-left: 1em; - margin-left: 1em; -} - -small { - color: #bededf; -} - -input[type=search] { - -webkit-appearance: none; - border-radius: 0; -} - -::-webkit-input-placeholder { - color: #808080; -} - -:-moz-placeholder { - color: #808080; -} - -/************End Global**************/ -/************Classes**************/ -.inactive { - color: #ddd; -} - -/************End Classes**************/ -/************Structure**************/ -.container { - max-width: 60em; - margin: 0 auto; - padding: 0 1em; - overflow: hidden; -} - -[role=main] { - padding-bottom: 1em; -} - -/*Footer*/ -[role=contentinfo] { - color: #fff; - background: #000; - margin: 0 -1em; - position: relative; - z-index: 2; -} -[role=contentinfo] > div { - max-width: 60em; - padding: 0 1em; - margin: 0 auto; - overflow: hidden; -} - -/*End Footer*/ -/*Grid*/ -.grid { - margin: 0 -1em; - overflow: hidden; -} - -.grid:target { - -webkit-animation: fadeout 5s 1 ease-out; - -moz-animation: fadeout 5s 1 ease-out; - -o-animation: fadeout 5s 1 ease-out; - animation: fadeout 5s 1 ease-out; -} - -.grid > h2 { - margin-left: 0.45em; -} - -.grid > section { - padding: 1em 1em 0.5em; -} - -.grid > section:target { - -webkit-animation: fadeout 5s 1 ease-out; - -moz-animation: fadeout 5s 1 ease-out; - -o-animation: fadeout 5s 1 ease-out; - animation: fadeout 5s 1 ease-out; -} - -.grid ul { - overflow: hidden; -} - -.grid ul li { - margin-bottom: 0.3em; -} - -.featured:after { - content: "*"; - color: #bededf; -} - -/*Fluid*/ -.fluid { - display: block; - margin: 0 auto; - max-width: 40em; -} - -/*Homepage*/ -.home h1 { - margin-bottom: 0.2em; -} - -.intro { - font-size: 1.8em; - line-height: 1.2; - margin: 0 auto; -} - -.intro a:hover, .intro a:focus { - color: #000; - border-bottom-color: #000; -} - -.ani { - position: relative; - height: 15em; - margin: 1em 0 0; - width: 100%; - z-index: 0; -} - -.ani div { - width: 100%; -} - -.ani div b { - display: block; - position: absolute; - top: 5%; - right: 5%; - bottom: 5%; - left: 5%; - background: rgba(229, 24, 55, 0.22); -} - -/*Patterns*/ -.mod { - padding: 1em; -} - -.pattern { - background: #f7f7f7; - border-bottom: 1px solid #808080; - margin-bottom: 1em; - overflow: hidden; -} - -.pattern-description h1 { - font-size: 3.4em; - margin-bottom: 0.5em; -} - -.pattern-description { - max-width: 40em; - margin: 0 auto; -} - -.pattern-description ul, .pattern-description ol { - margin-bottom: 2em; -} - -.pattern-description li { - margin-bottom: 1em; -} - -/*Blog*/ -/*Blog Header*/ -.blog .container { - max-width: 62em; -} - -.blog header[role=banner] { - overflow: hidden; - margin-bottom: 2em; - padding: 2em 0 1em; - border-bottom: 1px solid #000; -} - -.blog-logo { - font-weight: normal; - font-size: 1.2em; - margin: 0 0 1em; -} - -.blog-logo img { - width: 3.3em; -} - -.blog-logo a { - color: #000; -} - -.search-form { - width: 100%; - margin-bottom: 1em; -} - -.search-field { - width: 100%; - padding: 0.5em 0; - border: 0; - border-bottom: 1px solid #808080; - outline: none; -} - -.search-field:focus { - background: #bededf; - color: #fff; -} - -.search-field:focus::-webkit-input-placeholder { - color: #fff; -} - -.search-field:focus :-moz-placeholder { - color: #fff; -} - -.blog .nav { - clear: both; -} - -.blog .nav a { - display: block; - font-weight: bold; - color: #000; -} - -.blog .nav a:hover { - color: #bededf; -} - -/*Posts*/ -.posts ol > li { - padding-bottom: 1em; - border-bottom: 1px solid #ccc; - margin-bottom: 1em; - overflow: hidden; -} - -.posts h2 { - font-size: 1.4em; - margin: 0.28em 0 0.1em; - font-weight: normal; -} - -.posts h2 a { - color: #000; -} - -.posts h2 a:hover, .posts h2 a:focus { - color: #bededf; -} - -.permalink { - display: block; - font-size: 0.8em; - margin-bottom: 1.2em; -} - -.post-body a { - border-bottom: 1px solid #ccc; -} - -.posts blockquote { - margin: 0 0 1em; - color: #666; - border-left: 0.25em solid #ccc; - padding-left: 1em; -} - -.tags { - float: left; -} - -.tags li { - display: inline-block; - font-size: 0.8em; - margin-right: 0.5em; -} - -.posts ol > li .tags a, .permalink { - color: #ccc; - -webkit-transition: color 0.3s ease-out; - -moz-transition: color 0.3s ease-out; - -ms-transition: color 0.3s ease-out; - -o-transition: color 0.3s ease-out; - transition: color 0.3s ease-out; -} - -.posts ol > li:hover .tags a, .posts ol > li:hover .permalink { - color: #808080; -} - -.blog-nav { - text-align: center; - overflow: hidden; - padding: 1em 0; -} - -.posts .blog-nav a { - border: 0; -} - -.nav-next { - float: right; -} - -.nav-prev { - float: left; -} - -/* Sidebar */ -.sidebar { - font-size: 0.8em; - padding-bottom: 1.4em; -} - -.sidebar div { - margin-bottom: 2em; -} - -.sidebar h3 { - font-weight: bold; - font-size: 0.9em; - line-height: 1; - border-bottom: 1px solid #000; -} - -.sidebar a { - color: #808080; -} - -.sidebar a:hover, .sidebar a:focus { - color: #bededf; -} - -.top { - clear: both; - display: block; - padding: 1em 0; -} - -.top:before { - content: 'Γû▓'; -} - -/*# sourceMappingURL=static.css.map */ diff --git a/core/styleguide/css/styleguide-specific.css b/core/styleguide/css/styleguide-specific.css deleted file mode 100644 index 3be158e1a..000000000 --- a/core/styleguide/css/styleguide-specific.css +++ /dev/null @@ -1,101 +0,0 @@ -/*------------------------------------*\ - $PATTERN LAB-SPECIFIC STYLES -\*------------------------------------*/ -/** - * This stylesheet is for styles you want to include only when the interface is being viewed within Pattern Lab. - * This is helpful for displaying demo styles for grids, animations, color swatches, etc - * It's also helpful for overriding context-specific styles like fixed or absolutely positioned elements - * These styles will not be your production CSS. - */ -/* Style Guide Interface Colors */ -/* Typography */ -/* Defaults */ -/* Dimensions */ -/* Breakpoints */ -.demo { - overflow: hidden; - margin-bottom: 1rem; -} - -.demo .gi, .demo .demo-block { - background: #ddd; - color: #808080; - text-align: center; - margin-bottom: 0.5em; - padding: 1em !important; -} -.demo .gi:nth-of-type(2n), .demo .demo-block:nth-of-type(2n) { - color: #ddd; - background: #808080; -} -.demo .gi .gi, .demo .demo-block .gi { - background: rgba(0, 0, 0, 0.1); - color: #ddd; -} -.demo .gi .gi:nth-of-type(2n), .demo .demo-block .gi:nth-of-type(2n) { - background: rgba(0, 0, 0, 0.3); -} - -.demo-animate { - background: #ddd; - padding: 1em; - margin-bottom: 1em; - text-align: center; -} - -.animate-move { - position: relative; -} -.animate-move .demo-shape { - position: absolute; - top: 0; - left: 0; - bottom: 0; - width: 20px; - background: #808080; -} -.animate-move:hover > .demo-shape { - left: 100%; - margin-left: -20px; -} - -.sg-colors { - overflow: hidden; -} -.sg-colors li { - overflow: hidden; - border: 1px solid #ddd; - padding: 0.3em; - margin: 0 0.2em 0.2em 0; -} -@media all and (min-width: 30em) { - .sg-colors li { - float: left; - width: 5em; - } -} - -.sg-swatch { - display: block; - height: 1.5em; - width: 50%; -} -@media all and (max-width: 30em) { - .sg-swatch { - float: left; - margin-right: 0.3em; - } -} -@media all and (min-width: 30em) { - .sg-swatch { - width: 100%; - height: 4em; - margin-bottom: 0.2em; - } -} - -.sg-label { - line-height: 1; -} - -/*# sourceMappingURL=styleguide-specific.css.map */ diff --git a/core/styleguide/css/styleguide.css b/core/styleguide/css/styleguide.css deleted file mode 100644 index c7c2b48ae..000000000 --- a/core/styleguide/css/styleguide.css +++ /dev/null @@ -1,843 +0,0 @@ -/*------------------------------------*\ - $PATTERN LAB STYLES -\*------------------------------------*/ -/** - * NOTE: These styles are specific to Pattern Lab and should not be modified. - * Edit all project styles in /source/css/ - * - * Second note: Any important declarations are to prevent brand styles from overriding style guide - */ -/*------------------------------------*\ - $CONTENTS -\*------------------------------------*/ -/** - * STYLE GUIDE VARIABLES------------------Declarations of Sass variables - * -----Font - * -----Colors - * -----Typography - * -----Defaults - * -----Breakpoints - * MIXINS---------------------------------Sass mixins - * GLOBAL ELEMENTS------------------------Establish global styles - * -----Main - * -----Headings - * -----Text-related elements (p, blockquote, lists) - * -----Defaults - * -----Breakpoints - * STYLE GUIDE INTERFACE------------------CSS for the Pattern Lab Container. - * -----Header - * -----Navigation - * -----Controls - * -----Main Container - * -----Viewport - * -----Section Headers - * -----Code View - * -----Icon Fonts - */ -/*------------------------------------*\ - $PATTERN LAB VARIABLES -\*------------------------------------*/ -/*Fonts*/ -/* Style Guide Interface Colors */ -/* Typography */ -/* Defaults */ -/* Dimensions */ -/* Breakpoints */ -/*------------------------------------*\ - $PATTERN LAB MIXINS -\*------------------------------------*/ -/*------------------------------------*\ - $PATTERN LAB INTERFACE -\*------------------------------------*/ -#patternlab-html, #patternlab-body { - margin: 0; - padding: 0; - background: #ddd; - -webkit-text-size-adjust: 100%; -} - -.sg-nav-wrapper { - overflow: hidden; - background: #ddd; -} - -.is-vishidden { - position: absolute !important; - overflow: hidden; - width: 1px; - height: 1px; - padding: 0; - border: 0; - clip: rect(1px, 1px, 1px, 1px); -} - -.sg-cf, .sg-pattern { - /**zoom: 1;*/ -} -.sg-cf:before, .sg-pattern:before, .sg-cf:after, .sg-pattern:after { - content: " "; - display: table; -} -.sg-cf:after, .sg-pattern:after { - clear: both; -} - -/*------------------------------------*\ - $PATTERN LAB HEADER -\*------------------------------------*/ -/* Header */ -.sg-header { - background: #222; - color: #fff; - font-family: "HelveticaNeue", "Helvetica", "Arial", sans-serif; - text-transform: uppercase; - position: fixed; - top: 0; - left: 0; - z-index: 2; - width: 100%; -} -.sg-header * { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} -.sg-header ul, .sg-header ol { - padding: 0; - margin: 0; -} -.sg-header li { - list-style: none; - border-bottom: 1px solid rgba(255, 255, 255, 0.05); -} -.sg-header a { - font-size: 70%; - color: #808080; - text-decoration: none; - display: block; - line-height: 1; - padding: 1em; - -webkit-transition: background 0.15s ease-out; - -moz-transition: background 0.15s ease-out; - -ms-transition: background 0.15s ease-out; - -o-transition: background 0.15s ease-out; - transition: background 0.15s ease-out; - -webkit-transition: color 0.15s ease-out; - -moz-transition: color 0.15s ease-out; - -ms-transition: color 0.15s ease-out; - -o-transition: color 0.15s ease-out; - transition: color 0.15s ease-out; -} -.sg-header a:hover, .sg-header a:focus, .sg-header a.active { - color: #fff; - background: rgba(255, 255, 255, 0.05); -} -.sg-header ol ol ol a { - padding-left: 2em; - text-transform: none; -} - -/* Navigation */ -.sg-header .sg-nav-toggle { - display: inline-block; - padding: 0.9em 1em; - border-bottom: 1px solid transparent; - position: relative; - text-transform: uppercase; - z-index: 2; -} -.sg-header .sg-nav-toggle span { - display: inline-block; - padding-right: 0.2em; -} -@media all and (min-width: 48em) { - .sg-header .sg-nav-toggle { - display: none; - } -} - -@media all and (max-width: 48em) { - .sg-nav-container { - overflow: hidden; - max-height: 0; - -webkit-transition: max-height 0.1s ease-out; - -moz-transition: max-height 0.1s ease-out; - -ms-transition: max-height 0.1s ease-out; - -o-transition: max-height 0.1s ease-out; - transition: max-height 0.1s ease-out; - } - .sg-nav-container.active { - max-height: 50em; - } -} - -.sg-nav { - z-index: 1; - margin: 0; - padding: 0; - list-style: none; -} -.sg-nav > li { - cursor: pointer; -} -@media all and (min-width: 48em) { - .sg-nav > li { - border-bottom: 0; - border-right: 1px solid rgba(255, 255, 255, 0.05); - float: left; - position: relative; - } - .sg-nav > li > ol { - position: absolute; - top: 2em; - left: 0; - } -} - -/* Accordion */ -.sg-acc-handle:after { - content: ' +'; - float: right; - font-size: 70%; -} -@media all and (min-width: 48em) { - .sg-acc-handle:after { - float: none; - } -} -.sg-acc-handle.active { - color: #fff; - background: rgba(255, 255, 255, 0.05); -} -.sg-acc-handle.active:after { - content: ' -'; -} -.sg-acc-handle.sg-icon:after { - content: ""; -} - -.sg-header .sg-icon { - width: auto; - font-size: 1rem; - padding: 0.5rem 1rem; -} - -.sg-acc-panel { - overflow: hidden; - max-height: 0; - min-width: 10em; - -webkit-transition: max-height 0.1s ease-out; - -moz-transition: max-height 0.1s ease-out; - -ms-transition: max-height 0.1s ease-out; - -o-transition: max-height 0.1s ease-out; - transition: max-height 0.1s ease-out; -} -.sg-acc-panel li { - background: #222; -} -.sg-acc-panel.active { - max-height: 120em; - overflow: auto; -} -.sg-acc-panel.sg-right { - position: absolute; - left: auto; - right: 0; -} -.sg-acc-panel.sg-left { - position: absolute; - left: auto; -} -.sg-acc-panel [class^="sg-icon-"]:before { - display: inline-block; - margin-right: 0.4em; -} - -/* Controls (sizing, view mode) */ -.sg-controls { - border: 0; - position: absolute; - top: 0; - right: 0; - z-index: 2; -} - -.sg-control-trigger { - border-bottom: 1px solid rgba(255, 255, 255, 0.05); -} -@media all and (min-width: 48em) { - .sg-control-trigger { - border: 0; - } -} -@media all and (min-width: 72em) { - .sg-control-trigger { - float: left; - width: 6em; - } -} - -.sg-control > li { - float: left; -} -@media all and (min-width: 48em) { - .sg-control > li { - border-bottom: 0; - border-left: 1px solid rgba(255, 255, 255, 0.05); - } -} -.sg-control .sg-input { - padding: 0.1em; - -webkit-transition: all 0.2s ease-out; - -moz-transition: all 0.2s ease-out; - -ms-transition: all 0.2s ease-out; - -o-transition: all 0.2s ease-out; - transition: all 0.2s ease-out; -} -.sg-control .sg-input:active, .sg-control .sg-input:focus { - outline: 0; - background: #999; - color: #000; -} - -.sg-current-size { - font-size: 70%; - color: #808080; - padding: 0.85em 0.7em; -} -.sg-current-size:hover .sg-input { - background: #999; - color: #000; -} -@media all and (min-width: 72em) { - .sg-current-size { - float: left; - } -} - -.sg-size { - width: 135px; -} -@media all and (min-width: 48em) { - .sg-size { - width: auto; - } -} - -@media all and (min-width: 72em) { - .sg-size-options { - float: left; - position: static; - max-height: none; - max-width: none; - } - .sg-size-options > li { - float: left; - border: 0; - border-left: 1px solid rgba(255, 255, 255, 0.05); - } -} - -#sg-size-mq { - display: none; -} -@media all and (min-width: 72em) { - #sg-size-mq { - display: block; - } -} - -#sg-form { - margin: 0; - border: 0; - padding: 0; -} - -.sg-input { - margin: -2px 0 0 0; - padding: 0; - border: 0; - background-color: #222; - color: gray; - width: 25px; - text-align: right; -} -@media all and (min-width: 48em) { - .sg-input { - width: 35px; - } -} - -.sg-input-active { - background-color: #fff; - color: #000; -} - -.sg-view { - position: relative; -} -.sg-view > ul { - position: absolute; - top: 2em; - left: 0; -} - -.sg-checkbox:before { - display: inline-block; - margin-right: 0.4em; -} - -/* basic styling */ -.sg-pattern-state:before { - margin-right: 4px; - content: "\2022"; - display: inline-block; - margin-bottom: -4px; - font-size: 18px; - vertical-align: bottom; -} - -/* nav styling */ -.sg-nav .sg-pattern-state:before { - margin-top: -4px; - margin-bottom: 0; - margin-left: -4px; - height: 20px; - display: block; - float: left; -} - -.sg-sub-nav .sg-pattern-state:before { - margin-left: -11px; - margin-right: 4px; -} - -/* call out for pattern's pattern state */ -span.sg-pattern-state { - color: #999; -} - -span.sg-pattern-state:before { - margin-bottom: -3px; - margin-left: 4px; -} - -/* pattern states */ -.inprogress:before { - color: #FF4136 !important; -} - -.inreview:before { - color: #FFCC00 !important; -} - -.complete:before { - color: #2ECC40 !important; -} - -/*------------------------------------*\ - $PATTERN LAB VIEWPORT -\*------------------------------------*/ -/* Viewport */ -#sg-vp-wrap { - text-align: center; - width: 100%; - position: fixed; - top: 2em; - bottom: 0; - left: 0; - right: 0; - z-index: 0; -} -#sg-vp-wrap.wrap-animate { - -webkit-transition: left 0.3s ease-out; - -moz-transition: left 0.3s ease-out; - -ms-transition: left 0.3s ease-out; - -o-transition: left 0.3s ease-out; - transition: left 0.3s ease-out; -} - -#sg-viewport { - position: absolute; - height: 100%; - width: 100%; - border: 0; - padding: 0; - margin: 0; - top: 0; - bottom: 0; - left: 0; - right: 0; - background-color: white; -} -#sg-viewport.hay-mode { - -webkit-transition: all 40s linear; - -moz-transition: all 40s linear; - -ms-transition: all 40s linear; - -o-transition: all 40s linear; - transition: all 40s linear; -} - -.no-resize #sg-cover, .no-resize #sg-rightpull-container { - display: none; -} -.no-resize #sg-viewport { - overflow: hidden !important; -} - -#sg-cover { - width: 100%; - height: 100%; - display: none; - position: absolute; - z-index: 20; - cursor: col-resize; -} - -#sg-gen-container { - height: 100%; - position: relative; - text-align: center; - margin: 0 auto; - -webkit-overflow-scrolling: touch; - overflow-y: auto; - overflow-x: hidden; -} -#sg-gen-container.hay-mode { - -webkit-transition: all 40s linear; - -moz-transition: all 40s linear; - -ms-transition: all 40s linear; - -o-transition: all 40s linear; - transition: all 40s linear; -} - -#sg-rightpull-container { - width: 14px; - float: right; - margin: 0; - height: 100%; - cursor: col-resize; -} - -#sg-rightpull { - margin: 0; - width: 100%; - height: 100%; - background: #999; - -webkit-transition: background 0.2s ease-out; - -moz-transition: background 0.2s ease-out; - -ms-transition: background 0.2s ease-out; - -o-transition: background 0.2s ease-out; - transition: background 0.2s ease-out; -} -#sg-rightpull:hover { - background: #666; -} -#sg-rightpull:active { - cursor: col-resize; - background: #444; -} - -.vp-animate { - -webkit-transition: width 0.8s ease-out; - -moz-transition: width 0.8s ease-out; - -ms-transition: width 0.8s ease-out; - -o-transition: width 0.8s ease-out; - transition: width 0.8s ease-out; -} - -/*------------------------------------*\ - $PATTERN LAB CONTENT -\*------------------------------------*/ -/* Section Pattern */ -.sg-pattern { - margin-bottom: 2em; - position: relative; -} - -/* Section Head */ -.sg-pattern-head { - margin: 2em 0; - font-family: "HelveticaNeue", "Helvetica", "Arial", sans-serif; - font-size: 70%; - font-weight: normal; - padding: 1em 0; - border-bottom: 1px solid #808080; -} -.sg-pattern-head a { - display: block; - color: #808080; - text-decoration: none; - cursor: pointer; -} -.sg-pattern-head a:hover { - color: #222; -} - -.sg-view-container { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; - font-family: "HelveticaNeue", "Helvetica", "Arial", sans-serif; - line-height: 1.4; - font-size: 90%; - background: #222; - color: #808080; - position: fixed; - top: auto; - padding: 1em; - bottom: 0; - left: 0; - z-index: 2; - width: 100%; - height: 50%; - overflow-y: auto; - overflow-x: hidden; -} -.sg-view-container a { - color: #999; -} -.sg-view-container pre { - padding: 0 1em; -} -.sg-view-container.anim-ready { - -webkit-transition: bottom 0.3s ease-out; - -moz-transition: bottom 0.3s ease-out; - -webkit-transition: bottom 0.3s ease-out; - -ms-transition: bottom 0.3s ease-out; - -o-transition: bottom 0.3s ease-out; - transition: bottom 0.3s ease-out; -} - -.sg-view-close { - width: 100%; - margin-bottom: -10px; -} - -.sg-view-close-btn { - color: #fff; - text-transform: uppercase; - text-decoration: none; - text-align: right; - display: block; -} - -.has-annotation { - cursor: help !important; - box-shadow: 0 0 10px #808080; -} -.has-annotation a, .has-annotation input { - cursor: help !important; -} -.has-annotation:hover { - box-shadow: 0 0 10px #222; -} -.has-annotation.active { - box-shadow: inset 0 0 20px #808080; -} - -.annotation-tip { - display: block; - position: absolute; - margin-top: -10px !important; - margin-left: -10px !important; - width: 25px !important; - height: 25px !important; - border-radius: 13px !important; - text-align: center !important; - background: #444 !important; - color: #fff !important; - font-weight: bold !important; - font-size: 16px !important; - z-index: 100; -} - -#sg-comments-container { - max-width: 60em; - margin: 0 auto; -} - -.sg-comment-container { - padding-bottom: 2em; - margin-bottom: 1em; - border-bottom: 1px solid rgba(255, 255, 255, 0.25); -} -.sg-comment-container p:last-child { - margin-bottom: 0; -} -.sg-comment-container h2 { - margin-bottom: 0.25em; -} - -.sg-code, .sg-annotations { - clear: both; - background: #ddd; - color: #222; - padding: 1em 0.5em; - margin: 1em 0; -} -.sg-code a, .sg-annotations a { - text-decoration: underline; -} - -.sg-code pre { - white-space: -moz-pre-line; - white-space: -pre-line; - white-space: -o-pre-line; - word-wrap: break-word; - white-space: pre-line; - border: 1px solid rgba(0, 0, 0, 0.1); - padding: 0.5em; -} - -.sg-code-contains { - margin-bottom: 1rem; - font-size: 85%; - color: #808080; -} -.sg-code-contains code { - padding: 0.2em; - background: rgba(0, 0, 0, 0.3); - color: #999; - position: relative; - top: -2px; -} - -.sg-code-head { - color: #808080; - font-size: 1em; -} - -#sg-code-markup { - padding-top: 10px; -} - -#sg-code-tabs { - list-style: none; - margin: 0; - padding: 0; -} - -#sg-code-tabs li { - float: left; - background-color: #333; - font-size: 1.3em; - font-weight: bold; - padding: 5px 15px; - border-top: 2px solid #666; - margin-right: 2px; - cursor: pointer; -} - -.sg-code-title-active { - color: #bbb; - background-color: #272822 !important; -} - -div.clear { - clear: both; -} - -.sg-code-patternname { - color: #aaa; -} - -#sg-code-loader { - display: none; - position: absolute; - left: 45%; - top: 20%; - width: 150px; - padding: 10px; - text-align: center; - border-radius: 10px; - background-color: #000; - z-index: 100; -} - -.spinner { - height: 30px; - width: 30px; - margin-left: auto; - margin-right: auto; - background-position: center center; - background-repeat: no-repeat; - background: url("../images/spinner.gif"); - border-radius: 50%; - opacity: .7; -} - -/* Pattern Lab icon fonts */ -@font-face { - font-family: 'icomoon'; - src: url("../fonts/icomoon.eot?srsv7g"); - src: url("../fonts/icomoon.eot?#iefixsrsv7g") format("embedded-opentype"), url("../fonts/icomoon.woff?srsv7g") format("woff"), url("../fonts/icomoon.ttf?srsv7g") format("truetype"), url("../fonts/icomoon.svg?srsv7g#icomoon") format("svg"); - font-weight: normal; - font-style: normal; -} -.sg-icon-search, .sg-icon-cog, .sg-icon-minus, .sg-icon-plus, .sg-icon-menu, .sg-icon-radio-checked, .sg-checkbox.active, .sg-icon-radio-unchecked, .sg-checkbox, .sg-icon-file, .sg-icon-link, .sg-icon-keyboard, .sg-icon-qrcode, .sg-icon-eye, .sg-checkbox { - font-family: 'icomoon'; - speak: none; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - line-height: 1; - /* Better Font Rendering =========== */ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.sg-icon-search:before { - content: "\e600"; - font-size: 85%; -} - -.sg-icon-cog:before { - content: "\e601"; -} - -.sg-icon-minus:before { - content: "\e602"; -} - -.sg-icon-plus:before { - content: "\e603"; -} - -.sg-icon-menu:before { - content: "\e604"; -} - -.sg-icon-radio-checked:before, .sg-checkbox.active:before, .sg-checkbox.active:before { - content: "\e605"; -} - -.sg-icon-radio-unchecked:before, .sg-checkbox:before, .sg-checkbox:before { - content: "\e606"; -} - -.sg-icon-file:before { - content: "\e607"; -} - -.sg-icon-link:before { - content: "\e608"; -} - -.sg-icon-keyboard:before { - content: "\e609"; -} - -.sg-icon-qrcode:before { - content: "\e60a"; -} - -.sg-icon-eye:before { - content: "\e60b"; -} - -/******************************************************************/ -/* End Pattern Lab Interface code */ - -/*# sourceMappingURL=styleguide.css.map */ diff --git a/core/styleguide/css/vendor/prism.css b/core/styleguide/css/vendor/prism.css deleted file mode 100644 index 0b78bd0c4..000000000 --- a/core/styleguide/css/vendor/prism.css +++ /dev/null @@ -1,112 +0,0 @@ -/** - * okaidia theme for JavaScript, CSS and HTML - * Loosely based on Monokai textmate theme by http://www.monokai.nl/ - * @author ocodia - */ - -code[class*="language-"], -pre[class*="language-"] { - color: #f8f8f2; - text-shadow: 0 1px rgba(0,0,0,0.3); - font-family: Consolas, Monaco, 'Andale Mono', monospace; - direction: ltr; - text-align: left; - white-space: pre; - word-spacing: normal; - - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; - - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; - hyphens: none; -} - -/* Code blocks */ -pre[class*="language-"] { - padding: 1em; - margin: .5em 0; - overflow: auto; - border-radius: 0.3em; -} - -:not(pre) > code[class*="language-"], -pre[class*="language-"] { - background: #272822; -} - -/* Inline code */ -:not(pre) > code[class*="language-"] { - padding: .1em; - border-radius: .3em; -} - -.token.comment, -.token.prolog, -.token.doctype, -.token.cdata { - color: slategray; -} - -.token.punctuation { - color: #f8f8f2; -} - -.namespace { - opacity: .7; -} - -.token.property, -.token.tag, -.token.constant, -.token.symbol { - color: #f92672; -} - -.token.boolean, -.token.number{ - color: #ae81ff; -} - -.token.selector, -.token.attr-name, -.token.string, -.token.builtin { - color: #a6e22e; -} - - -.token.operator, -.token.entity, -.token.url, -.language-css .token.string, -.style .token.string, -.token.variable { - color: #f8f8f2; -} - -.token.atrule, -.token.attr-value -{ - color: #e6db74; -} - - -.token.keyword{ -color: #66d9ef; -} - -.token.regex, -.token.important { - color: #fd971f; -} - -.token.important { - font-weight: bold; -} - -.token.entity { - cursor: help; -} diff --git a/core/styleguide/css/vendor/typeahead.css b/core/styleguide/css/vendor/typeahead.css deleted file mode 100644 index a4f940169..000000000 --- a/core/styleguide/css/vendor/typeahead.css +++ /dev/null @@ -1,66 +0,0 @@ -#sg-find { - color: #000; - text-transform: lowercase; -} - -.show-overflow { - overflow: visible; -} - -.typeahead, -.tt-query, -.tt-hint { - width: 220px; - height: 30px; - padding: 8px 12px; - font-size: 14px; - line-height: 16px; - border: 2px solid #ccc; - outline: none; -} - -.typeahead { - background-color: #fff; -} - -.typeahead:focus { - border: 2px solid #999; -} - -.tt-query { - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} - -.tt-hint { - color: #999 -} - -.tt-dropdown-menu { - width: 422px; - padding: 8px 0; - background-color: #fff; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - text-align: left; - -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2); - -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2); - box-shadow: 0 5px 10px rgba(0,0,0,.2); -} - -.tt-suggestion { - padding: 3px 13px; - font-size: 14px; - line-height: 16px; -} - -.tt-suggestion.tt-cursor { - color: #fff; - background-color: #0097cf; - -} - -.tt-suggestion p { - margin: 0; -} \ No newline at end of file diff --git a/core/styleguide/fonts/icomoon.eot b/core/styleguide/fonts/icomoon.eot deleted file mode 100644 index a44826918..000000000 Binary files a/core/styleguide/fonts/icomoon.eot and /dev/null differ diff --git a/core/styleguide/fonts/icomoon.svg b/core/styleguide/fonts/icomoon.svg deleted file mode 100644 index d69b0abd4..000000000 --- a/core/styleguide/fonts/icomoon.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - -Generated by IcoMoon - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/core/styleguide/fonts/icomoon.ttf b/core/styleguide/fonts/icomoon.ttf deleted file mode 100644 index b4fc4ac20..000000000 Binary files a/core/styleguide/fonts/icomoon.ttf and /dev/null differ diff --git a/core/styleguide/fonts/icomoon.woff b/core/styleguide/fonts/icomoon.woff deleted file mode 100644 index ca0c4cffb..000000000 Binary files a/core/styleguide/fonts/icomoon.woff and /dev/null differ diff --git a/core/styleguide/html/README b/core/styleguide/html/README deleted file mode 100644 index 5b0c53819..000000000 --- a/core/styleguide/html/README +++ /dev/null @@ -1 +0,0 @@ -will hold the auto-generated styleguide.html \ No newline at end of file diff --git a/core/styleguide/images/spinner.gif b/core/styleguide/images/spinner.gif deleted file mode 100644 index a0aa8c8df..000000000 Binary files a/core/styleguide/images/spinner.gif and /dev/null differ diff --git a/core/styleguide/js/annotations-pattern.js b/core/styleguide/js/annotations-pattern.js deleted file mode 100644 index 3a30b25a7..000000000 --- a/core/styleguide/js/annotations-pattern.js +++ /dev/null @@ -1,308 +0,0 @@ -/*! - * Annotations Support for Patterns - v0.3 - * - * Copyright (c) 2013-2014 Dave Olsen, http://dmolsen.com - * Licensed under the MIT license - * - */ - -var annotationsPattern = { - - commentsOverlayActive: false, - commentsOverlay: false, - commentsEmbeddedActive: false, - commentsEmbedded: false, - commentsGathered: { "commentOverlay": "on", "comments": { } }, - trackedElements: [ ], - targetOrigin: (window.location.protocol == "file:") ? "*" : window.location.protocol+"//"+window.location.host, - - /** - * record which annotations are related to this pattern so they can be sent to the viewer when called - */ - gatherComments: function() { - - // make sure this only added when we're on a pattern specific view - if (document.getElementById("sg-patterns") === null) { - - var count = 0; - - for (comment in comments.comments) { - var item = comments.comments[comment]; - var els = document.querySelectorAll(item.el); - if (els.length > 0) { - - count++; - item.displaynumber = count; - - for (var i = 0; i < els.length; ++i) { - els[i].onclick = (function(item) { - return function(e) { - - if (annotationsPattern.commentsOverlayActive) { - - e.preventDefault(); - e.stopPropagation(); - - // if an element was clicked on while the overlay was already on swap it - var obj = JSON.stringify({ "displaynumber": item.displaynumber, "el": item.el, "title": item.title, "comment": item.comment }); - parent.postMessage(obj,annotationsPattern.targetOrigin); - - } - - } - })(item); - } - } - - - } - - } else { - - var obj = JSON.stringify({ "commentOverlay": "off" }); - parent.postMessage(obj,annotationsPattern.targetOrigin); - - } - - }, - - /** - * embed a comment by building the sg-annotations div (if necessary) and building an sg-annotation div - * @param {Object} element to check the parent node of - * @param {String} the title of the comment - * @param {String} the comment HTML - */ - embedComments: function (el,title,comment) { - - // build the annotation div and add the content to it - var annotationDiv = document.createElement("div"); - annotationDiv.classList.add("sg-annotation"); - - var h3 = document.createElement("h3"); - var p = document.createElement("p"); - h3.innerHTML = title; - p.innerHTML = comment; - - annotationDiv.appendChild(h3); - annotationDiv.appendChild(p); - - // find the parent element to attach things to - var parentEl = annotationsPattern.findParent(el); - - // see if a child with the class annotations exists - var els = parentEl.getElementsByClassName("sg-annotations"); - if (els.length > 0) { - els[0].appendChild(annotationDiv); - } else { - var annotationsDiv = document.createElement("div"); - annotationsDiv.classList.add("sg-annotations"); - annotationsDiv.appendChild(annotationDiv); - parentEl.appendChild(annotationsDiv); - } - - }, - - /** - * recursively find the parent of an element to see if it contains the sg-pattern class - * @param {Object} element to check the parent node of - */ - findParent: function(el) { - - var parentEl; - - if (el.classList.contains("sg-pattern")) { - return el; - } else if (el.parentNode.classList.contains("sg-pattern")) { - return el.parentNode; - } else { - parentEl = annotationsPattern.findParent(el.parentNode); - } - - return parentEl; - - }, - - /** - * toggle the annotation feature on/off - * based on the great MDN docs at https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage - * @param {Object} event info - */ - receiveIframeMessage: function(event) { - - var data = (typeof event.data !== "string") ? event.data : JSON.parse(event.data); - - // does the origin sending the message match the current host? if not dev/null the request - if ((window.location.protocol != "file:") && (event.origin !== window.location.protocol+"//"+window.location.host)) { - return; - } - - if ((data.resize !== undefined) && (annotationsPattern.commentsOverlayActive)) { - - for (var i = 0; i < annotationsPattern.trackedElements.length; ++i) { - var el = annotationsPattern.trackedElements[i]; - if (window.getComputedStyle(el.element,null).getPropertyValue("max-height") == "0px") { - el.element.firstChild.style.display = "none"; - var obj = JSON.stringify({"annotationState": false, "displayNumber": el.displayNumber }); - parent.postMessage(obj,annotationsPattern.targetOrigin); - } else { - el.element.firstChild.style.display = "block"; - var obj = JSON.stringify({"annotationState": true, "displayNumber": el.displayNumber }); - parent.postMessage(obj,annotationsPattern.targetOrigin); - } - } - - } else if (data.commentToggle !== undefined) { - - var i, els, item, displayNum; - - // if this is an overlay make sure it's active for the onclick event - annotationsPattern.commentsOverlayActive = false; - annotationsPattern.commentsEmbeddedActive = false; - - // see which flag to toggle based on if this is a styleguide or view-all page - if ((data.commentToggle === "on") && (document.getElementById("sg-patterns") !== null)) { - annotationsPattern.commentsEmbeddedActive = true; - } else if (data.commentToggle === "on") { - annotationsPattern.commentsOverlayActive = true; - } - - // if comments overlay is turned off make sure to remove the has-annotation class and pointer - if (!annotationsPattern.commentsOverlayActive) { - els = document.querySelectorAll(".has-annotation"); - for (i = 0; i < els.length; i++) { - els[i].classList.remove("has-annotation"); - } - els = document.querySelectorAll(".annotation-tip"); - for (i = 0; i < els.length; i++) { - els[i].style.display = "none"; - } - } - - // if comments embedding is turned off make sure to hide the annotations div - if (!annotationsPattern.commentsEmbeddedActive) { - els = document.getElementsByClassName("sg-annotations"); - for (i = 0; i < els.length; i++) { - els[i].style.display = "none"; - } - } - - // if comments overlay is turned on add the has-annotation class and pointer - if (annotationsPattern.commentsOverlayActive) { - - var count = 0; - - for (i = 0; i < comments.comments.length; i++) { - item = comments.comments[i]; - els = document.querySelectorAll(item.el); - - var state = true; - - if (els.length) { - - count++; - - //Loop through all items with annotations - for (k = 0; k < els.length; k++) { - - els[k].classList.add("has-annotation"); - - var span = document.createElement("span"); - span.innerHTML = count; - span.classList.add("annotation-tip"); - - if (window.getComputedStyle(els[k],null).getPropertyValue("max-height") == "0px") { - span.style.display = "none"; - state = false; - } - - annotationsPattern.trackedElements.push({ "itemel": item.el, "element": els[k], "displayNumber": count, "state": state }); - - els[k].insertBefore(span,els[k].firstChild); - - } - - } - - } - - // count elements so it can be used when displaying the results in the viewer - var count = 0; - - // iterate over the comments in annotations.js - for(i = 0; i < comments.comments.length; i++) { - - var state = true; - - var item = comments.comments[i]; - var els = document.querySelectorAll(item.el); - - // if an element is found in the given pattern add it to the overall object so it can be passed when the overlay is turned on - if (els.length > 0) { - count++; - for (k = 0; k < els.length; k++) { - if (window.getComputedStyle(els[k],null).getPropertyValue("max-height") == "0px") { - state = false; - } - } - annotationsPattern.commentsGathered.comments[count] = { "el": item.el, "title": item.title, "comment": item.comment, "number": count, "state": state }; - } - - } - - // send the list of annotations for the page back to the parent - var obj = JSON.stringify(annotationsPattern.commentsGathered); - parent.postMessage(obj,annotationsPattern.targetOrigin); - - } else if (annotationsPattern.commentsEmbeddedActive && !annotationsPattern.commentsEmbedded) { - - // if comment embedding is turned on and comments haven't been embedded yet do it - for (i = 0; i < comments.comments.length; i++) { - item = comments.comments[i]; - els = document.querySelectorAll(item.el); - if (els.length > 0) { - annotationsPattern.embedComments(els[0],item.title,item.comment); //Embed the comment - } - annotationsPattern.commentsEmbedded = true; - } - - } else if (annotationsPattern.commentsEmbeddedActive && annotationsPattern.commentsEmbedded) { - - // if comment embedding is turned on and comments have been embedded simply display them - els = document.getElementsByClassName("sg-annotations"); - for (i = 0; i < els.length; ++i) { - els[i].style.display = "block"; - } - - } - - } - - } - -}; - -// add the onclick handlers to the elements that have an annotations -annotationsPattern.gatherComments(); -window.addEventListener("message", annotationsPattern.receiveIframeMessage, false); - -// before unloading the iframe make sure any active overlay is turned off/closed -window.onbeforeunload = function() { - var obj = JSON.stringify({ "commentOverlay": "off" }); - parent.postMessage(obj,annotationsPattern.targetOrigin); -}; - -// tell the parent iframe that keys were pressed - -// toggle the annotations panel -jwerty.key('ctrl+shift+a', function (e) { - var obj = JSON.stringify({ "keyPress": "ctrl+shift+a" }); - parent.postMessage(obj,codePattern.targetOrigin); - return false; -}); - -// close the annotations panel if using escape -jwerty.key('esc', function (e) { - var obj = JSON.stringify({ "keyPress": "esc" }); - parent.postMessage(obj,codePattern.targetOrigin); - return false; -}); \ No newline at end of file diff --git a/core/styleguide/js/annotations-viewer.js b/core/styleguide/js/annotations-viewer.js deleted file mode 100644 index 79bfd2093..000000000 --- a/core/styleguide/js/annotations-viewer.js +++ /dev/null @@ -1,289 +0,0 @@ -/*! - * Annotations Support for the Viewer - v0.3 - * - * Copyright (c) 2013 Brad Frost, http://bradfrostweb.com & Dave Olsen, http://dmolsen.com - * Licensed under the MIT license - * - */ - -var annotationsViewer = { - - // set-up default sections - commentsActive: false, - commentsViewAllActive: false, - targetOrigin: (window.location.protocol === "file:") ? "*" : window.location.protocol+"//"+window.location.host, - moveToOnInit: 0, - - /** - * add the onclick handler to the annotations link in the main nav - */ - onReady: function() { - - // not sure this is used anymore... - $('body').addClass('comments-ready'); - - $(window).resize(function() { - if(!annotationsViewer.commentsActive) { - annotationsViewer.slideComment($('#sg-annotation-container').outerHeight()); - } - }); - - $('#sg-t-annotations').click(function(e) { - - e.preventDefault(); - - // remove the class from the "eye" nav item - $('#sg-t-toggle').removeClass('active'); - - // turn the annotations section on and off - annotationsViewer.toggleComments(); - - }); - - // initialize the annotations viewer - annotationsViewer.commentContainerInit(); - - // load the query strings in case code view has to show by default - var queryStringVars = urlHandler.getRequestVars(); - if ((queryStringVars.view !== undefined) && ((queryStringVars.view === "annotations") || (queryStringVars.view === "a"))) { - annotationsViewer.openComments(); - if (queryStringVars.number !== undefined) { - annotationsViewer.moveToOnInit = queryStringVars.number; - } - } - - }, - - /** - * decide on if the annotations panel should be open or closed - */ - toggleComments: function() { - - if (!annotationsViewer.commentsActive) { - annotationsViewer.openComments(); - } else { - annotationsViewer.closeComments(); - } - - }, - - /** - * open the annotations panel - */ - openComments: function() { - - // make sure the code view overlay is off before showing the annotations view - $('#sg-t-code').removeClass('active'); - codeViewer.codeActive = false; - var obj = JSON.stringify({ "codeToggle": "off" }); - document.getElementById('sg-viewport').contentWindow.postMessage(obj,annotationsViewer.targetOrigin); - codeViewer.slideCode(999); - - // tell the iframe annotation view has been turned on - var obj = JSON.stringify({ "commentToggle": "on" }); - document.getElementById('sg-viewport').contentWindow.postMessage(obj,annotationsViewer.targetOrigin); - - // note that it's turned on in the viewer - annotationsViewer.commentsActive = true; - $('#sg-t-annotations').addClass('active'); - }, - - /** - * close the annotations panel - */ - closeComments: function() { - annotationsViewer.commentsActive = false; - var obj = JSON.stringify({ "commentToggle": "off" }); - document.getElementById('sg-viewport').contentWindow.postMessage(obj,annotationsViewer.targetOrigin); - annotationsViewer.slideComment($('#sg-annotation-container').outerHeight()); - $('#sg-t-annotations').removeClass('active'); - }, - - /** - * add the basic mark-up and events for the annotations container - */ - commentContainerInit: function() { - - // the bulk of this template is in core/templates/index.mustache - if (document.getElementById("sg-annotation-container") === null) { - $('
').html($("#annotations-template").html()).appendTo('body').css('bottom',-$(document).outerHeight()); - setTimeout(function(){ $('#sg-annotation-container').addClass('anim-ready'); },50); //Add animation class once container is positioned out of frame - } - - // make sure the close button handles the click - $('body').delegate('#sg-annotation-close-btn','click',function() { - annotationsViewer.commentsActive = false; - $('#sg-t-annotations').removeClass('active'); - annotationsViewer.slideComment($('#sg-annotation-container').outerHeight()); - var obj = JSON.stringify({ "commentToggle": "off" }); - document.getElementById('sg-viewport').contentWindow.postMessage(obj,annotationsViewer.targetOrigin); - return false; - }); - - }, - - /** - * slides the panel - */ - slideComment: function(pos) { - $('#sg-annotation-container').css('bottom',-pos); - }, - - /** - * moves to a particular item in the viewer - */ - moveTo: function(number) { - if (document.getElementById("annotation-"+number) !== undefined) { - var top = document.getElementById("annotation-"+number).offsetTop; - $('#sg-annotation-container').animate({scrollTop: top - 10}, 600); - } - }, - - /** - * when turning on or switching between patterns with annotations view on make sure we get - * the annotations from from the pattern via post message - */ - updateComments: function(comments) { - - var commentsContainer = document.getElementById("sg-comments-container"); - - // clear out the comments container - if (commentsContainer.innerHTML !== "") { - commentsContainer.innerHTML = ""; - } - - // see how many comments this pattern might have. if more than zero write them out. if not alert the user to the fact their aren't any - var count = Object.keys(comments).length; - if (count > 0) { - - for (i = 1; i <= count; i++) { - - var displayNum = comments[i].number; - - var span = document.createElement("span"); - span.id = "annotation-state-" + displayNum; - span.style.fontSize = "0.8em"; - span.style.color = "#666"; - if (comments[i].state === false) { - span.innerHTML = " hidden"; - } - - var h2 = document.createElement("h2"); - h2.innerHTML = displayNum + ". " + comments[i].title; - h2.appendChild(span); - - var div = document.createElement("div"); - div.innerHTML = comments[i].comment; - - var commentDiv = document.createElement("div"); - commentDiv.classList.add("sg-comment-container"); - commentDiv.id = "annotation-" + displayNum; - commentDiv.appendChild(h2); - commentDiv.appendChild(div); - - commentsContainer.appendChild(commentDiv); - - } - - } else { - - var h2 = document.createElement("h2"); - h2.innerHTML = "No Annotations"; - - var div = document.createElement("div"); - div.innerHTML = "There are no annotations for this pattern."; - - var commentDiv = document.createElement("div"); - commentDiv.classList.add("sg-comment-container"); - commentDiv.appendChild(h2); - commentDiv.appendChild(div); - - commentsContainer.appendChild(commentDiv); - - } - - // slide the comment section into view - annotationsViewer.slideComment(0); - - if (annotationsViewer.moveToOnInit != "0") { - annotationsViewer.moveTo(annotationsViewer.moveToOnInit); - annotationsViewer.moveToOnInit = "0"; - } - - }, - - /** - * toggle the comment pop-up based on a user clicking on the pattern - * based on the great MDN docs at https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage - * @param {Object} event info - */ - receiveIframeMessage: function(event) { - - var data = (typeof event.data !== "string") ? event.data : JSON.parse(event.data); - - // does the origin sending the message match the current host? if not dev/null the request - if ((window.location.protocol !== "file:") && (event.origin !== window.location.protocol+"//"+window.location.host)) { - return; - } - - if (data.commentOverlay !== undefined) { - if (data.commentOverlay === "on") { - annotationsViewer.updateComments(data.comments); - } else { - annotationsViewer.slideComment($('#sg-annotation-container').outerHeight()); - } - } else if (data.annotationState !== undefined) { - document.getElementById("annotation-state-"+data.displayNumber).innerHTML = (data.annotationState == true) ? "" : " hidden"; - } else if (data.displaynumber !== undefined) { - annotationsViewer.moveTo(data.displaynumber); - } else if (data.keyPress !== undefined) { - if (data.keyPress == 'ctrl+shift+a') { - annotationsViewer.toggleComments(); - return false; - } else if (data.keyPress == 'esc') { - if (annotationsViewer.commentsActive) { - annotationsViewer.closeComments(); - return false; - } - } - } else if (data.patternpartial !== undefined) { - if (annotationsViewer.commentsViewAllActive && (data.patternpartial.indexOf("viewall-") != -1)) { - var obj = JSON.stringify({ "commentToggle": "on" }); - document.getElementById('sg-viewport').contentWindow.postMessage(obj,annotationsViewer.targetOrigin); - } - } - - } - -}; - -$(document).ready(function() { annotationsViewer.onReady(); }); -window.addEventListener("message", annotationsViewer.receiveIframeMessage, false); - -// make sure if a new pattern or view-all is loaded that comments are turned on as appropriate -$('#sg-viewport').load(function() { - if (annotationsViewer.commentsActive) { - var obj = JSON.stringify({ "commentToggle": "on" }); - document.getElementById('sg-viewport').contentWindow.postMessage(obj,annotationsViewer.targetOrigin); - } -}); - -// no idea why this has to be outside. there's something funky going on with the JS pattern -$('#sg-view li a').click(function() { - $(this).parent().parent().removeClass('active'); - $(this).parent().parent().parent().parent().removeClass('active'); -}); - -// toggle the annotations panel -jwerty.key('ctrl+shift+a', function (e) { - annotationsViewer.toggleComments(); - return false; -}); - -// close the annotations panel if using escape -jwerty.key('esc', function (e) { - if (annotationsViewer.commentsActive) { - annotationsViewer.closeComments(); - return false; - } -}); \ No newline at end of file diff --git a/core/styleguide/js/code-pattern.js b/core/styleguide/js/code-pattern.js deleted file mode 100644 index f8a949519..000000000 --- a/core/styleguide/js/code-pattern.js +++ /dev/null @@ -1,118 +0,0 @@ -/*! - * Code View Support for Patterns - v0.3 - * - * Copyright (c) 2013-2014 Dave Olsen, http://dmolsen.com - * Licensed under the MIT license - * - */ - -var codePattern = { - - codeOverlayActive: false, - codeEmbeddedActive: false, - targetOrigin: (window.location.protocol === "file:") ? "*" : window.location.protocol+"//"+window.location.host, - - /** - * toggle the annotation feature on/off - * based on the great MDN docs at https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage - * @param {Object} event info - */ - receiveIframeMessage: function(event) { - - var data = (typeof event.data !== "string") ? event.data : JSON.parse(event.data); - - // does the origin sending the message match the current host? if not dev/null the request - if ((window.location.protocol != "file:") && (event.origin !== window.location.protocol+"//"+window.location.host)) { - return; - } - - if (data.codeToggle !== undefined) { - - var els, i; - - // if this is an overlay make sure it's active for the onclick event - codePattern.codeOverlayActive = false; - codePattern.codeEmbeddedActive = false; - - // see which flag to toggle based on if this is a styleguide or view-all page - if ((data.codeToggle == "on") && (document.getElementById("sg-patterns") !== null)) { - codePattern.codeEmbeddedActive = true; - } else if (data.codeToggle == "on") { - codePattern.codeOverlayActive = true; - } - - // if comments embedding is turned off make sure to hide the annotations div - if (!codePattern.codeEmbeddedActive && (document.getElementById("sg-patterns") !== null)) { - els = document.getElementsByClassName("sg-code"); - for (i = 0; i < els.length; i++) { - els[i].style.display = "none"; - } - } - - // if comments overlay is turned on add the has-comment class and pointer - if (codePattern.codeOverlayActive) { - - var obj = JSON.stringify({ "codeOverlay": "on", "lineage": lineage, "lineageR": lineageR, "patternPartial": patternPartial, "patternState": patternState, "cssEnabled": cssEnabled }); - parent.postMessage(obj,codePattern.targetOrigin); - - } else if (codePattern.codeEmbeddedActive) { - - // if code embedding is turned on simply display them - els = document.getElementsByClassName("sg-code"); - for (i = 0; i < els.length; ++i) { - els[i].style.display = "block"; - } - - } - - } - - } - -}; - -// add the onclick handlers to the elements that have an annotations -window.addEventListener("message", codePattern.receiveIframeMessage, false); - -// before unloading the iframe make sure any active overlay is turned off/closed -window.onbeforeunload = function() { - var obj = JSON.stringify({ "codeOverlay": "off" }); - parent.postMessage(obj,codePattern.targetOrigin); -}; - -// tell the parent iframe that keys were pressed - -// toggle the code panel -jwerty.key('ctrl+shift+c', function (e) { - var obj = JSON.stringify({ "keyPress": "ctrl+shift+c" }); - parent.postMessage(obj,codePattern.targetOrigin); - return false; -}); - -// when the code panel is open hijack cmd+a so that it only selects the code view -jwerty.key('cmd+a/ctrl+a', function (e) { - var obj = JSON.stringify({ "keyPress": "cmd+a" }); - parent.postMessage(obj,codePattern.targetOrigin); - return false; -}); - -// open the mustache panel -jwerty.key('ctrl+shift+u', function (e) { - var obj = JSON.stringify({ "keyPress": "ctrl+shift+u" }); - parent.postMessage(obj,codePattern.targetOrigin); - return false; -}); - -// open the html panel -jwerty.key('ctrl+shift+h', function (e) { - var obj = JSON.stringify({ "keyPress": "ctrl+shift+h" }); - parent.postMessage(obj,codePattern.targetOrigin); - return false; -}); - -// close the code panel if using escape -jwerty.key('esc', function (e) { - var obj = JSON.stringify({ "keyPress": "esc" }); - parent.postMessage(obj,codePattern.targetOrigin); - return false; -}); \ No newline at end of file diff --git a/core/styleguide/js/code-viewer.js b/core/styleguide/js/code-viewer.js deleted file mode 100644 index ede15941f..000000000 --- a/core/styleguide/js/code-viewer.js +++ /dev/null @@ -1,441 +0,0 @@ -/*! - * Code View Support for the Viewer - v0.1 - * - * Copyright (c) 2013 Brad Frost, http://bradfrostweb.com & Dave Olsen, http://dmolsen.com - * Licensed under the MIT license - * - */ - -var codeViewer = { - - // set up some defaults - codeActive: false, - tabActive: "e", - encoded: "", - mustache: "", - css: "", - ids: { "e": "#sg-code-title-html", "m": "#sg-code-title-mustache", "c": "#sg-code-title-css" }, - targetOrigin: (window.location.protocol === "file:") ? "*" : window.location.protocol+"//"+window.location.host, - copyOnInit: false, - - /** - * add the onclick handler to the code link in the main nav - */ - onReady: function() { - - // not sure this is needed anymore... - $('body').addClass('code-ready'); - - $(window).resize(function() { - if(!codeViewer.codeActive) { - codeViewer.slideCode($('#sg-code-container').outerHeight()); - } - }); - - // add the onclick handler - $('#sg-t-code').click(function(e) { - - e.preventDefault(); - - // remove the class from the "eye" nav item - $('#sg-t-toggle').removeClass('active'); - - // if the code link in the main nav is active close the panel. otherwise open - if ($(this).hasClass('active')) { - codeViewer.closeCode(); - } else { - codeViewer.openCode(); - } - - }); - - // initialize the code viewer - codeViewer.codeContainerInit(); - - // load the query strings in case code view has to show by default - var queryStringVars = urlHandler.getRequestVars(); - if ((queryStringVars.view !== undefined) && ((queryStringVars.view === "code") || (queryStringVars.view === "c"))) { - codeViewer.copyOnInit = ((queryStringVars.copy !== undefined) && (queryStringVars.copy === "true")) ? true : false; - codeViewer.openCode(); - } - - }, - - /** - * decide on if the code panel should be open or closed - */ - toggleCode: function() { - - if (!codeViewer.codeActive) { - codeViewer.openCode(); - } else { - codeViewer.closeCode(); - } - - }, - - /** - * after clicking the code view link open the panel - */ - openCode: function() { - - // make sure the annotations overlay is off before showing code view - $('#sg-t-annotations').removeClass('active'); - annotationsViewer.commentsActive = false; - var obj = JSON.stringify({ "commentToggle": "off" }); - document.getElementById('sg-viewport').contentWindow.postMessage(obj,codeViewer.targetOrigin); - annotationsViewer.slideComment(999); - - // tell the iframe code view has been turned on - var obj = JSON.stringify({ "codeToggle": "on" }); - document.getElementById('sg-viewport').contentWindow.postMessage(obj,codeViewer.targetOrigin); - - // note it's turned on in the viewer - codeViewer.codeActive = true; - $('#sg-t-code').addClass('active'); - - }, - - /** - * after clicking the code view link close the panel - */ - closeCode: function() { - var obj = JSON.stringify({ "codeToggle": "off" }); - document.getElementById('sg-viewport').contentWindow.postMessage(obj,codeViewer.targetOrigin); - codeViewer.codeActive = false; - codeViewer.slideCode($('#sg-code-container').outerHeight()); - $('#sg-t-code').removeClass('active'); - }, - - /** - * add the basic mark-up and events for the code container - */ - codeContainerInit: function() { - - // the bulk of this template is in core/templates/index.mustache - if (document.getElementById("sg-code-container") === null) { - $('
').html($("#code-template").html()).appendTo('body').css('bottom',-$(document).outerHeight()); - setTimeout(function(){ $('#sg-code-container').addClass('anim-ready'); },50); //Add animation class once container is positioned out of frame - } - - // make sure the close button handles the click - $('body').delegate('#sg-code-close-btn','click',function() { - codeViewer.closeCode(); - return false; - }); - - // make sure the click events are handled on the HTML tab - $(codeViewer.ids["e"]).click(function() { - codeViewer.swapCode("e"); - }); - - // make sure the click events are handled on the Mustache tab - $(codeViewer.ids["m"]).click(function() { - codeViewer.swapCode("m"); - }); - - // make sure the click events are handled on the CSS tab - $(codeViewer.ids["c"]).click(function() { - codeViewer.swapCode("c"); - }); - - }, - - /** - * depending on what tab is clicked this swaps out the code container. makes sure prism highlight is added. - */ - swapCode: function(type) { - - codeViewer.clearSelection(); - var fill = ""; - var className = (type == "c") ? "css" : "markup"; - $("#sg-code-fill").removeClass().addClass("language-"+className); - if (type == "m") { - fill = codeViewer.mustache; - } else if (type == "e") { - fill = codeViewer.encoded; - } else if (type == "c") { - fill = codeViewer.css; - } - $("#sg-code-fill").html(fill).text(); - codeViewer.tabActive = type; - Prism.highlightElement(document.getElementById("sg-code-fill")); - $('.sg-code-title-active').removeClass('sg-code-title-active'); - $(codeViewer.ids[type]).toggleClass("sg-code-title-active"); - }, - - /** - * select the code where using cmd+a/ctrl+a - */ - selectCode: function() { - if (codeViewer.codeActive) { - selection = window.getSelection(); - range = document.createRange(); - range.selectNodeContents(document.getElementById("sg-code-fill")); - selection.removeAllRanges(); - selection.addRange(range); - } - }, - - /** - * clear any selection of code when swapping tabs or opening a new pattern - */ - clearSelection: function() { - if (codeViewer.codeActive) { - if (window.getSelection().empty) { - window.getSelection().empty(); - } else if (window.getSelection().removeAllRanges) { - window.getSelection().removeAllRanges(); - } - } - }, - - /** - * slides the panel - */ - slideCode: function(pos) { - $('#sg-code-container').css('bottom',-pos); - }, - - /** - * once the AJAX request for the encoded mark-up is finished this runs. - * if the encoded tab is the current active tab it adds the content to the default code container - */ - saveEncoded: function() { - codeViewer.encoded = this.responseText; - if (codeViewer.tabActive == "e") { - codeViewer.activateDefaultTab("e",this.responseText); - } - }, - - /** - * once the AJAX request for the mustache mark-up is finished this runs. - * if the mustache tab is the current active tab it adds the content to the default code container - */ - saveMustache: function() { - codeViewer.mustache = this.responseText; - if (codeViewer.tabActive == "m") { - codeViewer.activateDefaultTab("m",this.responseText); - } - }, - - /** - * once the AJAX request for the css mark-up is finished this runs. if this function is running then css has been enabled - * if the css tab is the current active tab it adds the content to the default code container - */ - saveCSS: function() { - $('#sg-code-title-css').css("display","block"); - codeViewer.css = this.responseText; - if (codeViewer.tabActive == "c") { - codeViewer.activateDefaultTab("c",this.responseText); - } - }, - - /** - * when loading the code view make sure the active tab is highlighted and filled in appropriately - */ - activateDefaultTab: function(type,code) { - var typeName = ""; - var className = (type == "c") ? "css" : "markup"; - if (type == "m") { - typeName = "mustache"; - } else if (type == "e") { - typeName = "html"; - } else if (type == "c") { - typeName = "css"; - } - $('.sg-code-title-active').removeClass('sg-code-title-active'); - $('#sg-code-title-'+typeName).addClass('sg-code-title-active'); - $("#sg-code-fill").removeClass().addClass("language-"+className); - $("#sg-code-fill").html(code).text(); - Prism.highlightElement(document.getElementById("sg-code-fill")); - if (codeViewer.copyOnInit) { - codeViewer.selectCode(); - codeViewer.copyOnInit = false; - } - }, - - /** - * when turning on or switching between patterns with code view on make sure we get - * the code from from the pattern via post message - */ - updateCode: function(lineage,lineageR,patternPartial,patternState,cssEnabled) { - - // clear any selections that might have been made - codeViewer.clearSelection(); - - // draw lineage - if (lineage.length !== 0) { - var lineageList = ""; - $("#sg-code-lineage").css("display","block"); - for (var i = 0; i < lineage.length; i++) { - lineageList += (i === 0) ? "" : ", "; - var cssClass = (lineage[i].lineageState != undefined) ? "sg-pattern-state "+lineage[i].lineageState : ""; - lineageList += ""+lineage[i].lineagePattern+""; - } - $("#sg-code-lineage-fill").html(lineageList); - } else { - $("#sg-code-lineage").css("display","none"); - } - - // draw reverse lineage - if (lineageR.length !== 0) { - var lineageRList = ""; - $("#sg-code-lineager").css("display","block"); - for (var i = 0; i < lineageR.length; i++) { - lineageRList += (i === 0) ? "" : ", "; - var cssClass = (lineageR[i].lineageState != undefined) ? "sg-pattern-state "+lineageR[i].lineageState : ""; - lineageRList += ""+lineageR[i].lineagePattern+""; - } - $("#sg-code-lineager-fill").html(lineageRList); - } else { - $("#sg-code-lineager").css("display","none"); - } - - // when clicking on a lineage item change the iframe source - $('#sg-code-lineage-fill a, #sg-code-lineager-fill a').on("click", function(e){ - e.preventDefault(); - $("#sg-code-loader").css("display","block"); - var obj = JSON.stringify({ "path": urlHandler.getFileName($(this).attr("data-patternpartial")) }); - document.getElementById("sg-viewport").contentWindow.postMessage(JSON.parse(obj),codeViewer.targetOrigin); - }); - - // show pattern state - if (patternState != "") { - $("#sg-code-patternstate").css("display","block"); - var patternStateItem = ""+patternState+""; - $("#sg-code-patternstate-fill").html(patternStateItem); - } else { - $("#sg-code-patternstate").css("display","none"); - } - - // fill in the name of the pattern - $('#sg-code-lineage-patternname, #sg-code-lineager-patternname, #sg-code-patternstate-patternname').html(patternPartial); - - // get the file name of the pattern so we can get the various editions of the code that can show in code view - var fileName = urlHandler.getFileName(patternPartial); - - // request the encoded markup version of the pattern - var e = new XMLHttpRequest(); - e.onload = this.saveEncoded; - e.open("GET", fileName.replace(/\.html/,".escaped.html") + "?" + (new Date()).getTime(), true); - e.send(); - - // request the mustache markup version of the pattern - var m = new XMLHttpRequest(); - m.onload = this.saveMustache; - m.open("GET", fileName.replace(/\.html/,".mustache") + "?" + (new Date()).getTime(), true); - m.send(); - - // if css is enabled request the css for the pattern - if (cssEnabled) { - var c = new XMLHttpRequest(); - c.onload = this.saveCSS; - c.open("GET", fileName.replace(/\.html/,".css") + "?" + (new Date()).getTime(), true); - c.send(); - } - - // move the code into view - codeViewer.slideCode(0); - - $("#sg-code-loader").css("display","none"); - - }, - - /** - * toggle the comment pop-up based on a user clicking on the pattern - * based on the great MDN docs at https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage - * @param {Object} event info - */ - receiveIframeMessage: function(event) { - - var data = (typeof event.data !== "string") ? event.data : JSON.parse(event.data); - - // does the origin sending the message match the current host? if not dev/null the request - if ((window.location.protocol !== "file:") && (event.origin !== window.location.protocol+"//"+window.location.host)) { - return; - } - - // switch based on stuff related to the postmessage - if (data.codeOverlay !== undefined) { - if (data.codeOverlay === "on") { - codeViewer.updateCode(data.lineage,data.lineageR,data.patternPartial,data.patternState,data.cssEnabled); - } else { - codeViewer.slideCode($('#sg-code-container').outerHeight()); - } - } else if (data.keyPress !== undefined) { - if (data.keyPress == 'ctrl+shift+c') { - codeViewer.toggleCode(); - return false; - } else if (data.keyPress == 'cmd+a') { - codeViewer.selectCode(); - return false; - } else if (data.keyPress == 'ctrl+shift+u') { - if (codeViewer.codeActive) { - codeViewer.swapCode("m"); - return false; - } - } else if (data.keyPress == 'ctrl+shift+y') { - if (codeViewer.codeActive) { - codeViewer.swapCode("e"); - return false; - } - } else if (data.keyPress == 'esc') { - if (codeViewer.codeActive) { - codeViewer.closeCode(); - return false; - } - } - } - - } - -}; - -// when the document is ready make the codeViewer ready -$(document).ready(function() { codeViewer.onReady(); }); -window.addEventListener("message", codeViewer.receiveIframeMessage, false); - -// make sure if a new pattern or view-all is loaded that comments are turned on as appropriate -$('#sg-viewport').load(function() { - if (codeViewer.codeActive) { - var obj = JSON.stringify({ "codeToggle": "on" }); - document.getElementById('sg-viewport').contentWindow.postMessage(obj,codeViewer.targetOrigin); - } -}); - -// toggle the code panel -jwerty.key('ctrl+shift+c', function (e) { - codeViewer.toggleCode(); - return false; -}); - -// when the code panel is open hijack cmd+a so that it only selects the code view -jwerty.key('cmd+a/ctrl+a', function (e) { - codeViewer.selectCode(); - return false; -}); - -// open the mustache panel -jwerty.key('ctrl+shift+u', function (e) { - if (codeViewer.codeActive) { - codeViewer.swapCode("m"); - return false; - } -}); - -// open the html panel -jwerty.key('ctrl+shift+y', function (e) { - if (codeViewer.codeActive) { - codeViewer.swapCode("e"); - return false; - } -}); - -// close the code panel if using escape -jwerty.key('esc', function (e) { - if (codeViewer.codeActive) { - codeViewer.closeCode(); - return false; - } -}); \ No newline at end of file diff --git a/core/styleguide/js/data-saver.js b/core/styleguide/js/data-saver.js deleted file mode 100644 index e354e1e79..000000000 --- a/core/styleguide/js/data-saver.js +++ /dev/null @@ -1,169 +0,0 @@ -/*! - * jQuery Cookie Plugin v1.3 - * https://github.com/carhartl/jquery-cookie - * - * Copyright 2011, Klaus Hartl - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://www.opensource.org/licenses/mit-license.php - * http://www.opensource.org/licenses/GPL-2.0 - */ -(function ($, document, undefined) { - - var pluses = /\+/g; - - function raw(s) { - return s; - } - - function decoded(s) { - return decodeURIComponent(s.replace(pluses, ' ')); - } - - var config = $.cookie = function (key, value, options) { - - // write - if (value !== undefined) { - options = $.extend({}, config.defaults, options); - - if (value === null) { - options.expires = -1; - } - - if (typeof options.expires === 'number') { - var days = options.expires, t = options.expires = new Date(); - t.setDate(t.getDate() + days); - } - - value = config.json ? JSON.stringify(value) : String(value); - - return (document.cookie = [ - encodeURIComponent(key), '=', config.raw ? value : encodeURIComponent(value), - options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE - options.path ? '; path=' + options.path : '', - options.domain ? '; domain=' + options.domain : '', - options.secure ? '; secure' : '' - ].join('')); - } - - // read - var decode = config.raw ? raw : decoded; - var cookies = document.cookie.split('; '); - for (var i = 0, l = cookies.length; i < l; i++) { - var parts = cookies[i].split('='); - if (decode(parts.shift()) === key) { - var cookie = decode(parts.join('=')); - return config.json ? JSON.parse(cookie) : cookie; - } - } - - return null; - }; - - config.defaults = {}; - - $.removeCookie = function (key, options) { - if ($.cookie(key) !== null) { - $.cookie(key, null, options); - return true; - } - return false; - }; - -})(jQuery, document); - -/*! - * Data Saver - v0.1 - * - * Copyright (c) 2013 Dave Olsen, http://dmolsen.com - * Licensed under the MIT license - */ - -var DataSaver = { - - // the name of the cookie to store the data in - cookieName: "patternlab", - - /** - * Add a given value to the cookie - * @param {String} the name of the key - * @param {String} the value - */ - addValue: function (name,val) { - var cookieVal = $.cookie(this.cookieName); - if ((cookieVal == null) || (cookieVal == "")) { - cookieVal = name+"~"+val; - } else { - cookieVal = cookieVal+"|"+name+"~"+val; - } - $.cookie(this.cookieName,cookieVal); - }, - - /** - * Update a value found in the cookie. If the key doesn't exist add the value - * @param {String} the name of the key - * @param {String} the value - */ - updateValue: function (name,val) { - if (this.findValue(name)) { - var updateCookieVals = ""; - var cookieVals = $.cookie(this.cookieName).split("|"); - for (var i = 0; i < cookieVals.length; i++) { - var fieldVals = cookieVals[i].split("~"); - if (fieldVals[0] == name) { - fieldVals[1] = val; - } - if (i > 0) { - updateCookieVals += "|"+fieldVals[0]+"~"+fieldVals[1]; - } else { - updateCookieVals += fieldVals[0]+"~"+fieldVals[1]; - } - } - $.cookie(this.cookieName,updateCookieVals); - } else { - this.addValue(name,val); - } - }, - - /** - * Remove the given key - * @param {String} the name of the key - */ - removeValue: function (name) { - var updateCookieVals = ""; - var cookieVals = $.cookie(this.cookieName).split("|"); - var k = 0; - for (var i = 0; i < cookieVals.length; i++) { - var fieldVals = cookieVals[i].split("~"); - if (fieldVals[0] != name) { - if (k == 0) { - updateCookieVals += fieldVals[0]+"~"+fieldVals[1]; - } else { - updateCookieVals += "|"+fieldVals[0]+"~"+fieldVals[1]; - } - k++; - } - } - $.cookie(this.cookieName,updateCookieVals); - }, - - /** - * Find the value using the given key - * @param {String} the name of the key - * - * @return {String} the value of the key or false if the value isn't found - */ - findValue: function (name) { - if ($.cookie(this.cookieName)) { - var cookieVals = $.cookie(this.cookieName).split("|"); - var k = 0; - for (var i = 0; i < cookieVals.length; i++) { - var fieldVals = cookieVals[i].split("~"); - if (fieldVals[0] == name) { - return fieldVals[1]; - } - } - } - return false; - } - -}; diff --git a/core/styleguide/js/pattern-finder.js b/core/styleguide/js/pattern-finder.js deleted file mode 100644 index f2290db12..000000000 --- a/core/styleguide/js/pattern-finder.js +++ /dev/null @@ -1,122 +0,0 @@ -/*! - * Pattern Finder - * - * Copyright (c) 2014 Dave Olsen, http://dmolsen.com - * Licensed under the MIT license - * - */ - -var patternFinder = { - - data: [], - active: false, - - init: function() { - - for (var patternType in patternPaths) { - if (patternPaths.hasOwnProperty(patternType)) { - for (var pattern in patternPaths[patternType]) { - var obj = {}; - obj.patternPartial = patternType+"-"+pattern; - obj.patternPath = patternPaths[patternType][pattern]; - this.data.push(obj); - } - } - } - - // instantiate the bloodhound suggestion engine - var patterns = new Bloodhound({ - datumTokenizer: function(d) { return Bloodhound.tokenizers.nonword(d.patternPartial); }, - queryTokenizer: Bloodhound.tokenizers.nonword, - limit: 10, - local: this.data - }); - - // initialize the bloodhound suggestion engine - patterns.initialize(); - - $('#sg-find .typeahead').typeahead({ highlight: true }, { - displayKey: 'patternPartial', - source: patterns.ttAdapter() - }).on('typeahead:selected', patternFinder.onAutocompleted).on('typeahead:autocompleted', patternFinder.onSelected); - - }, - - passPath: function(item) { - // update the iframe via the history api handler - patternFinder.closeFinder(); - var obj = JSON.stringify({ "path": urlHandler.getFileName(item.patternPartial) }); - document.getElementById("sg-viewport").contentWindow.postMessage(JSON.parse(obj), urlHandler.targetOrigin); - }, - - onSelected: function(e,item) { - patternFinder.passPath(item); - }, - - onAutocompleted: function(e,item) { - patternFinder.passPath(item); - }, - - toggleFinder: function() { - if (!patternFinder.active) { - patternFinder.openFinder(); - } else { - patternFinder.closeFinder(); - } - }, - - openFinder: function() { - patternFinder.active = true; - $('#sg-find .typeahead').val(""); - $("#sg-find").addClass('show-overflow'); - $('#sg-find .typeahead').focus(); - }, - - closeFinder: function() { - patternFinder.active = false; - $("#sg-find").removeClass('show-overflow'); - $('.sg-acc-handle, .sg-acc-panel').removeClass('active'); - $('#sg-find .typeahead').val(""); - }, - - receiveIframeMessage: function(event) { - - var data = (typeof event.data !== "string") ? event.data : JSON.parse(event.data); - - // does the origin sending the message match the current host? if not dev/null the request - if ((window.location.protocol !== "file:") && (event.origin !== window.location.protocol+"//"+window.location.host)) { - return; - } - - if (data.keyPress !== undefined) { - if (data.keyPress == 'ctrl+shift+f') { - patternFinder.toggleFinder(); - return false; - } - } - - } - -} - -patternFinder.init(); - -window.addEventListener("message", patternFinder.receiveIframeMessage, false); - -$('#sg-find .typeahead').focus(function() { - if (!patternFinder.active) { - patternFinder.openFinder(); - } -}); - -$('#sg-find .typeahead').blur(function() { - patternFinder.closeFinder(); -}); - -// jwerty stuff -// toggle the annotations panel -jwerty.key('ctrl+shift+f', function (e) { - $('.sg-find .sg-acc-handle, .sg-find .sg-acc-panel').addClass('active'); - patternFinder.toggleFinder(); - return false; -}); \ No newline at end of file diff --git a/core/styleguide/js/postmessage.js b/core/styleguide/js/postmessage.js deleted file mode 100644 index 76e482d3f..000000000 --- a/core/styleguide/js/postmessage.js +++ /dev/null @@ -1,127 +0,0 @@ -/*! - * Basic postMessage Support - v0.1 - * - * Copyright (c) 2013-2014 Dave Olsen, http://dmolsen.com - * Licensed under the MIT license - * - * Handles the postMessage stuff in the pattern, view-all, and style guide templates. - * - */ - -// alert the iframe parent that the pattern has loaded assuming this view was loaded in an iframe -if (self != top) { - - // handle the options that could be sent to the parent window - // - all get path - // - pattern & view all get a pattern partial, styleguide gets all - // - pattern shares lineage - var path = window.location.toString(); - var parts = path.split("?"); - var options = { "path": parts[0] }; - options.patternpartial = (patternPartial !== "") ? patternPartial : "all"; - if (lineage !== "") { - options.lineage = lineage; - } - - var targetOrigin = (window.location.protocol == "file:") ? "*" : window.location.protocol+"//"+window.location.host; - parent.postMessage(options, targetOrigin); - - // find all links and add an onclick handler for replacing the iframe address so the history works - var aTags = document.getElementsByTagName('a'); - for (var i = 0; i < aTags.length; i++) { - aTags[i].onclick = function(e) { - e.preventDefault(); - var href = this.getAttribute("href"); - if (href != "#") { - window.location.replace(href); - } - }; - } - - // bind the keyboard shortcuts for various viewport resizings + pattern search - var keys = [ "s", "m", "l", "d", "h", "f" ]; - for (var i = 0; i < keys.length; i++) { - jwerty.key('ctrl+shift+'+keys[i], function (k,t) { - return function(e) { - parent.postMessage({ "keyPress": "ctrl+shift+"+k },t); - return false; - } - }(keys[i],targetOrigin)); - } - - // bind the keyboard shortcuts for mqs - var i = 0; - while (i < 10) { - jwerty.key('ctrl+shift+'+i, function (k,t) { - return function(e) { - var targetOrigin = (window.location.protocol == "file:") ? "*" : window.location.protocol+"//"+window.location.host; - parent.postMessage({ "keyPress": "ctrl+shift+"+k },t); - return false; - } - }(i,targetOrigin)); - i++; - } - -} - -// if there are clicks on the iframe make sure the nav in the iframe parent closes -var body = document.getElementsByTagName('body'); -body[0].onclick = function() { - var targetOrigin = (window.location.protocol == "file:") ? "*" : window.location.protocol+"//"+window.location.host; - parent.postMessage({ "bodyclick": "bodyclick" },targetOrigin); -}; - -// watch the iframe source so that it can be sent back to everyone else. -function receiveIframeMessage(event) { - - var path; - var data = (typeof event.data !== "string") ? event.data : JSON.parse(event.data); - - // does the origin sending the message match the current host? if not dev/null the request - if ((window.location.protocol != "file:") && (event.origin !== window.location.protocol+"//"+window.location.host)) { - return; - } - - // see if it got a path to replace - if (data.path !== undefined) { - - if (patternPartial !== "") { - - if(baseurl){ - // create main site url - var siteurl = window.location.protocol+"//"+window.location.host; - // add a trailing slash if it doesn't exist - siteurl = siteurl.replace(/\/?$/, '/'); - // remove a begining slash for baseurl if it exists - baseurl = baseurl.replace(/^\//, ''); - // connect baseurl to siteurl - siteurl = siteurl + baseurl; - // add a trailing slash if it doesn't exist - siteurl = siteurl.replace(/\/?$/, '/'); - // build our final path - path = siteurl+data.path+'?'+Date.now(); - } else { - // handle patterns and the view all page - var re = /patterns\/(.*)$/; - path = window.location.protocol+"//"+window.location.host+window.location.pathname.replace(re,'')+data.path+'?'+Date.now(); - } - - window.location.replace(path); - - } else { - - // handle the style guide - path = window.location.protocol+"//"+window.location.host+window.location.pathname.replace("styleguide\/html\/styleguide.html","")+data.path+'?'+Date.now(); - window.location.replace(path); - - } - - } else if (data.reload !== undefined) { - - // reload the location if there was a message to do so - window.location.reload(); - - } - -} -window.addEventListener("message", receiveIframeMessage, false); \ No newline at end of file diff --git a/core/styleguide/js/styleguide.js b/core/styleguide/js/styleguide.js deleted file mode 100644 index ce83f10d5..000000000 --- a/core/styleguide/js/styleguide.js +++ /dev/null @@ -1,602 +0,0 @@ -(function(w){ - - var sw = document.body.clientWidth, //Viewport Width - sh = $(document).height(), //Viewport Height - minViewportWidth = 240, //Minimum Size for Viewport - maxViewportWidth = 2600, //Maxiumum Size for Viewport - viewportResizeHandleWidth = 14, //Width of the viewport drag-to-resize handle - $sgViewport = $('#sg-viewport'), //Viewport element - $sizePx = $('.sg-size-px'), //Px size input element in toolbar - $sizeEms = $('.sg-size-em'), //Em size input element in toolbar - $bodySize = parseInt($('body').css('font-size')), //Body size of the document - $headerHeight = $('.sg-header').height(), - discoID = false, - discoMode = false, - fullMode = true, - hayMode = false; - - $(w).resize(function(){ //Update dimensions on resize - sw = document.body.clientWidth; - sh = $(document).height(); - - setAccordionHeight(); - - if(fullMode === true) { - sizeiframe(sw, false); - }; - - }); - - /* Pattern Lab accordion dropdown */ - // Accordion dropdown - $('.sg-acc-handle').on("click", function(e){ - e.preventDefault(); - - var $this = $(this), - $panel = $this.next('.sg-acc-panel'), - subnav = $this.parent().parent().hasClass('sg-acc-panel'); - - //Close other panels if link isn't a subnavigation item - if (!subnav) { - $('.sg-acc-handle').not($this).removeClass('active'); - $('.sg-acc-panel').not($panel).removeClass('active'); - } - - //Activate selected panel - $this.toggleClass('active'); - $panel.toggleClass('active'); - setAccordionHeight(); - }); - - //Accordion Height - function setAccordionHeight() { - var $activeAccordion = $('.sg-acc-panel.active').first(), - accordionHeight = $activeAccordion.height(), - availableHeight = sh-$headerHeight; //Screen height minus the height of the header - - $activeAccordion.height(availableHeight); //Set height of accordion to the available height - } - - $('.sg-nav-toggle').on("click", function(e){ - e.preventDefault(); - $('.sg-nav-container').toggleClass('active'); - }); - - //"View (containing clean, code, raw, etc options) Trigger - $('#sg-t-toggle').on("click", function(e){ - e.preventDefault(); - $(this).parents('ul').toggleClass('active'); - }); - - //Size Trigger - $('#sg-size-toggle').on("click", function(e){ - e.preventDefault(); - $(this).parents('ul').toggleClass('active'); - }); - - //Phase View Events - $('.sg-size[data-size]').on("click", function(e){ - e.preventDefault(); - killDisco(); - killHay(); - fullMode = false; - - var val = $(this).attr('data-size'); - - if (val.indexOf('px') > -1) { - $bodySize = 1; - } - - val = val.replace(/[^\d.-]/g,'') - sizeiframe(Math.floor(val*$bodySize)); - }); - - //Size View Events - - // handle small button - function goSmall() { - killDisco(); - killHay(); - fullMode = false; - sizeiframe(getRandom(minViewportWidth,500)); - } - - $('#sg-size-s').on("click", function(e){ - e.preventDefault(); - goSmall(); - }); - - jwerty.key('ctrl+shift+s', function(e) { - goSmall(); - return false; - }); - - // handle medium button - function goMedium() { - killDisco(); - killHay(); - fullMode = false; - sizeiframe(getRandom(500,800)); - } - - $('#sg-size-m').on("click", function(e){ - e.preventDefault(); - goMedium(); - }); - - jwerty.key('ctrl+shift+m', function(e) { - goMedium(); - return false; - }); - - // handle large button - function goLarge() { - killDisco(); - killHay(); - fullMode = false; - sizeiframe(getRandom(800,1200)); - } - - $('#sg-size-l').on("click", function(e){ - e.preventDefault(); - goLarge(); - }); - - jwerty.key('ctrl+shift+l', function(e) { - goLarge(); - return false; - }); - - //Click Full Width Button - $('#sg-size-full').on("click", function(e){ //Resets - e.preventDefault(); - killDisco(); - killHay(); - fullMode = true; - sizeiframe(sw); - }); - - //Click Random Size Button - $('#sg-size-random').on("click", function(e){ - e.preventDefault(); - killDisco(); - killHay(); - sizeiframe(getRandom(minViewportWidth,sw)); - }); - - //Click for Disco Mode, which resizes the viewport randomly - $('#sg-size-disco').on("click", function(e){ - e.preventDefault(); - killHay(); - fullMode = false; - - if (discoMode) { - killDisco(); - - } else { - startDisco(); - } - }); - - /* Disco Mode */ - function disco() { - sizeiframe(getRandom(minViewportWidth,sw)); - } - - function killDisco() { - discoMode = false; - clearInterval(discoID); - discoID = false; - } - - function startDisco() { - killHay(); - discoMode = true; - discoID = setInterval(disco, 800); - } - - jwerty.key('ctrl+shift+d', function(e) { - if (!discoMode) { - startDisco(); - } else { - killDisco(); - } - return false; - }); - - //Stephen Hay Mode - "Start with the small screen first, then expand until it looks like shit. Time for a breakpoint!" - $('#sg-size-hay').on("click", function(e){ - e.preventDefault(); - killDisco(); - if (hayMode) { - killHay(); - } else { - startHay(); - } - }); - - //Stop Hay! Mode - function killHay() { - var currentWidth = $sgViewport.width(); - hayMode = false; - $sgViewport.removeClass('hay-mode'); - $('#sg-gen-container').removeClass('hay-mode'); - sizeiframe(Math.floor(currentWidth)); - } - - // start Hay! mode - function startHay() { - killDisco(); - hayMode = true; - $('#sg-gen-container').removeClass("vp-animate").width(minViewportWidth+viewportResizeHandleWidth); - $sgViewport.removeClass("vp-animate").width(minViewportWidth); - - var timeoutID = window.setTimeout(function(){ - $('#sg-gen-container').addClass('hay-mode').width(maxViewportWidth+viewportResizeHandleWidth); - $sgViewport.addClass('hay-mode').width(maxViewportWidth); - - setInterval(function(){ var vpSize = $sgViewport.width(); updateSizeReading(vpSize); },100); - }, 200); - } - - // start hay from a keyboard shortcut - jwerty.key('ctrl+shift+h', function(e) { - if (hayMode) { - killHay(); - } else { - startHay(); - } - return false; - }); - - //Pixel input - $sizePx.on('keydown', function(e){ - var val = Math.floor($(this).val()); - - if(e.keyCode === 38) { //If the up arrow key is hit - val++; - sizeiframe(val,false); - } else if(e.keyCode === 40) { //If the down arrow key is hit - val--; - sizeiframe(val,false); - } else if(e.keyCode === 13) { //If the Enter key is hit - e.preventDefault(); - sizeiframe(val); //Size Iframe to value of text box - $(this).blur(); - } - }); - - $sizePx.on('keyup', function(){ - var val = Math.floor($(this).val()); - updateSizeReading(val,'px','updateEmInput'); - }); - - //Em input - $sizeEms.on('keydown', function(e){ - var val = parseFloat($(this).val()); - - if(e.keyCode === 38) { //If the up arrow key is hit - val++; - sizeiframe(Math.floor(val*$bodySize),false); - } else if(e.keyCode === 40) { //If the down arrow key is hit - val--; - sizeiframe(Math.floor(val*$bodySize),false); - } else if(e.keyCode === 13) { //If the Enter key is hit - e.preventDefault(); - sizeiframe(Math.floor(val*$bodySize)); //Size Iframe to value of text box - } - }); - - $sizeEms.on('keyup', function(){ - var val = parseFloat($(this).val()); - updateSizeReading(val,'em','updatePxInput'); - }); - - // set 0 to 320px as a default - jwerty.key('ctrl+shift+0', function(e) { - e.preventDefault(); - sizeiframe(320,true); - return false; - }); - - // handle the MQ click - var mqs = []; - $('#sg-mq a').each(function(i) { - - mqs.push($(this).html()); - - // bind the click - $(this).on("click", function(i,k) { - return function(e) { - e.preventDefault(); - var val = $(k).html(); - var type = (val.indexOf("px") !== -1) ? "px" : "em"; - val = val.replace(type,""); - var width = (type === "px") ? val*1 : val*$bodySize; - sizeiframe(width,true); - } - }(i,this)); - - // bind the keyboard shortcut. can't use cmd on a mac because 3 & 4 are for screenshots - jwerty.key('ctrl+shift+'+(i+1), function (k) { - return function(e) { - var val = $(k).html(); - var type = (val.indexOf("px") !== -1) ? "px" : "em"; - val = val.replace(type,""); - var width = (type === "px") ? val*1 : val*$bodySize; - sizeiframe(width,true); - return false; - } - }(this)); - - }); - - //Resize the viewport - //'size' is the target size of the viewport - //'animate' is a boolean for switching the CSS animation on or off. 'animate' is true by default, but can be set to false for things like nudging and dragging - function sizeiframe(size,animate) { - var theSize; - - if(size>maxViewportWidth) { //If the entered size is larger than the max allowed viewport size, cap value at max vp size - theSize = maxViewportWidth; - } else if(size