{{guide.attributes.title}}
5 |6 |
7 | {{/if}} 8 | {{markdown-content guide.content extensions="prettify"}} 9 |
├── .editorconfig
├── .ember-cli
├── .eslintrc.js
├── .gitattributes
├── .gitignore
├── .npmignore
├── .travis.yml
├── .watchmanconfig
├── LICENSE.md
├── README.md
├── addon
├── .gitkeep
├── components
│ ├── markdown-menu-item.js
│ └── markdown-menu.js
├── helpers
│ ├── get-markdown-content.js
│ ├── get-markdown-file.js
│ └── get-markdown-tree.js
├── services
│ └── markdown-resolver.js
├── templates
│ └── components
│ │ ├── markdown-menu-item.hbs
│ │ └── markdown-menu.hbs
└── utils
│ └── computed-fallback-action.js
├── app
├── .gitkeep
├── components
│ ├── markdown-menu-item.js
│ └── markdown-menu.js
├── helpers
│ ├── get-markdown-content.js
│ ├── get-markdown-file.js
│ └── get-markdown-tree.js
├── services
│ └── markdown-resolver.js
└── styles
│ └── app.scss
├── blueprints
└── ember-cli-markdown-resolver
│ └── index.js
├── config
├── ember-try.js
└── environment.js
├── ember-cli-build.js
├── index.js
├── package.json
├── testem.js
├── tests
├── .eslintrc.js
├── dummy
│ ├── app
│ │ ├── app.js
│ │ ├── components
│ │ │ ├── .gitkeep
│ │ │ ├── markdown-content.js
│ │ │ ├── ui-button-link-to.js
│ │ │ ├── ui-button-link.js
│ │ │ ├── ui-button.js
│ │ │ ├── ui-navbar.js
│ │ │ └── ui-section.js
│ │ ├── controllers
│ │ │ └── .gitkeep
│ │ ├── guides
│ │ │ ├── components.md
│ │ │ ├── components
│ │ │ │ └── markdown-menu.md
│ │ │ ├── examples.md
│ │ │ ├── examples
│ │ │ │ ├── ember-cli-showdown.md
│ │ │ │ └── ember-collapsible-panel.md
│ │ │ ├── fragment-identifiers.md
│ │ │ ├── index.md
│ │ │ ├── install.md
│ │ │ ├── not-in-tree.md
│ │ │ ├── usage.md
│ │ │ └── usage
│ │ │ │ ├── files.md
│ │ │ │ └── trees.md
│ │ ├── helpers
│ │ │ └── .gitkeep
│ │ ├── index.html
│ │ ├── initializers
│ │ │ └── showdown.js
│ │ ├── instance-initializers
│ │ │ ├── head-data.js
│ │ │ └── inject-config.js
│ │ ├── mixins
│ │ │ └── ui
│ │ │ │ ├── align-mixin.js
│ │ │ │ ├── color-mixin.js
│ │ │ │ ├── depth-mixin.js
│ │ │ │ ├── font-size-mixin.js
│ │ │ │ ├── padding-mixin.js
│ │ │ │ └── size-mixin.js
│ │ ├── models
│ │ │ └── .gitkeep
│ │ ├── resolver.js
│ │ ├── router.js
│ │ ├── routes
│ │ │ ├── .gitkeep
│ │ │ ├── application.js
│ │ │ ├── guides.js
│ │ │ └── guides
│ │ │ │ ├── index.js
│ │ │ │ └── single.js
│ │ ├── styles
│ │ │ ├── app.scss
│ │ │ ├── components
│ │ │ │ ├── _.scss
│ │ │ │ ├── _config.scss
│ │ │ │ ├── buttons
│ │ │ │ │ └── _.scss
│ │ │ │ ├── footer
│ │ │ │ │ └── _.scss
│ │ │ │ ├── markdown
│ │ │ │ │ ├── _.scss
│ │ │ │ │ ├── _menu.scss
│ │ │ │ │ └── _prettyprint.scss
│ │ │ │ ├── navbar
│ │ │ │ │ └── _.scss
│ │ │ │ └── sections
│ │ │ │ │ └── _.scss
│ │ │ ├── framework
│ │ │ │ ├── _colors.scss
│ │ │ │ ├── _fonts.scss
│ │ │ │ ├── _grid.scss
│ │ │ │ ├── _mixins.scss
│ │ │ │ ├── _reset.scss
│ │ │ │ ├── _type.scss
│ │ │ │ └── _utility.scss
│ │ │ ├── main
│ │ │ │ ├── _.scss
│ │ │ │ └── _config.scss
│ │ │ └── routes
│ │ │ │ └── _.scss
│ │ ├── templates
│ │ │ ├── application.hbs
│ │ │ ├── components
│ │ │ │ ├── .gitkeep
│ │ │ │ ├── ui-button.hbs
│ │ │ │ ├── ui-footer.hbs
│ │ │ │ └── ui-navbar.hbs
│ │ │ ├── error.hbs
│ │ │ ├── guides.hbs
│ │ │ ├── guides
│ │ │ │ └── single.hbs
│ │ │ ├── head.hbs
│ │ │ └── index.hbs
│ │ └── utils
│ │ │ └── property-class-name-binding.js
│ ├── config
│ │ ├── environment.js
│ │ └── targets.js
│ └── public
│ │ ├── crossdomain.xml
│ │ ├── images
│ │ ├── facebook.jpg
│ │ ├── favicon-16x16.png
│ │ ├── favicon-32x32.png
│ │ ├── favicon.ico
│ │ ├── logo-black.svg
│ │ └── logo-white.svg
│ │ └── robots.txt
├── helpers
│ ├── destroy-app.js
│ ├── module-for-acceptance.js
│ ├── resolver.js
│ └── start-app.js
├── index.html
├── integration
│ └── .gitkeep
├── test-helper.js
└── unit
│ └── .gitkeep
├── vendor
└── .gitkeep
└── yarn.lock
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 | end_of_line = lf
10 | charset = utf-8
11 | trim_trailing_whitespace = true
12 | insert_final_newline = true
13 | indent_style = space
14 | indent_size = 2
15 |
16 | [*.hbs]
17 | insert_final_newline = false
18 |
19 | [*.{diff,md}]
20 | trim_trailing_whitespace = false
21 |
--------------------------------------------------------------------------------
/.ember-cli:
--------------------------------------------------------------------------------
1 | {
2 | /**
3 | Ember CLI sends analytics information by default. The data is completely
4 | anonymous, but there are times when you might want to disable this behavior.
5 |
6 | Setting `disableAnalytics` to true will prevent any data from being sent.
7 | */
8 | "disableAnalytics": false
9 | }
10 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parserOptions: {
4 | ecmaVersion: 2017,
5 | sourceType: 'module'
6 | },
7 | extends: 'eslint:recommended',
8 | env: {
9 | browser: true
10 | },
11 | rules: {
12 | }
13 | };
14 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | tests/dummy/* linguist-vendored
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 |
7 | # dependencies
8 | /node_modules
9 | /bower_components
10 |
11 | # misc
12 | /.sass-cache
13 | /connect.lock
14 | /coverage/*
15 | /libpeerconnection.log
16 | npm-debug.log*
17 | yarn-error.log
18 | testem.log
19 |
20 | # ember-try
21 | .node_modules.ember-try/
22 | bower.json.ember-try
23 | package.json.ember-try
24 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | /bower_components
2 | /config/ember-try.js
3 | /dist
4 | /tests
5 | /tmp
6 | **/.gitkeep
7 | .bowerrc
8 | .editorconfig
9 | .ember-cli
10 | .gitignore
11 | .eslintrc.js
12 | .watchmanconfig
13 | .travis.yml
14 | bower.json
15 | ember-cli-build.js
16 | testem.js
17 | /DEBUG
18 | Icon^M^M
19 | Icon*
20 |
21 | # ember-try
22 | .node_modules.ember-try/
23 | bower.json.ember-try
24 | package.json.ember-try
25 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | ---
2 | language: node_js
3 | node_js:
4 | # we recommend testing addons with the same minimum supported node version as Ember CLI
5 | # so that your addon works for all apps
6 | - "6"
7 |
8 | sudo: false
9 | dist: trusty
10 |
11 | addons:
12 | chrome: stable
13 |
14 | cache:
15 | yarn: true
16 |
17 | env:
18 | global:
19 | # See https://git.io/vdao3 for details.
20 | - JOBS=1
21 | matrix:
22 | # we recommend new addons test the current and previous LTS
23 | # as well as latest stable release (bonus points to beta/canary)
24 | - EMBER_TRY_SCENARIO=ember-lts-2.12
25 | - EMBER_TRY_SCENARIO=ember-lts-2.16
26 | - EMBER_TRY_SCENARIO=ember-release
27 | - EMBER_TRY_SCENARIO=ember-beta
28 | - EMBER_TRY_SCENARIO=ember-canary
29 | - EMBER_TRY_SCENARIO=ember-default
30 |
31 | matrix:
32 | fast_finish: true
33 | allow_failures:
34 | - env: EMBER_TRY_SCENARIO=ember-canary
35 |
36 | before_install:
37 | - curl -o- -L https://yarnpkg.com/install.sh | bash
38 | - export PATH=$HOME/.yarn/bin:$PATH
39 |
40 | install:
41 | - yarn install --no-lockfile --non-interactive
42 |
43 | script:
44 | # Usually, it's ok to finish the test scenario without reverting
45 | # to the addon's original dependency state, skipping "cleanup".
46 | - node_modules/.bin/ember try:one $EMBER_TRY_SCENARIO --skip-cleanup
47 |
--------------------------------------------------------------------------------
/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {
2 | "ignore_dirs": ["tmp", "dist"]
3 | }
4 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | Ember CLI Markdown Resolver
4 | ======
5 | [](https://travis-ci.org/willviles/ember-cli-markdown-resolver) [](http://emberobserver.com/addons/ember-cli-markdown-resolver) []((https://www.npmjs.com/package/ember-cli-markdown-resolver)) [](https://www.npmjs.com/package/ember-cli-markdown-resolver)
6 |
7 | Ember CLI Markdown Resolver is the quickest way to include static markdown content in your Ember.js application using [Broccoli Markdown Resolver](https://github.com/willviles/broccoli-markdown-resolver).
8 |
9 | ## Installation
10 |
11 | ```
12 | ember install ember-cli-markdown-resolver
13 | ```
14 |
15 | ## Configuration
16 |
17 | The addon requires you specify the locations of markdown files:
18 |
19 | ```js
20 | // config/environment.js
21 |
22 | ENV['ember-cli-markdown-resolver'] = {
23 | folders: {
24 | 'guides': 'app/guides'
25 | }
26 | };
27 | ```
28 |
29 | And to populate your folder with markdown content:
30 |
31 | ```shell
32 | .
33 | └── app/
34 | └── guides/
35 | ├── quick-start.md
36 | ├── examples.md
37 | └── examples/
38 | └── first.md
39 | ```
40 |
41 | ## Usage
42 |
43 | Ember CLI Markdown Resolver enables markdown content to be retrieved via the `markdownResolver` service.
44 |
45 | ### `this.get('markdownResolver').file(type, path)`
46 |
47 | The `file` method returns promisified markdown content, allowing the content to be chainable via `.then()`.
48 |
49 | ```js
50 | // routes/guides/single.js
51 |
52 | import Route from '@ember/routing/route';
53 | import { get } from '@ember/object';
54 | import { inject } from '@ember/service';
55 |
56 | export default Route.extend({
57 | markdownResolver: inject(),
58 |
59 | model({ path }) {
60 | return get(this, 'markdownResolver').file('guides', path);
61 | }
62 | });
63 | ```
64 |
65 | Each markdown file exposes the path, raw content, frontmatter attributes and its children.
66 |
67 | ```hbs
68 |
69 |
70 | {{model.content}}
71 | {{model.path}}
72 | {{model.attributes}}
73 | {{model.children}}
74 | ```
75 |
76 | ### `this.get('markdownResolver').tree(type)`
77 |
78 | The `tree` method returns a tree object for a given folder, allowing menu interfaces to be built from the markdown file structure.
79 |
80 | ```js
81 | // routes/guides.js
82 |
83 | import Route from '@ember/routing/route';
84 | import { get } from '@ember/object';
85 | import { inject } from '@ember/service';
86 |
87 | export default Route.extend({
88 | markdownResolver: inject(),
89 |
90 | model() {
91 | return get(this, 'markdownResolver').tree('guides');
92 | }
93 | });
94 | ```
95 |
96 | Adding an `order` value to a file's frontmatter will automatically order files within the tree.
97 |
98 | ```md
99 | ---
100 | title: Quick Start
101 | order: 0
102 | ---
103 |
104 | Lorem ipsum dolor sit amet...
105 | ```
106 |
107 | Additionally, adding a `fragmentIdLinks` object to a file's frontmatter will generate a list local fragment identifier links which are used within the `{{markdown-menu-item}}` component. This is handy when you want to link to several individual sections of a large parent markdown file instead of having individual child markdown files.
108 |
109 | The `fragmentIdLinks` object expects child key-value pairs where each `key` represents the hash fragment id link and each `value` represents the text label to be shown as a child on the `{{markdown-menu}}` component.
110 |
111 | ```md
112 | ---
113 | title: Fragment Identifier Links
114 | order: 4
115 | fragmentIdLinks:
116 | iamsectionone: "Section One"
117 | section-two: "Section Two"
118 | ---
119 |
120 | ### I am section one
121 | Lorem ipsum dolor sit amet...
122 |
123 | Lorem ipsum dolor sit amet...
124 | ```
125 |
126 | By default, when you click on each `fragmentIdLinks` child link within the `{{markdown-menu-item}}` component it will update the url hash. You can easily override this default behavior by passing an `onClick` closure action into the `{{markdown-menu}}` component.
127 |
128 | ```hbs
129 | {{!-- templates/guides.hbs --}}
130 | {{markdown-menu onClick=(action "clickedMenuItemLink")}}
131 | ```
132 |
133 | ```js
134 | // controllers/guides.js
135 | import Controller from '@ember/controller';
136 |
137 | export default Controller.extend({
138 | actions: {
139 | clickedMenuItemLink(fragmentIdLink) {
140 | document.querySelector(`#${fragmentIdLink}`).scrollIntoView({
141 | behavior: 'smooth'
142 | });
143 | }
144 | }
145 | });
146 | ```
147 |
148 | The addon ships with a `markdown-menu` component which builds a nested list from your file tree and can be styled using your own css.
149 |
150 | ```hbs
151 |
152 |
153 | {{markdown-menu
154 | title="My Markdown Menu"
155 | tree=model}}
156 | {{outlet}}
157 | ```
158 |
159 | ## Helpers
160 |
161 | Ember CLI Markdown Resolver defines the following template helpers:
162 |
163 | ```hbs
164 |
165 | {{get (get-markdown-file 'guides' 'nested/page-slug') 'title'}}
166 |
167 |
168 | {{my-render-component content=(get-markdown-content 'guides' 'nested/page-slug')}}
169 |
170 |
171 | {{markdown-menu tree=(get-markdown-tree 'guides')}}
172 | ```
173 |
174 | ## Demo
175 |
176 | Check out the [Ember CLI Markdown Resolver guides](https://willviles.github.io/ember-cli-markdown-resolver), which is generated using the addon.
177 |
178 | Code for the guides can be found [here](https://github.com/willviles/ember-cli-markdown-resolver/tree/master/tests/dummy).
179 |
180 | ## Node Version
181 |
182 | Ember CLI Markdown Resolver currently supports Node >=6.
183 |
184 | ## Contributing
185 |
186 | ### Installation
187 |
188 | * `git clone https://github.com/willviles/ember-cli-markdown-resolver.git`
189 | * `cd ember-cli-markdown-resolver`
190 | * `yarn install`
191 |
192 | ### Running
193 |
194 | * `ember serve`
195 | * Visit your app at [http://localhost:4200](http://localhost:4200).
196 |
197 | ### Running Tests
198 |
199 | * `yarn test` (Runs `ember try:each` to test your addon against multiple Ember versions)
200 | * `ember test`
201 | * `ember test --server`
202 |
203 | ### Building
204 |
205 | * `ember build`
206 |
207 | For more information on using ember-cli, visit [https://ember-cli.com/](https://ember-cli.com/).
208 |
--------------------------------------------------------------------------------
/addon/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willviles/ember-cli-markdown-resolver/46e56e04d3bf9508f56e7844030f865f7e0fd788/addon/.gitkeep
--------------------------------------------------------------------------------
/addon/components/markdown-menu-item.js:
--------------------------------------------------------------------------------
1 | import Component from '@ember/component';
2 | import { computed, get } from '@ember/object';
3 | import { empty } from '@ember/object/computed';
4 |
5 | import layout from 'ember-cli-markdown-resolver/templates/components/markdown-menu-item';
6 |
7 | export default Component.extend({
8 | layout,
9 | tagName: 'li',
10 | classNames: ['markdown-menu-item'],
11 |
12 | itemPath: computed('item.path', 'treePath', function() {
13 | let itemPath = get(this, 'item.path'),
14 | treePath = get(this, 'treePath');
15 | if (!itemPath) { return; }
16 | return itemPath.replace(`${treePath}/`, '');
17 | }),
18 |
19 | noContent: empty('item.content'),
20 |
21 | actions: {
22 | onClick(fragmentIdLink) {
23 | let onClick = get(this, 'onClick');
24 |
25 | if (onClick) {
26 | onClick(fragmentIdLink);
27 | }
28 | }
29 | }
30 | });
31 |
--------------------------------------------------------------------------------
/addon/components/markdown-menu.js:
--------------------------------------------------------------------------------
1 | import Component from '@ember/component';
2 | import { scheduleOnce } from '@ember/runloop';
3 | import { or } from '@ember/object/computed';
4 | import fallbackAction from 'ember-cli-markdown-resolver/utils/computed-fallback-action';
5 |
6 | import layout from 'ember-cli-markdown-resolver/templates/components/markdown-menu';
7 |
8 | export default Component.extend({
9 | layout,
10 | classNames: ['markdown-menu'],
11 |
12 | menuTitle: or('title', 'tree.name'),
13 |
14 | // Actions
15 | onClick: fallbackAction(function(fragmentIdLink) {
16 | if (fragmentIdLink && typeof fragmentIdLink === "string" && fragmentIdLink.length) {
17 | scheduleOnce('afterRender', this, () => {
18 | location.hash = fragmentIdLink;
19 | });
20 | } else {
21 | location.hash = "";
22 | }
23 | })
24 | });
25 |
--------------------------------------------------------------------------------
/addon/helpers/get-markdown-content.js:
--------------------------------------------------------------------------------
1 | import Helper from '@ember/component/helper';
2 | import { get } from '@ember/object';
3 | import { inject as service } from '@ember/service';
4 |
5 | export default Helper.extend({
6 |
7 | markdownResolver: service(),
8 |
9 | compute([tree, file]) {
10 | let md = get(this, 'markdownResolver')._file(tree, file);
11 | return get(md, 'content');
12 | }
13 |
14 | });
15 |
--------------------------------------------------------------------------------
/addon/helpers/get-markdown-file.js:
--------------------------------------------------------------------------------
1 | import Helper from '@ember/component/helper';
2 | import { get } from '@ember/object';
3 | import { inject as service } from '@ember/service';
4 |
5 | export default Helper.extend({
6 |
7 | markdownResolver: service(),
8 |
9 | compute([tree, file]) {
10 | return get(this, 'markdownResolver')._file(tree, file);
11 | }
12 |
13 | });
14 |
--------------------------------------------------------------------------------
/addon/helpers/get-markdown-tree.js:
--------------------------------------------------------------------------------
1 | import Helper from '@ember/component/helper';
2 | import { get } from '@ember/object';
3 | import { inject as service } from '@ember/service';
4 |
5 | export default Helper.extend({
6 |
7 | markdownResolver: service(),
8 |
9 | compute([tree]) {
10 | return get(this, 'markdownResolver')._tree(tree);
11 | }
12 |
13 | });
14 |
--------------------------------------------------------------------------------
/addon/services/markdown-resolver.js:
--------------------------------------------------------------------------------
1 | import Service from '@ember/service';
2 | import {
3 | getOwner
4 | } from '@ember/application';
5 | import {
6 | A
7 | } from "@ember/array"
8 | import {
9 | computed,
10 | get,
11 | getWithDefault,
12 | set
13 | } from '@ember/object';
14 | import {
15 | files,
16 | trees
17 | } from 'ember-cli-markdown-resolver/files';
18 | import RSVP from 'rsvp';
19 |
20 | const {
21 | resolve
22 | } = RSVP;
23 |
24 | export default Service.extend({
25 |
26 | config: computed(function() {
27 | return getOwner(this).resolveRegistration('config:environment')['ember-cli-markdown-resolver'] || {}
28 | }),
29 |
30 | files: computed(function() {
31 | return A(files);
32 | }),
33 |
34 | trees: computed(function() {
35 | return Object.keys(trees).reduce((allTrees, key) => {
36 | allTrees[key] = {
37 | name: this.getTreeName(key),
38 | path: key,
39 | files: this.orderFiles(trees[key])
40 | };
41 | return allTrees;
42 | }, {});
43 | }),
44 |
45 | _file(tree, file) {
46 | tree = this.getPathFromTreeName(tree);
47 | return get(this, 'files').findBy('path', `${tree}/${file}`);
48 | },
49 |
50 | file(tree, file) {
51 | return resolve(this._file(tree, file));
52 | },
53 |
54 | _tree(tree) {
55 | tree = this.getPathFromTreeName(tree);
56 | return getWithDefault(this, `trees.${tree}`, []);
57 | },
58 |
59 | tree(tree) {
60 | return resolve(this._tree(tree));
61 | },
62 |
63 | getTreeName(path) {
64 | let folders = get(this, 'config.folders');
65 | return Object.keys(folders).find(key => {
66 | return folders[key] === path;
67 | });
68 | },
69 |
70 | getPathFromTreeName(treeName) {
71 | return get(this, `config.folders.${treeName}`);
72 | },
73 |
74 | orderFiles(files) {
75 | files = A(files).sortBy('attributes.order').filter((file) => {
76 | let attrs = get(file, 'attributes');
77 | if (attrs.hasOwnProperty('inTree') && !get(attrs, 'inTree')) {
78 | return;
79 | }
80 | return file;
81 | });
82 |
83 | files.forEach(file => {
84 | let children = get(file, 'children');
85 | if (children) {
86 | set(file, 'children', this.orderFiles(children));
87 | }
88 | });
89 |
90 | return files;
91 | }
92 |
93 | });
94 |
--------------------------------------------------------------------------------
/addon/templates/components/markdown-menu-item.hbs:
--------------------------------------------------------------------------------
1 | {{#unless noContent}}
2 | {{link-to item.attributes.title linkTo itemPath click=(action "onClick")}}
3 | {{else}}
4 | {{item.attributes.title}}
5 | {{/unless}}
6 |
7 | {{#if item.attributes.fragmentIdLinks}}
8 |
]*>)?[\n\s]?]*)>/gi, (match, pre, codeClass) => {
9 | return pre ?
10 | `` :
11 | ` `;
12 | });
13 | }
14 | }];
15 | });
16 | }
17 |
18 | export default {
19 | name: 'register-showdown-extensions',
20 | initialize
21 | };
22 |
--------------------------------------------------------------------------------
/tests/dummy/app/instance-initializers/head-data.js:
--------------------------------------------------------------------------------
1 | import { get, set, setProperties } from '@ember/object';
2 | import { assign } from '@ember/polyfills';
3 | import Route from '@ember/routing/route';
4 | import Router from '@ember/routing/router';
5 | import { inject } from '@ember/service';
6 | import { typeOf } from '@ember/utils';
7 |
8 |
9 | export function initialize() {
10 |
11 | Router.reopen({
12 | headData: inject(),
13 | setTitle(title) { set(get(this, 'headData'), 'title', title); }
14 | });
15 |
16 | Route.reopen({
17 | headData: inject(),
18 | afterModel(model) {
19 | this._super(...arguments);
20 | if (typeOf(this.metadata) === 'function') {
21 | const metadata = this.metadata(model);
22 | const url = get(this, 'routeURL');
23 | setProperties(get(this, 'headData'), assign(metadata, { url }));
24 | }
25 | }
26 | });
27 |
28 | }
29 |
30 | export default {
31 | name: 'head-data',
32 | initialize
33 | };
34 |
--------------------------------------------------------------------------------
/tests/dummy/app/instance-initializers/inject-config.js:
--------------------------------------------------------------------------------
1 | import Component from '@ember/component';
2 | import Controller from '@ember/controller';
3 | import { computed } from '@ember/object';
4 | import Mixin from '@ember/object/mixin';
5 | import Route from '@ember/routing/route';
6 | import ENV from 'dummy/config/environment';
7 |
8 | const { rootURL } = ENV;
9 |
10 | export function initialize(appInstance) {
11 | let fastbootService = appInstance.lookup('service:fastboot');
12 | let isFastBoot = fastbootService && fastbootService.get('isFastBoot');
13 |
14 | let baseURL;
15 |
16 | if (isFastBoot) {
17 | let protocol = fastbootService.get('request.protocol');
18 | let host = fastbootService.get('request.host');
19 | baseURL = `${protocol}://${host}`;
20 |
21 | } else {
22 | let pathArray = window.location.href.split('/');
23 | baseURL = `${pathArray[0]}//${pathArray[2]}`;
24 |
25 | }
26 |
27 | let URLMixin = Mixin.create({
28 | baseURL, rootURL
29 | });
30 |
31 | let RouteURLMixin = Mixin.create({
32 | routeURL: computed(function() {
33 | return isFastBoot ?
34 | `${baseURL}${rootURL}${fastbootService.get('request.path')}` :
35 | window.location.href;
36 | })
37 |
38 | });
39 |
40 | Component.reopen(URLMixin);
41 | Controller.reopen(URLMixin);
42 | Route.reopen(URLMixin, RouteURLMixin);
43 |
44 | }
45 |
46 | export default {
47 | name: 'urls',
48 | initialize
49 | };
50 |
--------------------------------------------------------------------------------
/tests/dummy/app/mixins/ui/align-mixin.js:
--------------------------------------------------------------------------------
1 | import Mixin from '@ember/object/mixin';
2 |
3 | import propertyClassNameBinding from 'dummy/utils/property-class-name-binding';
4 |
5 | export default Mixin.create({
6 |
7 | classNameBindings: ['_align'],
8 |
9 | align: false,
10 | _align: propertyClassNameBinding('align')
11 |
12 | });
13 |
--------------------------------------------------------------------------------
/tests/dummy/app/mixins/ui/color-mixin.js:
--------------------------------------------------------------------------------
1 | import Mixin from '@ember/object/mixin';
2 |
3 | import propertyClassNameBinding from 'dummy/utils/property-class-name-binding';
4 |
5 | export default Mixin.create({
6 |
7 | classNameBindings: ['_bg', '_bgHover', '_color', '_colorHover'],
8 |
9 | bg: false,
10 | _bg: propertyClassNameBinding('bg'),
11 |
12 | bgHover: false,
13 | _bgHover: propertyClassNameBinding('bgHover'),
14 |
15 | color: false,
16 | _color: propertyClassNameBinding('color'),
17 |
18 | colorHover: false,
19 | _colorHover: propertyClassNameBinding('colorHover')
20 |
21 | });
22 |
--------------------------------------------------------------------------------
/tests/dummy/app/mixins/ui/depth-mixin.js:
--------------------------------------------------------------------------------
1 | import Mixin from '@ember/object/mixin';
2 |
3 | import propertyClassNameBinding from 'dummy/utils/property-class-name-binding';
4 |
5 | export default Mixin.create({
6 |
7 | classNameBindings: ['_depth'],
8 |
9 | depth: false,
10 | _depth: propertyClassNameBinding('depth')
11 |
12 | });
13 |
--------------------------------------------------------------------------------
/tests/dummy/app/mixins/ui/font-size-mixin.js:
--------------------------------------------------------------------------------
1 | import Mixin from '@ember/object/mixin';
2 |
3 | import propertyClassNameBinding from 'dummy/utils/property-class-name-binding';
4 |
5 | export default Mixin.create({
6 |
7 | classNameBindings: ['_fontSize'],
8 |
9 | fontSize: false,
10 | _fontSize: propertyClassNameBinding('fontSize')
11 |
12 | });
13 |
--------------------------------------------------------------------------------
/tests/dummy/app/mixins/ui/padding-mixin.js:
--------------------------------------------------------------------------------
1 | import Mixin from '@ember/object/mixin';
2 |
3 | import propertyClassNameBinding from 'dummy/utils/property-class-name-binding';
4 |
5 | export default Mixin.create({
6 |
7 | classNameBindings: ['_padding'],
8 |
9 | padding: false,
10 | _padding: propertyClassNameBinding('padding', {
11 | values: ['top', 'right', 'bottom', 'left']
12 | })
13 |
14 | });
15 |
--------------------------------------------------------------------------------
/tests/dummy/app/mixins/ui/size-mixin.js:
--------------------------------------------------------------------------------
1 | import Mixin from '@ember/object/mixin';
2 |
3 | import propertyClassNameBinding from 'dummy/utils/property-class-name-binding';
4 |
5 | export default Mixin.create({
6 |
7 | classNameBindings: ['_size'],
8 |
9 | size: false,
10 | _size: propertyClassNameBinding('size')
11 |
12 | });
13 |
--------------------------------------------------------------------------------
/tests/dummy/app/models/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willviles/ember-cli-markdown-resolver/46e56e04d3bf9508f56e7844030f865f7e0fd788/tests/dummy/app/models/.gitkeep
--------------------------------------------------------------------------------
/tests/dummy/app/resolver.js:
--------------------------------------------------------------------------------
1 | import Resolver from 'ember-resolver';
2 |
3 | export default Resolver;
4 |
--------------------------------------------------------------------------------
/tests/dummy/app/router.js:
--------------------------------------------------------------------------------
1 | import EmberRouter from '@ember/routing/router';
2 | import config from './config/environment';
3 |
4 | const Router = EmberRouter.extend({
5 | location: config.locationType,
6 | rootURL: config.rootURL
7 | });
8 |
9 | Router.map(function() {
10 | this.route('guides', function() {
11 | this.route('single', { path: '/*path' });
12 | });
13 |
14 | this.route('error', { path: '/*type' });
15 | });
16 |
17 | export default Router;
18 |
--------------------------------------------------------------------------------
/tests/dummy/app/routes/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willviles/ember-cli-markdown-resolver/46e56e04d3bf9508f56e7844030f865f7e0fd788/tests/dummy/app/routes/.gitkeep
--------------------------------------------------------------------------------
/tests/dummy/app/routes/application.js:
--------------------------------------------------------------------------------
1 | import Route from '@ember/routing/route';
2 | import { getProperties } from '@ember/object';
3 |
4 | export default Route.extend({
5 | title(tokens) {
6 | return tokens.length ?
7 | `${tokens.join(' – ')} – Ember CLI Markdown Resolver` :
8 | 'Ember CLI Markdown Resolver';
9 | },
10 |
11 | metadata() {
12 | let { baseURL, rootURL } = getProperties(this, 'baseURL', 'rootURL');
13 | return {
14 | appName: `Ember CLI Markdown Resolver`,
15 | description: `The quickest way to include static markdown content in your Ember.js application. Ember CLI Markdown Resolver is an addon for resolving markdown files in custom folders and retrieving content via a service.`,
16 | keywords: `ember.js, ember-addon, markdown, md, resolver, frontmatter, content`,
17 | image: `${baseURL}${rootURL}images/facebook.jpg`,
18 | favicon: `${baseURL}${rootURL}images/favicon`
19 | };
20 | },
21 | })
22 |
--------------------------------------------------------------------------------
/tests/dummy/app/routes/guides.js:
--------------------------------------------------------------------------------
1 | import Route from '@ember/routing/route';
2 | import { get } from '@ember/object';
3 | import { inject } from '@ember/service';
4 | import RSVP from 'rsvp';
5 |
6 | const { hash } = RSVP;
7 |
8 | export default Route.extend({
9 |
10 | titleToken: 'Guides',
11 |
12 | markdownResolver: inject(),
13 |
14 | model() {
15 | return hash({
16 | tree: get(this, 'markdownResolver').tree('guides')
17 | });
18 | },
19 |
20 | setupController(controller, model) {
21 | controller.setProperties(model);
22 | }
23 |
24 | });
25 |
--------------------------------------------------------------------------------
/tests/dummy/app/routes/guides/index.js:
--------------------------------------------------------------------------------
1 | import Route from '@ember/routing/route';
2 | import { get } from '@ember/object';
3 | import { inject } from '@ember/service';
4 | import RSVP from 'rsvp';
5 |
6 | const { hash } = RSVP;
7 |
8 | export default Route.extend({
9 |
10 | titleToken: 'Introduction',
11 |
12 | templateName: 'guides.single',
13 |
14 | markdownResolver: inject(),
15 |
16 | model() {
17 | return hash({
18 | guide: get(this, 'markdownResolver').file('guides', 'index')
19 | });
20 | },
21 |
22 | setupController(controller, model) {
23 | controller.setProperties(model);
24 | }
25 |
26 | });
27 |
--------------------------------------------------------------------------------
/tests/dummy/app/routes/guides/single.js:
--------------------------------------------------------------------------------
1 | import Route from '@ember/routing/route';
2 | import { get } from '@ember/object';
3 | import { inject } from '@ember/service';
4 | import RSVP from 'rsvp';
5 |
6 | const { hash } = RSVP;
7 |
8 | export default Route.extend({
9 |
10 | titleToken({ guide }) {
11 | return get(guide, 'attributes.title');
12 | },
13 |
14 | markdownResolver: inject(),
15 |
16 | model({ path }) {
17 | return hash({
18 | guide: get(this, 'markdownResolver').file('guides', path)
19 | });
20 | },
21 |
22 | afterModel({ guide }) {
23 | if (!guide) {
24 | this.transitionTo('error', { type: '404' });
25 | }
26 | },
27 |
28 | setupController(controller, model) {
29 | controller.setProperties(model);
30 | }
31 |
32 | });
33 |
--------------------------------------------------------------------------------
/tests/dummy/app/styles/app.scss:
--------------------------------------------------------------------------------
1 | @import 'framework/reset';
2 | @import 'framework/mixins';
3 | @import 'sassdash';
4 |
5 | @import 'main/config';
6 | @import 'components/config';
7 |
8 | @import 'framework/grid';
9 | @import 'framework/fonts';
10 | @import 'framework/type';
11 | @import 'framework/colors';
12 | @import 'framework/utility';
13 |
14 | @import 'components/_';
15 | @import 'main/_';
16 | @import 'routes/_';
17 |
--------------------------------------------------------------------------------
/tests/dummy/app/styles/components/_.scss:
--------------------------------------------------------------------------------
1 | @import 'buttons/_';
2 | @import 'footer/_';
3 | @import 'markdown/_';
4 | @import 'navbar/_';
5 | @import 'sections/_';
6 |
--------------------------------------------------------------------------------
/tests/dummy/app/styles/components/_config.scss:
--------------------------------------------------------------------------------
1 | // Components config
2 |
3 | $--navbar: (
4 | height: (50px, 50px, 60px, 70px, 90px),
5 | background-color: _get($--colors, 'black'),
6 | color: _get($--colors, 'white'),
7 | item-horiz-padding: (.5rem, .5rem, .66rem, .75rem, .9rem),
8 | fixed: false
9 | );
10 |
11 | $--buttons: (
12 | font-size: (.7rem, 1rem, 1.2rem, 1.5rem, 2rem),
13 | padding: (.5rem, .75rem, 1rem, 2rem, 3rem),
14 | padding-horiz-ratio: 1.5,
15 | line-height: (160%, 150%, 140%, 130%, 120%),
16 | border-radius: .25rem,
17 | disabled-bg: rgba(_get($--colors, 'lt-gray'), .33),
18 | disabled-color: rgba(_get($--colors, 'black'), .5)
19 | );
20 |
21 | $--sections: (
22 | font-size: (.7rem, .9rem, 1rem, 1.1rem, 1.2rem),
23 | padding: (3rem, 5rem, 7rem, 10rem, 20rem)
24 | );
25 |
--------------------------------------------------------------------------------
/tests/dummy/app/styles/components/buttons/_.scss:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------
2 |
3 | // Buttons
4 | //
5 |
6 | button {
7 | border: none;
8 | padding: 0 0 0 0;
9 | background-color: transparent;
10 | cursor: pointer;
11 | color: inherit;
12 | font-size: 100%;
13 | font-family: inherit;
14 | font-style: inherit;
15 |
16 | &:focus { outline: 0; }
17 | &.active {
18 | font-weight: bold;
19 | text-decoration: underline;
20 | }
21 |
22 | }
23 |
24 | .button {
25 | display: inline-flex;
26 | align-items: center;
27 | cursor: pointer;
28 | justify-content: center;
29 |
30 | &.align-left { justify-content: left; }
31 | &.align-right { justify-content: right; }
32 |
33 | &.rounded {
34 | border-radius: _get($--buttons, 'border-radius');
35 | }
36 |
37 | &:not(.inline) {
38 | display: flex;
39 | width: 100%;
40 | box-sizing: border-box;
41 | }
42 |
43 | &.transparent {
44 | background-color: rgba(white, 0);
45 | color: inherit !important;
46 | }
47 |
48 | @for $i from 1 through length(_get($--grid, 'breakpoints')) {
49 | $breakpoints: _keys(_get($--grid, 'breakpoints'));
50 | $breakpoint: nth($breakpoints, $i);
51 |
52 | line-height: nth(_get($--buttons, 'line-height'), $i);
53 |
54 | &.padding-#{$breakpoint} {
55 | $padding: nth(_get($--buttons, 'padding'), $i);
56 | $horiz-ratio: _get($--buttons, 'padding-horiz-ratio');
57 | padding: $padding #{$padding * $horiz-ratio};
58 | }
59 |
60 | &.font-size-#{$breakpoint} {
61 | $font-size: nth(_get($--buttons, 'font-size'), $i);
62 | font-size: $font-size;
63 | }
64 | }
65 |
66 | @each $name, $hex in $--colors {
67 | &.bg-#{$name}:not([class*=' bg-hover']):not(:disabled) {
68 | &:hover { background-color: darken($hex, 5%) !important; }
69 | }
70 | }
71 |
72 | &:disabled {
73 | background-color: _get($--buttons, 'disabled-bg') !important;
74 | color: _get($--buttons, 'disabled-color') !important;
75 | cursor: auto !important;
76 | }
77 |
78 | &.pending {
79 | background-color: _get($--buttons, 'pending-bg') !important;
80 | color: _get($--buttons, 'pending-color') !important;
81 | cursor: auto;
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/tests/dummy/app/styles/components/footer/_.scss:
--------------------------------------------------------------------------------
1 | footer {
2 | padding: 1rem 0 2rem 0;
3 | ul {
4 | li {
5 | display: inline-block;
6 | font-size: _get($--type, 'small');
7 | margin: .5em .5em;
8 | & > a {
9 | &.active, &:hover {
10 | @include set-font('header');
11 | }
12 | &.active {
13 | text-decoration: underline;
14 | }
15 | }
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/tests/dummy/app/styles/components/markdown/_.scss:
--------------------------------------------------------------------------------
1 | @import 'menu';
2 | @import 'prettyprint';
3 |
4 | article, .markdown-content {
5 | h1, h2, h3, h4, h5, h6 {
6 | @include set-font('header');
7 | margin-bottom: 1em;
8 | }
9 | p {
10 | a {
11 | @include set-font('header');
12 | &:hover {
13 | text-decoration: underline;
14 | }
15 | }
16 | }
17 | .codelink {
18 | display: block;
19 | background: _get($--colors, 'lt-gray');
20 | color: inherit;
21 | padding: .2em .5em;
22 | border-radius: .25rem;
23 | white-space: nowrap;
24 | overflow-x: scroll;
25 | a {
26 | font-size: .8em;
27 | }
28 | }
29 | & > ul, & > ol {
30 | @include media-breakpoint-up('sm') {
31 | padding-left: _get($--grid, 'margin');
32 | padding-right: _get($--grid, 'margin');
33 | }
34 | }
35 | ul, ol {
36 | font-size: 1.2rem;
37 | ul, ol {
38 | margin-left: 2rem;
39 | font-size: 0.8em;
40 | }
41 | li {
42 | line-height: 2em;
43 | list-style-position: inside;
44 | & > p {
45 | display: inline-block;
46 | font-size: inherit;
47 | }
48 | }
49 | }
50 | ol {
51 | li {
52 | list-style-type: decimal-leading-zero;
53 | list-style-position: inside;
54 | }
55 | }
56 | ul {
57 | li {
58 | &:not(.task-list-item) {
59 | list-style-type: circle;
60 | }
61 | &.task-list-item {
62 | [type="checkbox"] {
63 | margin-right: 1em;
64 | }
65 | }
66 | }
67 | }
68 | pre {
69 | & > ul, & > ol {
70 | font-size: 1rem;
71 | li {
72 | line-height: 1.5em;
73 | }
74 | }
75 | }
76 | blockquote {
77 | position: relative;
78 | margin-bottom: 3rem;
79 | padding-bottom: 2rem;
80 | p {
81 | font-size: 1.33em;
82 | }
83 | &:before {
84 | content: '“';
85 | font-size: 4em;
86 | opacity: .5;
87 | }
88 | &:after {
89 | content: '';
90 | position: absolute;
91 | top: 100%; left: 0;
92 | height: 3px; width: 4em;
93 | background-color: rgba(_get($--colors, 'black'), 0.33);
94 | }
95 | p {
96 | margin-top: -1em;
97 | }
98 | @include media-breakpoint-up('md') {
99 | margin-left: -#{_get($--grid, 'margin')};
100 | margin-right: -#{_get($--grid, 'margin')};
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/tests/dummy/app/styles/components/markdown/_menu.scss:
--------------------------------------------------------------------------------
1 | .markdown-menu {
2 | .markdown-menu-title {
3 | font-weight: 800;
4 | font-size: 1.1em;
5 | text-transform: capitalize;
6 | margin-bottom: .75em;
7 | }
8 | & > ul {
9 | a {
10 | padding: .5em 0;
11 | &[href] {
12 | &:hover {
13 | font-weight: 800;
14 | }
15 | &.active {
16 | color: _get($--colors, 'red');
17 | font-weight: 800;
18 | }
19 | }
20 | &:not([href]):focus {
21 | outline: 0;
22 | }
23 | }
24 | ul {
25 | margin-left: 1em;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tests/dummy/app/styles/components/markdown/_prettyprint.scss:
--------------------------------------------------------------------------------
1 | .prettyprint {
2 |
3 | @at-root pre#{&} {
4 | background: _get($--colors, 'gray');
5 | color: _get($--colors, 'white');
6 | margin: 0 0 2em 0;
7 | padding: 1em;
8 | }
9 |
10 | @at-root code#{&} {
11 | background: _get($--colors, 'lt-gray');
12 | color: inherit;
13 | padding: .2em .5em;
14 | }
15 |
16 | font-family: Menlo, Monaco, Consolas, monospace;
17 | border: 0 !important;
18 | border-radius: .25rem;
19 | overflow-x: scroll;
20 |
21 | li {
22 | padding-left: .5em;
23 | padding-right: .5em;
24 | line-height: 1.5em;
25 | // &.L4, &.L9 {
26 | // list-style-type: none !important;
27 | // }
28 | }
29 |
30 | // Hide the text until it's prettyprinted
31 | &:not(.prettyprinted) {
32 | & > code {
33 | visibility: hidden;
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/tests/dummy/app/styles/components/navbar/_.scss:
--------------------------------------------------------------------------------
1 | .navbar, .navbar > .container {
2 | display: flex;
3 | align-items: stretch;
4 | }
5 |
6 | .navbar {
7 |
8 | &:not(.unfixed) {
9 | position: fixed;
10 | z-index: 60;
11 | top: 0; left: 0; width: 100%;
12 | }
13 |
14 | background-color: _get($--navbar, 'background-color');
15 | color: _get($--navbar, 'color');
16 |
17 | @for $i from length(_get($--grid, 'breakpoints'))*-1 through -1 {
18 | $breakpoints: _keys(_get($--grid, 'breakpoints'));
19 | $breakpoint: nth($breakpoints, abs($i));
20 | @include media-breakpoint-down($breakpoint) {
21 | height: nth(_get($--navbar, 'height'), abs($i));
22 | }
23 | }
24 |
25 | & > .container {
26 | flex-grow: 1;
27 | }
28 | .navbar-content {
29 | display: flex;
30 | flex-grow: 1;
31 | & > * {
32 | display: flex;
33 | align-items: stretch;
34 | }
35 | .left, .right, .center {
36 | flex-grow: 1;
37 | & > * {
38 | display: inline-flex;
39 | }
40 | a {
41 | display: inline-flex;
42 | align-items: center;
43 | &.active {
44 | text-decoration: underline;
45 | @include set-font('header');
46 | }
47 | }
48 | ul li {
49 | display: inline-flex;
50 | align-items: stretch;
51 | a {
52 | @for $i from 1 through length(_get($--grid, 'breakpoints')) {
53 | $breakpoints: _keys(_get($--grid, 'breakpoints'));
54 | $breakpoint: nth($breakpoints, $i);
55 | @include media-breakpoint-down($breakpoint) {
56 | padding-left: nth(_get($--navbar, 'item-horiz-padding'), $i);
57 | padding-right: nth(_get($--navbar, 'item-horiz-padding'), $i);
58 | }
59 | }
60 | }
61 | }
62 | }
63 | .left {
64 | justify-content: flex-start;
65 | @include media-breakpoint-down('sm') {
66 | flex-basis: 100%;
67 | // justify-content: center;
68 | }
69 | }
70 | .center {
71 | justify-content: center;
72 | }
73 | .right {
74 | justify-content: flex-end;
75 | }
76 | // Custom components
77 | .unauthenticated {
78 | a {
79 | display: inline-flex;
80 | align-items: center;
81 | padding-left: .3em;
82 | padding-right: .3em;
83 | }
84 | & > span {
85 | align-self: center;
86 | }
87 | }
88 | .logo {
89 | @include media-breakpoint-down('sm') {
90 | flex-grow: 1;
91 | }
92 | img {
93 | max-height: 33%;
94 | @include media-breakpoint-down('lg') {
95 | max-height: 45%;
96 | }
97 | @include media-breakpoint-down('sm') {
98 | margin: auto;
99 | max-height: 66%;
100 | }
101 | }
102 | }
103 | .burger {
104 | font-size: 2rem;
105 | padding: 0 _get($--grid, 'gutter');
106 | &.left {
107 | margin-left: -#{_get($--grid, 'margin')};
108 | padding-left: _get($--grid, 'margin');
109 | }
110 | &:not(.left) {
111 | margin-right: -#{_get($--grid, 'margin')};
112 | padding-right: _get($--grid, 'margin');
113 | }
114 | }
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/tests/dummy/app/styles/components/sections/_.scss:
--------------------------------------------------------------------------------
1 | .section {
2 | @for $i from 1 through length(_get($--grid, 'breakpoints')) {
3 | $breakpoints: _keys(_get($--grid, 'breakpoints'));
4 | $breakpoint: nth($breakpoints, $i);
5 | $padding: nth(_get($--sections, 'padding'), $i);
6 |
7 | &.padding-#{$breakpoint}, &.padding-top-#{$breakpoint} {
8 | padding-top: $padding;
9 |
10 | @include media-breakpoint-down('lg') {
11 | padding-top: $padding * 0.8;
12 | }
13 |
14 | @include media-breakpoint-down('md') {
15 | padding-top: $padding * 0.6;
16 | }
17 |
18 | @include media-breakpoint-down('sm') {
19 | padding-top: $padding * 0.4;
20 | }
21 |
22 | @include media-breakpoint-down('xs') {
23 | padding-top: _get($--grid, 'gutter') * 2;
24 | }
25 | }
26 |
27 | &.padding-#{$breakpoint}, &.padding-bottom-#{$breakpoint} {
28 | padding-bottom: $padding;
29 |
30 | @include media-breakpoint-down('lg') {
31 | padding-bottom: $padding * 0.8;
32 | }
33 |
34 | @include media-breakpoint-down('md') {
35 | padding-bottom: $padding * 0.6;
36 | }
37 |
38 | @include media-breakpoint-down('sm') {
39 | padding-bottom: $padding * 0.4;
40 | }
41 |
42 | @include media-breakpoint-down('xs') {
43 | padding-bottom: _get($--grid, 'gutter') * 2;
44 | }
45 | }
46 |
47 | &.font-size-#{$breakpoint} {
48 | $font-size: nth(_get($--sections, 'font-size'), $i);
49 | font-size: $font-size;
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/tests/dummy/app/styles/framework/_colors.scss:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------
2 |
3 | // Colors
4 | //
5 |
6 | @each $name, $hex in $--colors {
7 | // Give each color a unique color class
8 | .color-#{$name} { color: $hex !important; }
9 | // Give each color a unique bg class
10 | .bg-#{$name} { background-color: $hex !important; }
11 | // Give each color a unique bg hover class
12 | .bg-hover-#{$name}:hover { background-color: $hex !important; }
13 | // Give each color a unique color hover class
14 | .color-hover-#{$name}:hover { color: $hex !important; }
15 | }
16 |
--------------------------------------------------------------------------------
/tests/dummy/app/styles/framework/_fonts.scss:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------
2 |
3 | // Fonts
4 | //
5 |
6 | // Give each font style a class
7 | @each $name, $styles in $--font-styles {
8 | .font-#{$name} { @include set-font($name); }
9 | }
10 |
--------------------------------------------------------------------------------
/tests/dummy/app/styles/framework/_grid.scss:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------
2 |
3 | // Grid
4 | //
5 |
6 | $grid-columns: _get($--grid, 'columns') !default;
7 | $gutter-width: _get($--grid, 'gutter') !default;
8 | $outer-margin: _get($--grid, 'margin') !default;
9 | $breakpoints: _get($--grid, 'breakpoints') !default;
10 | $flexboxgrid-max-width: _get($--grid, 'max-width') !default;
11 |
12 | $gutter-compensation: $gutter-width * .5 * -1;
13 | $half-gutter-width: $gutter-width * .5;
14 |
15 | .flex {
16 | display: flex;
17 | }
18 |
19 | .inline-flex {
20 | display: inline-flex;
21 | }
22 |
23 | .wrapper {
24 | box-sizing: border-box;
25 | max-width: $flexboxgrid-max-width;
26 | margin: 0 auto;
27 | }
28 |
29 | .container, .container-fluid {
30 | margin-right: auto;
31 | margin-left: auto;
32 | padding-right: $outer-margin;
33 | padding-left: $outer-margin;
34 | }
35 |
36 | .row, .row-fluid {
37 | box-sizing: border-box;
38 | @include flexbox();
39 | @include flex(0, 1, auto);
40 | @include flex-direction(row);
41 | @include flex-wrap(wrap);
42 | }
43 |
44 | .row {
45 | margin-right: $gutter-compensation;
46 | margin-left: $gutter-compensation;
47 | }
48 |
49 | .row.reverse {
50 | @include flex-direction(row-reverse);
51 | }
52 |
53 | .col.reverse {
54 | @include flex-direction(column-reverse);
55 | }
56 |
57 | @mixin flexboxgrid-sass-col-common {
58 | box-sizing: border-box;
59 |
60 | // split @include flex(0, 0, auto) into individual props
61 | @include flex-grow(0);
62 | @include flex-shrink(0);
63 |
64 | // we leave @include flex-basis(auto) out of common because
65 | // in some spots we need it and some we dont
66 | // more why here: https://github.com/kristoferjoseph/flexboxgrid/issues/126
67 |
68 | padding-right: $half-gutter-width;
69 | padding-left: $half-gutter-width;
70 | }
71 |
72 | @each $value in $breakpoints {
73 |
74 | $name: nth($value, 1);
75 | $breakpoint: nth($value, 2);
76 |
77 | // If is smallest breakpoint
78 | @if index(map-keys($breakpoints), $name) == 1 {
79 |
80 | .col-#{$name} {
81 | @include flexboxgrid-sass-col-common;
82 | @include flex-basis(auto);
83 | }
84 | @for $i from 1 through $grid-columns {
85 | .col.#{$name}#{$i} {
86 | @include flexboxgrid-sass-col-common;
87 | @include flex-basis(100% / $grid-columns * $i);
88 | max-width: 100% / $grid-columns * $i;
89 | }
90 | }
91 | @for $i from 0 through $grid-columns {
92 | .col.offset-#{$name}#{$i} {
93 | @include flexboxgrid-sass-col-common;
94 | @if $i == 0 {
95 | margin-left: 0;
96 | } @else {
97 | margin-left: 100% / $grid-columns * $i;
98 | }
99 | }
100 | }
101 | .col.#{$name} {
102 | @include flex-grow(1);
103 | @include flex-basis(0);
104 | max-width: 100%;
105 | margin-left: _get($--grid, 'gutter') / 2;
106 | margin-right: _get($--grid, 'gutter') / 2;
107 | }
108 | .start-#{$name} {
109 | @include justify-content(flex-start);
110 | text-align: start;
111 | }
112 |
113 | .center-#{$name} {
114 | @include justify-content(center);
115 | text-align: center;
116 | }
117 |
118 | .end-#{$name} {
119 | @include justify-content(flex-end);
120 | text-align: end;
121 | }
122 |
123 | .top-#{$name} {
124 | @include align-items(flex-start);
125 | }
126 |
127 | .middle-#{$name} {
128 | @include align-items(center);
129 | }
130 |
131 | .bottom-#{$name} {
132 | @include align-items(flex-end);
133 | }
134 |
135 | .stretch-#{name} {
136 | @include align-items(stretch);
137 | }
138 |
139 | .around-#{$name} {
140 | @include justify-content(space-around);
141 | }
142 |
143 | .between-#{$name} {
144 | @include justify-content(space-between);
145 | }
146 |
147 | .first-#{$name} {
148 | order: -1;
149 | }
150 |
151 | .last-#{$name} {
152 | order: 1;
153 | }
154 |
155 | // Otherwise, let's use
156 |
157 | } @else {
158 |
159 | $size: nth($breakpoint, 1);
160 | $container: nth($breakpoint, 2);
161 |
162 | @include media-breakpoint-up($name) {
163 | .container {
164 | max-width: $container;
165 | }
166 |
167 | .col.#{$name} {
168 | @include flexboxgrid-sass-col-common;
169 | @include flex-basis(auto);
170 | }
171 | @for $i from 1 through $grid-columns {
172 | .col.#{$name}#{$i} {
173 | @include flexboxgrid-sass-col-common;
174 | @include flex-basis(100% / $grid-columns * $i);
175 | max-width: 100% / $grid-columns * $i;
176 | }
177 | }
178 | @for $i from 0 through $grid-columns {
179 | .col.offset-#{$name}#{$i} {
180 | @include flexboxgrid-sass-col-common;
181 | @if $i == 0 {
182 | margin-left: 0;
183 | } @else {
184 | margin-left: 100% / $grid-columns * $i;
185 | }
186 | }
187 | }
188 | .col.#{$name} {
189 | @include flex-grow(1);
190 | @include flex-basis(0);
191 | max-width: 100%;
192 | }
193 | .start-#{$name} {
194 | @include justify-content(flex-start);
195 | text-align: start;
196 | }
197 |
198 | .center-#{$name} {
199 | @include justify-content(center);
200 | text-align: center;
201 | }
202 |
203 | .end-#{$name} {
204 | @include justify-content(flex-end);
205 | text-align: end;
206 | }
207 |
208 | .top-#{$name} {
209 | @include align-items(flex-start);
210 | }
211 |
212 | .middle-#{$name} {
213 | @include align-items(center);
214 | }
215 |
216 | .bottom-#{$name} {
217 | @include align-items(flex-end);
218 | }
219 |
220 | .around-#{$name} {
221 | @include justify-content(space-around);
222 | }
223 |
224 | .between-#{$name} {
225 | @include justify-content(space-between);
226 | }
227 |
228 | .first-#{$name} {
229 | order: -1;
230 | }
231 |
232 | .last-#{$name} {
233 | order: 1;
234 | }
235 | }
236 | }
237 | }
238 |
239 | //----------------------------------------------------------------------
240 |
241 | // Responsive classes
242 | //
243 | // Hide elements responsively using classes.
244 |
245 | @each $name, $value in _get($--grid, 'breakpoints') {
246 |
247 | .hide-#{$name} {
248 | @include media-breakpoint-only($name) {
249 | display: none !important;
250 | }
251 | }
252 |
253 | .hide-#{$name}-up {
254 | @include media-breakpoint-up($name) {
255 | display: none !important;
256 | }
257 | }
258 | .hide-#{$name}-down {
259 | @include media-breakpoint-down($name) {
260 | display: none !important;
261 | }
262 | }
263 |
264 | }
265 |
--------------------------------------------------------------------------------
/tests/dummy/app/styles/framework/_mixins.scss:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------
2 |
3 | // Map Reverse
4 | //
5 | // Reverse the order of a sass map.
6 | //
7 | // values: Sass Map
8 |
9 | @function _map-reverse($map) {
10 | $result: null;
11 |
12 | @if type-of($map) == "map" {
13 | $keys: map-keys($map);
14 | $map-reversed: ();
15 |
16 | @for $i from length($keys) through 1 {
17 | $map-reversed: map-merge(
18 | $map-reversed,
19 | (nth($keys, $i): _get($map, nth($keys, $i)))
20 | );
21 | }
22 |
23 | @if type-of($map-reversed) == "map" {
24 | $result: $map-reversed;
25 | } @else {
26 | @warn 'There was an error reversing the order of "#{$map}"';
27 | }
28 | } @else {
29 | @warn '"#{$map}" is not a valid map';
30 | }
31 |
32 | @return $result;
33 | }
34 |
35 | //----------------------------------------------------------------------
36 |
37 | // Background
38 | //
39 | // Adds a background
40 | //
41 | // Values: file, width, height, position
42 | // Default: row
43 | //
44 | // @include bg('image.jpg' 1440px 900px center);
45 |
46 | @mixin bg($values) {
47 | $file: nth($values, 1);
48 | $width: nth($values, 2);
49 | $height: nth($values, 3);
50 | $position: nth($values, 4);
51 |
52 | background-image: url($file);
53 | background-repeat: no-repeat;
54 | background-position: $position;
55 | background-size: $width $height;
56 | }
57 |
58 | //----------------------------------------------------------------------
59 |
60 | // Retina Background
61 | //
62 | // Adds a retina background
63 | //
64 | // Values: file, width, type height, position
65 | // Default: row
66 | //
67 | // @include bg2x('image' 'jpg' 1440px 900px center);
68 |
69 | @mixin bg2x($values) {
70 | $file: nth($values, 1);
71 | $extension: nth($values, 2);
72 | $width: nth($values, 3);
73 | $height: nth($values, 4);
74 | $position: nth($values, 5);
75 |
76 | background-image: url($file + '.' + $extension);
77 | background-repeat: no-repeat;
78 | background-position: $position;
79 | @media (min-resolution: 2dppx) {
80 | & {
81 | background-image: url($file + '@2x.' + $extension);
82 | background-size: $width $height;
83 | }
84 | }
85 | }
86 |
87 | //----------------------------------------------------------------------
88 |
89 | // Flexbox Containers
90 | //
91 | // The 'flex' value causes an element to generate a block-level flex
92 | // container box.
93 | //
94 | // The 'inline-flex' value causes an element to generate a inline-level
95 | // flex container box.
96 | //
97 | // display: flex | inline-flex
98 | //
99 | // http://w3.org/tr/css3-flexbox/#flex-containers
100 | //
101 | // (Placeholder selectors for each type, for those who rather @extend)
102 |
103 | @mixin flexbox {
104 | display: -webkit-box;
105 | display: -webkit-flex;
106 | display: -moz-flex;
107 | display: -ms-flexbox;
108 | display: flex;
109 | }
110 |
111 | %flexbox { @include flexbox; }
112 |
113 | //----------------------------------
114 |
115 | @mixin inline-flex {
116 | display: -webkit-inline-box;
117 | display: -webkit-inline-flex;
118 | display: -moz-inline-flex;
119 | display: -ms-inline-flexbox;
120 | display: inline-flex;
121 | }
122 |
123 | %inline-flex { @include inline-flex; }
124 |
125 | //----------------------------------------------------------------------
126 |
127 | // Flexbox Direction
128 | //
129 | // The 'flex-direction' property specifies how flex items are placed in
130 | // the flex container, by setting the direction of the flex container's
131 | // main axis. This determines the direction that flex items are laid out in.
132 | //
133 | // Values: row | row-reverse | column | column-reverse
134 | // Default: row
135 | //
136 | // http://w3.org/tr/css3-flexbox/#flex-direction-property
137 |
138 | @mixin flex-direction($value: row) {
139 | @if $value == row-reverse {
140 | -webkit-box-direction: reverse;
141 | -webkit-box-orient: horizontal;
142 | } @else if $value == column {
143 | -webkit-box-direction: normal;
144 | -webkit-box-orient: vertical;
145 | } @else if $value == column-reverse {
146 | -webkit-box-direction: reverse;
147 | -webkit-box-orient: vertical;
148 | } @else {
149 | -webkit-box-direction: normal;
150 | -webkit-box-orient: horizontal;
151 | }
152 | -webkit-flex-direction: $value;
153 | -moz-flex-direction: $value;
154 | -ms-flex-direction: $value;
155 | flex-direction: $value;
156 | }
157 | // Shorter version:
158 | @mixin flex-dir($args...) { @include flex-direction($args...); }
159 |
160 | //----------------------------------------------------------------------
161 |
162 | // Flexbox Wrap
163 | //
164 | // The 'flex-wrap' property controls whether the flex container is single-line
165 | // or multi-line, and the direction of the cross-axis, which determines
166 | // the direction new lines are stacked in.
167 | //
168 | // Values: nowrap | wrap | wrap-reverse
169 | // Default: nowrap
170 | //
171 | // http://w3.org/tr/css3-flexbox/#flex-wrap-property
172 |
173 | @mixin flex-wrap($value: nowrap) {
174 | // No Webkit Box fallback.
175 | -webkit-flex-wrap: $value;
176 | -moz-flex-wrap: $value;
177 | @if $value == nowrap {
178 | -ms-flex-wrap: none;
179 | } @else {
180 | -ms-flex-wrap: $value;
181 | }
182 | flex-wrap: $value;
183 | }
184 |
185 | //----------------------------------------------------------------------
186 |
187 | // Flexbox Flow (shorthand)
188 | //
189 | // The 'flex-flow' property is a shorthand for setting the 'flex-direction'
190 | // and 'flex-wrap' properties, which together define the flex container's
191 | // main and cross axes.
192 | //
193 | // Values: |
194 | // Default: row nowrap
195 | //
196 | // http://w3.org/tr/css3-flexbox/#flex-flow-property
197 |
198 | @mixin flex-flow($values: (row nowrap)) {
199 | // No Webkit Box fallback.
200 | -webkit-flex-flow: $values;
201 | -moz-flex-flow: $values;
202 | -ms-flex-flow: $values;
203 | flex-flow: $values;
204 | }
205 |
206 | //----------------------------------------------------------------------
207 |
208 | // Flexbox Order
209 | //
210 | // The 'order' property controls the order in which flex items appear within
211 | // their flex container, by assigning them to ordinal groups.
212 | //
213 | // Default: 0
214 | //
215 | // http://w3.org/tr/css3-flexbox/#order-property
216 |
217 | @mixin order($int: 0) {
218 | -webkit-box-ordinal-group: $int + 1;
219 | -webkit-order: $int;
220 | -moz-order: $int;
221 | -ms-flex-order: $int;
222 | order: $int;
223 | }
224 |
225 | //----------------------------------------------------------------------
226 |
227 | // Flexbox Grow
228 | //
229 | // The 'flex-grow' property sets the flex grow factor. Negative numbers
230 | // are invalid.
231 | //
232 | // Default: 0
233 | //
234 | // http://w3.org/tr/css3-flexbox/#flex-grow-property
235 |
236 | @mixin flex-grow($int: 0) {
237 | -webkit-box-flex: $int;
238 | -webkit-flex-grow: $int;
239 | -moz-flex-grow: $int;
240 | -ms-flex-positive: $int;
241 | flex-grow: $int;
242 | }
243 |
244 | //----------------------------------------------------------------------
245 |
246 | // Flexbox Shrink
247 | //
248 | // The 'flex-shrink' property sets the flex shrink factor. Negative numbers
249 | // are invalid.
250 | //
251 | // Default: 1
252 | //
253 | // http://w3.org/tr/css3-flexbox/#flex-shrink-property
254 |
255 | @mixin flex-shrink($int: 1) {
256 | -webkit-flex-shrink: $int;
257 | -moz-flex-shrink: $int;
258 | -ms-flex-negative: $int;
259 | flex-shrink: $int;
260 | }
261 |
262 | //----------------------------------------------------------------------
263 |
264 | // Flexbox Basis
265 | //
266 | // The 'flex-basis' property sets the flex basis. Negative lengths are invalid.
267 | //
268 | // Values: Like "width"
269 | // Default: auto
270 | //
271 | // http://www.w3.org/TR/css3-flexbox/#flex-basis-property
272 |
273 | @mixin flex-basis($value: auto) {
274 | -webkit-flex-basis: $value;
275 | -moz-flex-basis: $value;
276 | -ms-flex-preferred-size: $value;
277 | flex-basis: $value;
278 | }
279 |
280 | //----------------------------------------------------------------------
281 |
282 | // Flexbox "Flex" (shorthand)
283 | //
284 | // The 'flex' property specifies the components of a flexible length: the
285 | // flex grow factor and flex shrink factor, and the flex basis. When an
286 | // element is a flex item, 'flex' is consulted instead of the main size
287 | // property to determine the main size of the element. If an element is
288 | // not a flex item, 'flex' has no effect.
289 | //
290 | // Values: none | ||
291 | // Default: See individual properties (1 1 0).
292 | //
293 | // http://w3.org/tr/css3-flexbox/#flex-property
294 |
295 | @mixin flex($fg: 1, $fs: null, $fb: null) {
296 |
297 | // Set a variable to be used by box-flex properties
298 | $fg-boxflex: $fg;
299 |
300 | // Box-Flex only supports a flex-grow value so let's grab the
301 | // first item in the list and just return that.
302 | @if type-of($fg) == 'list' {
303 | $fg-boxflex: nth($fg, 1);
304 | }
305 |
306 | -webkit-box-flex: $fg-boxflex;
307 | -webkit-flex: $fg $fs $fb;
308 | -moz-box-flex: $fg-boxflex;
309 | -moz-flex: $fg $fs $fb;
310 | -ms-flex: $fg $fs $fb;
311 | flex: $fg $fs $fb;
312 | }
313 |
314 | //----------------------------------------------------------------------
315 |
316 | // Flexbox Justify Content
317 | //
318 | // The 'justify-content' property aligns flex items along the main axis
319 | // of the current line of the flex container. This is done after any flexible
320 | // lengths and any auto margins have been resolved. Typically it helps distribute
321 | // extra free space leftover when either all the flex items on a line are
322 | // inflexible, or are flexible but have reached their maximum size. It also
323 | // exerts some control over the alignment of items when they overflow the line.
324 | //
325 | // Note: 'space-*' values not supported in older syntaxes.
326 | //
327 | // Values: flex-start | flex-end | center | space-between | space-around
328 | // Default: flex-start
329 | //
330 | // http://w3.org/tr/css3-flexbox/#justify-content-property
331 |
332 | @mixin justify-content($value: flex-start) {
333 | @if $value == flex-start {
334 | -webkit-box-pack: start;
335 | -ms-flex-pack: start;
336 | } @else if $value == flex-end {
337 | -webkit-box-pack: end;
338 | -ms-flex-pack: end;
339 | } @else if $value == space-between {
340 | -webkit-box-pack: justify;
341 | -ms-flex-pack: justify;
342 | } @else if $value == space-around {
343 | -ms-flex-pack: distribute;
344 | } @else {
345 | -webkit-box-pack: $value;
346 | -ms-flex-pack: $value;
347 | }
348 | -webkit-justify-content: $value;
349 | -moz-justify-content: $value;
350 | justify-content: $value;
351 | }
352 | // Shorter version:
353 | @mixin flex-just($args...) { @include justify-content($args...); }
354 |
355 | //----------------------------------------------------------------------
356 |
357 | // Flexbox Align Items
358 | //
359 | // Flex items can be aligned in the cross axis of the current line of the
360 | // flex container, similar to 'justify-content' but in the perpendicular
361 | // direction. 'align-items' sets the default alignment for all of the flex
362 | // container's items, including anonymous flex items. 'align-self' allows
363 | // this default alignment to be overridden for individual flex items. (For
364 | // anonymous flex items, 'align-self' always matches the value of 'align-items'
365 | // on their associated flex container.)
366 | //
367 | // Values: flex-start | flex-end | center | baseline | stretch
368 | // Default: stretch
369 | //
370 | // http://w3.org/tr/css3-flexbox/#align-items-property
371 |
372 | @mixin align-items($value: stretch) {
373 | @if $value == flex-start {
374 | -webkit-box-align: start;
375 | -ms-flex-align: start;
376 | } @else if $value == flex-end {
377 | -webkit-box-align: end;
378 | -ms-flex-align: end;
379 | } @else {
380 | -webkit-box-align: $value;
381 | -ms-flex-align: $value;
382 | }
383 | -webkit-align-items: $value;
384 | -moz-align-items: $value;
385 | align-items: $value;
386 | }
387 |
388 | //----------------------------------
389 |
390 | // Flexbox Align Self
391 | //
392 | // Values: auto | flex-start | flex-end | center | baseline | stretch
393 | // Default: auto
394 |
395 | @mixin align-self($value: auto) {
396 | // No Webkit Box Fallback.
397 | -webkit-align-self: $value;
398 | -moz-align-self: $value;
399 | @if $value == flex-start {
400 | -ms-flex-item-align: start;
401 | } @else if $value == flex-end {
402 | -ms-flex-item-align: end;
403 | } @else {
404 | -ms-flex-item-align: $value;
405 | }
406 | align-self: $value;
407 | }
408 |
409 | //----------------------------------------------------------------------
410 |
411 | // Flexbox Align Content
412 | //
413 | // The 'align-content' property aligns a flex container's lines within the
414 | // flex container when there is extra space in the cross-axis, similar to
415 | // how 'justify-content' aligns individual items within the main-axis. Note,
416 | // this property has no effect when the flexbox has only a single line.
417 | //
418 | // Values: flex-start | flex-end | center | space-between | space-around | stretch
419 | // Default: stretch
420 | //
421 | // http://w3.org/tr/css3-flexbox/#align-content-property
422 |
423 | @mixin align-content($value: stretch) {
424 | // No Webkit Box Fallback.
425 | -webkit-align-content: $value;
426 | -moz-align-content: $value;
427 | @if $value == flex-start {
428 | -ms-flex-line-pack: start;
429 | } @else if $value == flex-end {
430 | -ms-flex-line-pack: end;
431 | } @else {
432 | -ms-flex-line-pack: $value;
433 | }
434 | align-content: $value;
435 | }
436 |
437 | //----------------------------------------------------------------------
438 |
439 | // Breakpoint Mixins
440 |
441 | @function breakpoint-next($name, $breakpoints: _get($--grid, 'breakpoints'), $breakpoint-names: map-keys($breakpoints)) {
442 | $n: index($breakpoint-names, $name);
443 | @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);
444 | }
445 |
446 | // Minimum breakpoint width. Null for the smallest (first) breakpoint.
447 | //
448 | // >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px))
449 | // 576px
450 | @function breakpoint-min($name, $breakpoints: _get($--grid, 'breakpoints')) {
451 | $breakpoint: _get($breakpoints, $name);
452 | $min: nth($breakpoint, 1);
453 | @return if($min != 0, $min, null);
454 | }
455 |
456 | // Maximum breakpoint width. Null for the largest (last) breakpoint.
457 | // The maximum value is calculated as the minimum of the next one less 0.1.
458 | //
459 | // >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px))
460 | // 767px
461 | @function breakpoint-max($name, $breakpoints: _get($--grid, 'breakpoints')) {
462 | $next: breakpoint-next($name, $breakpoints);
463 | @return if($next, breakpoint-min($next, $breakpoints) - 1px, null);
464 | }
465 |
466 | // Media of at least the minimum breakpoint width. No query for the smallest breakpoint.
467 | // Makes the @content apply to the given breakpoint and wider.
468 | @mixin media-breakpoint-up($name, $breakpoints: _get($--grid, 'breakpoints')) {
469 | $min: breakpoint-min($name, $breakpoints);
470 | @if $min {
471 | @media (min-width: $min) {
472 | @content;
473 | }
474 | } @else {
475 | @content;
476 | }
477 | }
478 |
479 | // Media of at most the maximum breakpoint width. No query for the largest breakpoint.
480 | // Makes the @content apply to the given breakpoint and narrower.
481 | @mixin media-breakpoint-down($name, $breakpoints: _get($--grid, 'breakpoints')) {
482 | $max: breakpoint-max($name, $breakpoints);
483 | @if $max {
484 | @media (max-width: $max) {
485 | @content;
486 | }
487 | } @else {
488 | @content;
489 | }
490 | }
491 |
492 | // Media that spans multiple breakpoint widths.
493 | // Makes the @content apply between the min and max breakpoints
494 | @mixin media-breakpoint-between($lower, $upper, $breakpoints: _get($--grid, 'breakpoints')) {
495 | @include media-breakpoint-up($lower, $breakpoints) {
496 | @include media-breakpoint-down($upper, $breakpoints) {
497 | @content;
498 | }
499 | }
500 | }
501 |
502 | // Media between the breakpoint's minimum and maximum widths.
503 | // No minimum for the smallest breakpoint, and no maximum for the largest one.
504 | // Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.
505 | @mixin media-breakpoint-only($name, $breakpoints: _get($--grid, 'breakpoints')) {
506 | @include media-breakpoint-between($name, $name, $breakpoints) {
507 | @content;
508 | }
509 | }
510 |
511 | //----------------------------------------------------------------------
512 |
513 | // Button style mixin
514 | // Generate coloured buttons with modular hover color states.
515 |
516 | @mixin btn-style($name, $normal, $hover) {
517 | .btn, .btn-round {
518 | &.btn--#{$name} {
519 | color: nth($normal, 1) !important;
520 | background-color: nth($normal, 2);
521 | &:hover {
522 | color: nth($hover, 1) !important;
523 | background-color: nth($hover, 2);
524 | }
525 | }
526 |
527 | &.btn--hover-#{$name}:hover {
528 | color: nth($normal, 1) !important;
529 | background-color: nth($normal, 2) !important;
530 | }
531 | }
532 |
533 | }
534 |
535 | //----------------------------------------------------------------------
536 |
537 | // Responsive Font Scale
538 | // Set a responsive font scale which weights down across breakpoints.
539 |
540 | @mixin responsive-font-scale($fontsize: 1rem, $ratio: 1, $breakpoints: _get($--grid, 'breakpoints')) {
541 |
542 | $breakpoints: _map-reverse($breakpoints);
543 |
544 | @each $breakpoint in $breakpoints {
545 | $name: nth($breakpoint, 1);
546 | $i: index(map-keys($breakpoints), $name);
547 |
548 | // Ensure we're not setting a responsive scale on the largest breakpoint
549 | @if $i != 1 {
550 |
551 | // Get the total number of breakpoints
552 | $n: length($breakpoints);
553 |
554 | // Get decimal representation of breakpoint increment
555 | $b: $i / $n;
556 |
557 | // Get full intended decrement across all breakpoints
558 | $d: 1 - $ratio;
559 |
560 | // Get decrement for just this breakpoint
561 | $bd: $d * $b;
562 |
563 | // Represent the proper value
564 | $br: 1 - $bd;
565 |
566 | // Get the responsive fontsize
567 | $rf: $fontsize * $br;
568 |
569 | @include media-breakpoint-down($name) {
570 | font-size: $rf;
571 | }
572 | }
573 | }
574 |
575 | }
576 |
577 | //----------------------------------------------------------------------
578 |
579 | // Font mixins
580 | // Get and set fonts using the
581 |
582 | @function font($name, $fonts: $--font-faces) {
583 | $font: _get($fonts, $name);
584 | @if $font == null {
585 | @error "Font isn't defined.";
586 | } @else {
587 | $family: _get($font, 'family');
588 | $type: _get($font, 'type');
589 | @return '#{$family}', #{$type};
590 | }
591 | }
592 |
593 | // Set Font
594 | @mixin set-font($font, $font-styles: $--font-styles) {
595 |
596 | $setup: _get($font-styles, $font);
597 |
598 | $family: _get($setup, 'family');
599 | @if $family != null { font-family: $family; }
600 |
601 | $style: _get($setup, 'style');
602 | @if $style != null { font-style: $style; }
603 |
604 | $weight: _get($setup, 'weight');
605 | @if $weight != null { font-weight: $weight; }
606 |
607 | $spacing: _get($setup, 'letter-spacing');
608 | @if $spacing != null { letter-spacing: $spacing; }
609 |
610 | $text-transform: _get($setup, 'text-transform');
611 | @if $text-transform != null { text-transform: $text-transform; }
612 |
613 | }
614 |
--------------------------------------------------------------------------------
/tests/dummy/app/styles/framework/_reset.scss:
--------------------------------------------------------------------------------
1 | html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
2 | margin: 0;
3 | padding: 0;
4 | border: 0;
5 | font: inherit;
6 | vertical-align: baseline;
7 | }
8 |
9 | // HTML5 display-role reset for older browsers
10 | article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
11 | display: block;
12 | }
13 | body {
14 | line-height: 1;
15 | }
16 | ol, ul {
17 | list-style: none;
18 | }
19 | blockquote, q {
20 | quotes: none;
21 | }
22 | blockquote {
23 | &:before, &:after {
24 | content: "";
25 | content: none;
26 | }
27 | }
28 | q {
29 | &:before, &:after {
30 | content: "";
31 | content: none;
32 | }
33 | }
34 | table {
35 | border-collapse: collapse;
36 | border-spacing: 0;
37 | }
38 |
--------------------------------------------------------------------------------
/tests/dummy/app/styles/framework/_type.scss:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------
2 |
3 | // Type
4 | //
5 |
6 | $html: _get($--type, 'html');
7 | $headers: _get($--type, 'headers');
8 | $breakpoints: map-reverse(_get($--grid, 'breakpoints'));
9 | $paragraph: _get($--type, 'p');
10 | $small: _get($--type, 'small');
11 |
12 |
13 | html{
14 | font-size: nth($html, 1);
15 | line-height: nth($html, 2);
16 |
17 | @include responsive-font-scale(nth($html, 1), nth($html, 3));
18 | }
19 |
20 | @each $size, $value in $headers {
21 |
22 | $fontsize: nth($value, 1);
23 | $ratio: nth($value, 3);
24 |
25 | #{$size} {
26 | font-size: $fontsize;
27 | line-height: nth($value, 2);
28 | margin: $fontsize;
29 |
30 | @include responsive-font-scale($fontsize, $ratio);
31 |
32 | }
33 |
34 | }
35 |
36 | small { font-size: $small; }
37 |
38 | p {
39 | font-size: nth($paragraph, 1);
40 | line-height: nth($paragraph, 2);
41 | padding-bottom: nth($paragraph, 3);
42 | }
43 |
44 | article {
45 | // padding: 0 _get($--grid, 'margin') _get($--grid, 'margin') _get($--grid, 'margin');
46 | p {
47 | font-size: 1.1em;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/tests/dummy/app/styles/framework/_utility.scss:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------
2 |
3 | // Alignment classes
4 | //
5 | // Align element content using classes.
6 |
7 | .align-left { text-align: left; }
8 | .align-right { text-align: right; }
9 | .align-center { text-align: center; }
10 | .float-left { float: left !important; }
11 | .float-right { float: right !important; }
12 |
13 | //----------------------------------------------------------------------
14 |
15 | // Depth classes
16 | //
17 | // Add depth to elements using classes.
18 |
19 | $depth-color: _get($--colors, 'gray');
20 |
21 | $--depths: (
22 | xs: #{0 1px 2px 0 rgba($depth-color, 0.1),
23 | 0 2px 6px 0 rgba($depth-color, 0.1)},
24 | sm: #{0 1px 3px 0 rgba($depth-color, 0.2),
25 | 0 2px 8px 0 rgba($depth-color, 0.1)},
26 | md: #{0 1px 4px 0 rgba($depth-color, 0.3),
27 | 0 3px 12px 0 rgba($depth-color, 0.1)},
28 | lg: #{0 8px 17px 0 rgba($depth-color, 0.2),
29 | 0 6px 20px 0 rgba($depth-color, 0.19)},
30 | xl: #{0 12px 15px 0 rgba($depth-color, 0.24),
31 | 0 17px 50px 0 rgba($depth-color, 0.19)}
32 | );
33 |
34 | @each $name, $depth in $--depths {
35 | &.depth-#{$name} {
36 | box-shadow: $depth;
37 | }
38 | &.hover-depth-#{$name}:hover {
39 | box-shadow: $depth;
40 | }
41 | }
42 |
43 | .depth-none {
44 | box-shadow: none !important;
45 | }
46 |
47 | .depth-xs {
48 | box-shadow: 0 1px 2px 0 rgba($depth-color, 0.1), 0 2px 6px 0 rgba($depth-color, 0.1);
49 | }
50 |
51 | .depth-sm {
52 | box-shadow: 0 1px 3px 0 rgba($depth-color, 0.2), 0 2px 8px 0 rgba($depth-color, 0.1);
53 | }
54 |
55 | .depth-md {
56 | box-shadow: 0 1px 4px 0 rgba($depth-color, 0.3), 0 3px 12px 0 rgba($depth-color, 0.1);
57 | }
58 |
59 | .depth-lg {
60 | box-shadow: 0 8px 17px 0 rgba($depth-color, 0.2), 0 6px 20px 0 rgba($depth-color, 0.19);
61 | }
62 |
63 | .depth-xl {
64 | box-shadow: 0 12px 15px 0 rgba($depth-color, 0.24), 0 17px 50px 0 rgba($depth-color, 0.19);
65 | }
66 |
67 | //----------------------------------------------------------------------
68 |
69 | // Responsive media
70 | //
71 | // Responsive images and embedded video
72 |
73 | img.responsive-img,
74 | video.responsive-video {
75 | max-width: 100%;
76 | height: auto;
77 | &.fullwidth {
78 | min-width: 100%;
79 | }
80 | }
81 |
82 | .container-video {
83 | position: relative;
84 | padding-bottom: 56.25%;
85 | height: 0;
86 | overflow: hidden;
87 |
88 | iframe, object, embed {
89 | position: absolute;
90 | top: 0;
91 | left: 0;
92 | width: 100%;
93 | height: 100%;
94 | }
95 | }
96 |
97 |
98 | //----------------------------------------------------------------------
99 |
100 | // Truncate
101 | //
102 | // Truncate element text in the UI.
103 |
104 | .truncate {
105 | display: block;
106 | white-space: nowrap;
107 | overflow: hidden;
108 | text-overflow: ellipsis;
109 | }
110 |
111 | //----------------------------------------------------------------------
112 |
113 | // Clearfix
114 | //
115 | // Using flexbox should remove the need for clearfix, but you can use it to ensure elements float correctly.
116 |
117 | .clearfix {
118 | clear: both;
119 | &:before, &:after {
120 | flex-basis: 0;
121 | order: 1;
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/tests/dummy/app/styles/main/_.scss:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------
2 |
3 | // Main
4 | //
5 |
6 | * {
7 | &::selection {
8 | color: _get($--main, 'selection-color');
9 | background-color: _get($--main, 'selection-background-color');
10 | }
11 | }
12 |
13 | html {
14 | @include set-font('content');
15 | }
16 |
17 | body {
18 | overflow-x: hidden;
19 | overflow-y: auto;
20 | -webkit-font-smoothing: antialiased;
21 |
22 | color: _get($--main, 'body-color');
23 | background-color: _get($--main, 'body-background-color');
24 |
25 | &.no-scroll { overflow: hidden; }
26 |
27 | }
28 |
29 | //----------------------------------------------------------------------
30 |
31 | // Headers
32 | // Add header styles.
33 |
34 | h1, h2, h3, h4, h5, h6 {
35 | @include set-font('display');
36 |
37 | // Ensure there's a margin on each header
38 | margin: .5em 0;
39 |
40 | // Other styles to attach to all headers
41 | a { font-weight: inherit; }
42 | }
43 |
44 | //----------------------------------------------------------------------
45 |
46 | // Links
47 | // Add link styles.
48 |
49 | a {
50 | text-decoration: none;
51 | &, &:visited, &:active { display: inline-block; color: inherit; }
52 | }
53 |
54 | //----------------------------------------------------------------------
55 |
56 | // Type
57 | // Defaults for type styles
58 |
59 | i { font-style: italic; }
60 | b { font-weight: 700; }
61 | em { font-style: italic; }
62 | strong { font-weight: 500; }
63 | .uppercase { text-transform: uppercase !important; }
64 |
--------------------------------------------------------------------------------
/tests/dummy/app/styles/main/_config.scss:
--------------------------------------------------------------------------------
1 | // Main config
2 |
3 | $--grid: (
4 | // Set the number of columns you want to use on your layout.
5 | columns: 12,
6 | // Set the gutter between columns.
7 | gutter: 1rem,
8 | // Set a margin for the container sides.
9 | margin: 2rem,
10 | // Define breakpoints.
11 | breakpoints: (
12 | xs: default, // Less than 576px wide - Portrait phones
13 | sm: 576px 540px, // Between 576 and 767 - Landscape Phones
14 | md: 768px 720px, // Between 768 and 991 - Tablets
15 | lg: 992px 960px, // Between 992 and 1199 - Desktops
16 | xl: 1280px 1024px // 1200 upwards - Extra large devices
17 | ),
18 | // Max width of container
19 | max-width: 1024px
20 | );
21 |
22 | $--font-faces: (
23 | 'overpass': (
24 | family: 'Overpass',
25 | type: sans-serif
26 | )
27 | );
28 |
29 | $--font-styles: (
30 | 'display': (
31 | family: font('overpass'),
32 | style: normal,
33 | weight: 300,
34 | letter-spacing: -.02em
35 | ),
36 | 'header': (
37 | family: font('overpass'),
38 | style: normal,
39 | weight: 800,
40 | letter-spacing: -0.01em
41 | ),
42 | 'content': (
43 | family: font('overpass'),
44 | transform: inherit,
45 | weight: 400,
46 | letter-spacing: 0em
47 | )
48 | );
49 |
50 | $--type: (
51 | // HTML Base Font
52 | // @params font-size, line-height, responsive-ratio
53 | html: (15px, 150%, 1.1),
54 |
55 | // Headers
56 | // @params font-size, line-height, responsive-ratio
57 | headers: (
58 | h1: (3.33rem, 110%, 0.6),
59 | h2: (2rem, 120%, 0.8),
60 | h3: (1.66rem, 130%, 0.85),
61 | h4: (1.33rem, 140%, 0.9),
62 | h5: (1.2rem, 160%, 0.95),
63 | h6: (1rem, 180%, 1)
64 | ),
65 |
66 | // Paragraph
67 | // @params font-size, line-height, padding-bottom
68 | p: (1rem, 200%, 1em),
69 |
70 | // Small
71 | // @params font-size
72 | small: 0.9em
73 | );
74 |
75 | $--colors: (
76 | // Monochrome
77 | 'white': white,
78 | 'black': black,
79 |
80 | // Mid tones
81 | 'gray': #2f3640,
82 | 'lt-gray': darken(white, 5%),
83 | 'mid-gray': darken(white, 33%),
84 |
85 | // Success, Error & Warning
86 | 'green': #2ecc71,
87 | 'red': #EF2038,
88 | 'yellow': #FFDF2E
89 | );
90 |
91 | $--main: (
92 | body-color: _get($--colors, 'black'),
93 | body-background-color: _get($--colors, 'white'),
94 | selection-background-color: _get($--colors, 'black'),
95 | selection-color: _get($--colors, 'white')
96 | );
97 |
98 | $--easing: (
99 | 'cubic': (
100 | in: cubic-bezier(0.550, 0.055, 0.675, 0.190),
101 | out: cubic-bezier(0.215, 0.610, 0.355, 1.000),
102 | in-out: cubic-bezier(0.645, 0.045, 0.355, 1.000)
103 | ),
104 | 'expo': (
105 | in: cubic-bezier(0.950, 0.050, 0.795, 0.035),
106 | out: cubic-bezier(0.190, 1.000, 0.220, 1.000),
107 | in-out: cubic-bezier(1.000, 0.000, 0.000, 1.000)
108 | ),
109 | 'back': (
110 | in: cubic-bezier(0.600, -0.280, 0.735, 0.045),
111 | out: cubic-bezier(0.175, 0.885, 0.320, 1.275),
112 | in-out: cubic-bezier(0.680, -0.550, 0.265, 1.550)
113 | ),
114 | 'jump': (
115 | out: cubic-bezier(.25,1.4,.55,.99),
116 | in-out: cubic-bezier(.87,-.41,.19,1.44),
117 | ),
118 | 'leap': (
119 | out: cubic-bezier(.25,1.9,.55,.99),
120 | in-out: cubic-bezier(.78,-0.81,.27,1.7)
121 | )
122 |
123 | );
124 |
--------------------------------------------------------------------------------
/tests/dummy/app/styles/routes/_.scss:
--------------------------------------------------------------------------------
1 | [data-section="index"] {
2 | img {
3 | width: 66%;
4 | max-width: 480px;
5 | min-width: 320px;
6 | }
7 | }
8 |
9 | .valign-section {
10 | display: flex;
11 | height: 100vh;
12 | padding: 0 0 0 0 !important;
13 | & > div {
14 | margin: auto;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tests/dummy/app/templates/application.hbs:
--------------------------------------------------------------------------------
1 | {{outlet}}
2 |
--------------------------------------------------------------------------------
/tests/dummy/app/templates/components/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willviles/ember-cli-markdown-resolver/46e56e04d3bf9508f56e7844030f865f7e0fd788/tests/dummy/app/templates/components/.gitkeep
--------------------------------------------------------------------------------
/tests/dummy/app/templates/components/ui-button.hbs:
--------------------------------------------------------------------------------
1 | {{#if linkTitle}}{{linkTitle}}{{else}}{{yield}}{{/if}}
2 |
--------------------------------------------------------------------------------
/tests/dummy/app/templates/components/ui-footer.hbs:
--------------------------------------------------------------------------------
1 |
2 |
29 |
--------------------------------------------------------------------------------
/tests/dummy/app/templates/components/ui-navbar.hbs:
--------------------------------------------------------------------------------
1 |
2 |
30 |
--------------------------------------------------------------------------------
/tests/dummy/app/templates/error.hbs:
--------------------------------------------------------------------------------
1 |
29 | Uh-oh
2 |
3 | 404
4 |
5 |
--------------------------------------------------------------------------------
/tests/dummy/app/templates/guides.hbs:
--------------------------------------------------------------------------------
1 | {{ui-navbar fixed=false}}
2 |
3 | {{#ui-section padding="xs"}}
4 |
5 |
6 |
7 |
8 | {{markdown-menu tree=tree linkTo='guides.single'}}
9 |
10 |
11 |
12 |
13 |
14 |
15 | {{outlet}}
16 |
17 |
18 |
19 |
20 |
21 |
22 | {{/ui-section}}
23 |
24 | {{partial 'components/ui-footer'}}
--------------------------------------------------------------------------------
/tests/dummy/app/templates/guides/single.hbs:
--------------------------------------------------------------------------------
1 | {{#if guide.content}}
2 |
3 | {{#if guide.attributes.title}}
4 | {{guide.attributes.title}}
5 |
6 |
7 | {{/if}}
8 | {{markdown-content guide.content extensions="prettify"}}
9 |
10 | {{/if}}
11 |
--------------------------------------------------------------------------------
/tests/dummy/app/templates/head.hbs:
--------------------------------------------------------------------------------
1 | {{!--
2 | Add content you wish automatically added to the documents head
3 | here. The 'model' available in this template can be populated by
4 | setting values on the 'head-data' service.
5 | --}}
6 |
7 | {{model.title}}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/tests/dummy/app/templates/index.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{#ui-section name="index" align="center" padding="md"}}
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | The quickest way to include static markdown content in your Ember.js application.
13 |
14 |
15 |
16 |
17 | {{ui-button-link-to 'View the Guides' 'guides'
18 | bg="black"
19 | bgHover="red"
20 | color="white"
21 | inline=true
22 | padding="md"
23 | depth="md" }}
24 |
25 | {{ui-button-link 'GitHub'
26 | href="https://github.com/willviles/ember-cli-markdown-resolver"
27 | target="_blank"
28 | bg="black"
29 | bgHover="red"
30 | color="white"
31 | inline=true
32 | padding="md"
33 | depth="md" }}
34 |
35 |
36 | {{/ui-section}}
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/tests/dummy/app/utils/property-class-name-binding.js:
--------------------------------------------------------------------------------
1 | import { assign } from '@ember/polyfills';
2 | import { computed, get } from '@ember/object';
3 | import { dasherize } from '@ember/string';
4 | import { typeOf } from '@ember/utils';
5 |
6 | export default function(property, opts) {
7 | return computed(property, function() {
8 | let value = get(this, property);
9 |
10 | opts = assign({
11 | prefix: dasherize(property),
12 | values: false
13 | }, opts);
14 |
15 | if (typeOf(value) === 'string') {
16 | return `${opts.prefix}-${value}`;
17 | } else if (typeOf(value) === 'boolean') {
18 | return value;
19 | } else if (typeOf(value) === 'object') {
20 | if (typeOf(opts.values) === 'array') {
21 | return opts.values.reduce((arr, key) => {
22 | return value[key] ?
23 | [...arr, `${opts.prefix}-${key}-${value[key]}`] :
24 | [...arr];
25 | }, []).join(' ');
26 | } else {
27 | return;
28 | }
29 |
30 | }
31 | });
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/tests/dummy/config/environment.js:
--------------------------------------------------------------------------------
1 | /* eslint-env node */
2 | 'use strict';
3 |
4 | module.exports = function(environment) {
5 | let ENV = {
6 | modulePrefix: 'dummy',
7 | environment,
8 | rootURL: '/',
9 | locationType: 'auto',
10 | EmberENV: {
11 | FEATURES: {
12 | // Here you can enable experimental features on an ember canary build
13 | // e.g. 'with-controller': true
14 | },
15 | EXTEND_PROTOTYPES: {
16 | // Prevent Ember Data from overriding Date.parse.
17 | Date: false
18 | }
19 | },
20 |
21 | APP: {
22 | // Here you can pass flags/options to your application instance
23 | // when it is created
24 | }
25 | };
26 |
27 | // @addon Ember CLI Markdown Resolver
28 | // @url https://github.com/willviles/ember-cli-markdown-resolver
29 |
30 | ENV['ember-cli-markdown-resolver'] = {
31 | folders: {
32 | guides: 'app/guides'
33 | }
34 | };
35 |
36 | // @addon Ember Code Prettify
37 | // @url https://github.com/willviles/ember-code-prettify
38 |
39 | ENV['ember-code-prettify'] = {
40 | languages: ['css', 'yaml'],
41 | skin: 'desert'
42 | };
43 |
44 | ENV['googleFonts'] = [
45 | 'Overpass:300,400,800'
46 | ];
47 |
48 | if (environment === 'development') {
49 | // ENV.APP.LOG_RESOLVER = true;
50 | // ENV.APP.LOG_ACTIVE_GENERATION = true;
51 | // ENV.APP.LOG_TRANSITIONS = true;
52 | // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
53 | // ENV.APP.LOG_VIEW_LOOKUPS = true;
54 | }
55 |
56 | if (environment === 'test') {
57 | // Testem prefers this...
58 | ENV.locationType = 'none';
59 |
60 | // keep test console output quieter
61 | ENV.APP.LOG_ACTIVE_GENERATION = false;
62 | ENV.APP.LOG_VIEW_LOOKUPS = false;
63 |
64 | ENV.APP.rootElement = '#ember-testing';
65 | }
66 |
67 | if (environment === 'production') {
68 | ENV.locationType = 'hash';
69 | ENV.rootURL = '/ember-cli-markdown-resolver/';
70 |
71 | }
72 |
73 | return ENV;
74 | };
75 |
--------------------------------------------------------------------------------
/tests/dummy/config/targets.js:
--------------------------------------------------------------------------------
1 | /* eslint-env node */
2 | module.exports = {
3 | browsers: [
4 | 'ie 9',
5 | 'last 1 Chrome versions',
6 | 'last 1 Firefox versions',
7 | 'last 1 Safari versions'
8 | ]
9 | };
10 |
--------------------------------------------------------------------------------
/tests/dummy/public/crossdomain.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
15 |
16 |
--------------------------------------------------------------------------------
/tests/dummy/public/images/facebook.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willviles/ember-cli-markdown-resolver/46e56e04d3bf9508f56e7844030f865f7e0fd788/tests/dummy/public/images/facebook.jpg
--------------------------------------------------------------------------------
/tests/dummy/public/images/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willviles/ember-cli-markdown-resolver/46e56e04d3bf9508f56e7844030f865f7e0fd788/tests/dummy/public/images/favicon-16x16.png
--------------------------------------------------------------------------------
/tests/dummy/public/images/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willviles/ember-cli-markdown-resolver/46e56e04d3bf9508f56e7844030f865f7e0fd788/tests/dummy/public/images/favicon-32x32.png
--------------------------------------------------------------------------------
/tests/dummy/public/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willviles/ember-cli-markdown-resolver/46e56e04d3bf9508f56e7844030f865f7e0fd788/tests/dummy/public/images/favicon.ico
--------------------------------------------------------------------------------
/tests/dummy/public/images/logo-black.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/dummy/public/images/logo-white.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/tests/dummy/public/robots.txt:
--------------------------------------------------------------------------------
1 | # http://www.robotstxt.org
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/tests/helpers/destroy-app.js:
--------------------------------------------------------------------------------
1 | import { run } from '@ember/runloop';
2 |
3 | export default function destroyApp(application) {
4 | run(application, 'destroy');
5 | }
6 |
--------------------------------------------------------------------------------
/tests/helpers/module-for-acceptance.js:
--------------------------------------------------------------------------------
1 | import { module } from 'qunit';
2 | import { resolve } from 'rsvp';
3 | import startApp from '../helpers/start-app';
4 | import destroyApp from '../helpers/destroy-app';
5 |
6 | export default function(name, options = {}) {
7 | module(name, {
8 | beforeEach() {
9 | this.application = startApp();
10 |
11 | if (options.beforeEach) {
12 | return options.beforeEach.apply(this, arguments);
13 | }
14 | },
15 |
16 | afterEach() {
17 | let afterEach = options.afterEach && options.afterEach.apply(this, arguments);
18 | return resolve(afterEach).then(() => destroyApp(this.application));
19 | }
20 | });
21 | }
22 |
--------------------------------------------------------------------------------
/tests/helpers/resolver.js:
--------------------------------------------------------------------------------
1 | import Resolver from '../../resolver';
2 | import config from '../../config/environment';
3 |
4 | const resolver = Resolver.create();
5 |
6 | resolver.namespace = {
7 | modulePrefix: config.modulePrefix,
8 | podModulePrefix: config.podModulePrefix
9 | };
10 |
11 | export default resolver;
12 |
--------------------------------------------------------------------------------
/tests/helpers/start-app.js:
--------------------------------------------------------------------------------
1 | import Application from '../../app';
2 | import config from '../../config/environment';
3 | import { merge } from '@ember/polyfills';
4 | import { run } from '@ember/runloop';
5 |
6 | export default function startApp(attrs) {
7 | let attributes = merge({}, config.APP);
8 | attributes = merge(attributes, attrs); // use defaults, but you can override;
9 |
10 | return run(() => {
11 | let application = Application.create(attributes);
12 | application.setupForTesting();
13 | application.injectTestHelpers();
14 | return application;
15 | });
16 | }
17 |
--------------------------------------------------------------------------------
/tests/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Dummy Tests
7 |
8 |
9 |
10 | {{content-for "head"}}
11 | {{content-for "test-head"}}
12 |
13 |
14 |
15 |
16 |
17 | {{content-for "head-footer"}}
18 | {{content-for "test-head-footer"}}
19 |
20 |
21 | {{content-for "body"}}
22 | {{content-for "test-body"}}
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | {{content-for "body-footer"}}
31 | {{content-for "test-body-footer"}}
32 |
33 |
34 |
--------------------------------------------------------------------------------
/tests/integration/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willviles/ember-cli-markdown-resolver/46e56e04d3bf9508f56e7844030f865f7e0fd788/tests/integration/.gitkeep
--------------------------------------------------------------------------------
/tests/test-helper.js:
--------------------------------------------------------------------------------
1 | import Application from '../app';
2 | import { setApplication } from '@ember/test-helpers';
3 | import { start } from 'ember-qunit';
4 |
5 | setApplication(Application.create({ autoboot: false }));
6 |
7 | start();
8 |
--------------------------------------------------------------------------------
/tests/unit/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willviles/ember-cli-markdown-resolver/46e56e04d3bf9508f56e7844030f865f7e0fd788/tests/unit/.gitkeep
--------------------------------------------------------------------------------
/vendor/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willviles/ember-cli-markdown-resolver/46e56e04d3bf9508f56e7844030f865f7e0fd788/vendor/.gitkeep
--------------------------------------------------------------------------------