├── app
├── .gitkeep
├── components
│ ├── in-sidebar.js
│ ├── show-sidebar.js
│ └── with-sidebar.js
└── services
│ └── ember-sidebars.js
├── addon
├── .gitkeep
├── templates
│ └── components
│ │ ├── in-sidebar.hbs
│ │ ├── show-sidebar.hbs
│ │ └── with-sidebar.hbs
├── components
│ ├── show-sidebar.js
│ ├── in-sidebar.js
│ └── with-sidebar.js
└── services
│ └── ember-sidebars.js
├── vendor
└── .gitkeep
├── tests
├── unit
│ ├── .gitkeep
│ └── services
│ │ └── ember-sidebars-test.js
├── integration
│ └── .gitkeep
├── dummy
│ ├── app
│ │ ├── helpers
│ │ │ └── .gitkeep
│ │ ├── models
│ │ │ └── .gitkeep
│ │ ├── routes
│ │ │ ├── .gitkeep
│ │ │ └── index.js
│ │ ├── components
│ │ │ └── .gitkeep
│ │ ├── controllers
│ │ │ ├── .gitkeep
│ │ │ └── second.js
│ │ ├── templates
│ │ │ ├── components
│ │ │ │ ├── .gitkeep
│ │ │ │ ├── third-tools.hbs
│ │ │ │ ├── first-sidebar.hbs
│ │ │ │ └── second-tools.hbs
│ │ │ ├── third.hbs
│ │ │ ├── index.hbs
│ │ │ ├── second.hbs
│ │ │ └── application.hbs
│ │ ├── resolver.js
│ │ ├── router.js
│ │ ├── transitions.js
│ │ ├── app.js
│ │ ├── index.html
│ │ └── styles
│ │ │ └── app.css
│ ├── public
│ │ ├── robots.txt
│ │ └── crossdomain.xml
│ └── config
│ │ └── environment.js
├── test-helper.js
├── helpers
│ ├── destroy-app.js
│ ├── resolver.js
│ ├── start-app.js
│ └── module-for-acceptance.js
├── .jshintrc
└── index.html
├── .watchmanconfig
├── .bowerrc
├── index.js
├── config
├── environment.js
├── deploy.js
└── ember-try.js
├── bower.json
├── .npmignore
├── testem.js
├── .ember-cli
├── .gitignore
├── ember-cli-build.js
├── .jshintrc
├── .editorconfig
├── .travis.yml
├── LICENSE.md
├── package.json
└── README.md
/app/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/addon/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vendor/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/unit/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/integration/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/dummy/app/helpers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/dummy/app/models/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/dummy/app/routes/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/dummy/app/components/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/dummy/app/controllers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/dummy/app/templates/components/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/addon/templates/components/in-sidebar.hbs:
--------------------------------------------------------------------------------
1 | {{yield}}
2 |
--------------------------------------------------------------------------------
/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {
2 | "ignore_dirs": ["tmp", "dist"]
3 | }
4 |
--------------------------------------------------------------------------------
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory": "bower_components",
3 | "analytics": false
4 | }
5 |
--------------------------------------------------------------------------------
/app/components/in-sidebar.js:
--------------------------------------------------------------------------------
1 | export { default } from 'ember-sidebars/components/in-sidebar';
--------------------------------------------------------------------------------
/tests/dummy/public/robots.txt:
--------------------------------------------------------------------------------
1 | # http://www.robotstxt.org
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/app/components/show-sidebar.js:
--------------------------------------------------------------------------------
1 | export { default } from 'ember-sidebars/components/show-sidebar';
--------------------------------------------------------------------------------
/app/components/with-sidebar.js:
--------------------------------------------------------------------------------
1 | export { default } from 'ember-sidebars/components/with-sidebar';
--------------------------------------------------------------------------------
/app/services/ember-sidebars.js:
--------------------------------------------------------------------------------
1 | export { default } from 'ember-sidebars/services/ember-sidebars';
2 |
--------------------------------------------------------------------------------
/tests/dummy/app/resolver.js:
--------------------------------------------------------------------------------
1 | import Resolver from 'ember-resolver';
2 |
3 | export default Resolver;
4 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | /* jshint node: true */
2 | 'use strict';
3 |
4 | module.exports = {
5 | name: 'ember-sidebars'
6 | };
7 |
--------------------------------------------------------------------------------
/tests/dummy/app/templates/components/third-tools.hbs:
--------------------------------------------------------------------------------
1 |
2 | This is the third-tools component.
3 |
--------------------------------------------------------------------------------
/tests/dummy/app/templates/components/first-sidebar.hbs:
--------------------------------------------------------------------------------
1 | This is the first-sidebar component. It has acces to the model, which says {{model.title}}.
--------------------------------------------------------------------------------
/addon/templates/components/show-sidebar.hbs:
--------------------------------------------------------------------------------
1 | {{#with (get sidebars.actives _name) as |name|}}
2 | {{component (get name 'component') }}
3 | {{/with}}
4 |
--------------------------------------------------------------------------------
/config/environment.js:
--------------------------------------------------------------------------------
1 | /*jshint node:true*/
2 | 'use strict';
3 |
4 | module.exports = function(/* environment, appConfig */) {
5 | return { };
6 | };
7 |
--------------------------------------------------------------------------------
/tests/test-helper.js:
--------------------------------------------------------------------------------
1 | import resolver from './helpers/resolver';
2 | import {
3 | setResolver
4 | } from 'ember-qunit';
5 |
6 | setResolver(resolver);
7 |
--------------------------------------------------------------------------------
/tests/helpers/destroy-app.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 |
3 | export default function destroyApp(application) {
4 | Ember.run(application, 'destroy');
5 | }
6 |
--------------------------------------------------------------------------------
/tests/dummy/app/templates/components/second-tools.hbs:
--------------------------------------------------------------------------------
1 |
2 | This is the second tools component. Send an action out.
3 |
--------------------------------------------------------------------------------
/addon/templates/components/with-sidebar.hbs:
--------------------------------------------------------------------------------
1 | {{#if initialized}}
2 | {{yield (get (get sidebars.actives _name) 'component') (get (get sidebars.actives _name) 'hooks')}}
3 | {{/if}}
4 |
--------------------------------------------------------------------------------
/tests/dummy/app/routes/index.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 |
3 | export default Ember.Route.extend({
4 | model() {
5 | return Ember.Object.create({
6 | title: "Welcome"
7 | });
8 | }
9 | });
10 |
--------------------------------------------------------------------------------
/tests/dummy/app/templates/third.hbs:
--------------------------------------------------------------------------------
1 | {{! BEGIN-SNIPPET third }}
2 | This is the third page.
3 |
4 | {{in-sidebar name="tools" show=(component "third-tools") }}
5 | {{! END-SNIPPET }}
6 |
7 | {{code-snippet name="third.hbs"}}
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ember-sidebars",
3 | "dependencies": {
4 | "ember": "~2.4.1",
5 | "ember-cli-shims": "0.1.0",
6 | "ember-cli-test-loader": "0.2.2",
7 | "ember-qunit-notifications": "0.1.0"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/tests/dummy/app/templates/index.hbs:
--------------------------------------------------------------------------------
1 | {{!- BEGIN-SNIPPET index }}
2 | This is the first page. The model says: {{model.title}}
3 |
4 | {{in-sidebar name="right" show=(component "first-sidebar" model=model)}}
5 | {{!- END-SNIPPET }}
6 |
7 | {{code-snippet name="index.hbs"}}
8 |
--------------------------------------------------------------------------------
/.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 | .jshintrc
12 | .watchmanconfig
13 | .travis.yml
14 | bower.json
15 | ember-cli-build.js
16 | testem.js
17 |
--------------------------------------------------------------------------------
/testem.js:
--------------------------------------------------------------------------------
1 | /*jshint node:true*/
2 | module.exports = {
3 | "framework": "qunit",
4 | "test_page": "tests/index.html?hidepassed",
5 | "disable_watching": true,
6 | "launch_in_ci": [
7 | "PhantomJS"
8 | ],
9 | "launch_in_dev": [
10 | "PhantomJS",
11 | "Chrome"
12 | ]
13 | };
14 |
--------------------------------------------------------------------------------
/tests/dummy/app/controllers/second.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 |
3 | export default Ember.Controller.extend({
4 | init() {
5 | this.set('handled', Ember.A());
6 | },
7 | actions: {
8 | handleIt() {
9 | this.get('handled').pushObject("I handled an event");
10 | }
11 | }
12 | });
13 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/tests/dummy/app/router.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 | import config from './config/environment';
3 |
4 | const Router = Ember.Router.extend({
5 | location: config.locationType
6 | });
7 |
8 | Router.map(function() {
9 | this.route('second');
10 | this.route('third');
11 | });
12 |
13 | export default Router;
14 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://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 | testem.log
18 |
--------------------------------------------------------------------------------
/addon/components/show-sidebar.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 | import layout from '../templates/components/show-sidebar';
3 |
4 | export default Ember.Component.extend({
5 | sidebars: Ember.inject.service('ember-sidebars'),
6 | layout,
7 | _name: Ember.computed('name', function() {
8 | return this.get('name') || 'default';
9 | })
10 | });
11 |
--------------------------------------------------------------------------------
/tests/dummy/app/templates/second.hbs:
--------------------------------------------------------------------------------
1 | {{!- BEGIN-SNIPPET second }}
2 | This is the second page.
3 | {{#each handled as |h|}}
4 | {{h}}
5 | {{/each}}
6 |
7 | {{in-sidebar name="tools"
8 | show=(component "second-tools" doIt=(action "handleIt") ) }}
9 | {{!- END-SNIPPET }}
10 |
11 | {{code-snippet name="second.hbs"}}
12 |
--------------------------------------------------------------------------------
/tests/dummy/app/transitions.js:
--------------------------------------------------------------------------------
1 | export default function() {
2 | this.transition(
3 | this.inHelper('liquid-bind'),
4 | this.fromValue(false),
5 | this.toValue(true),
6 | this.use('to-down'),
7 | this.reverse('to-up')
8 | );
9 | this.transition(
10 | this.inHelper('liquid-bind'),
11 | this.fromValue(true),
12 | this.toValue(true),
13 | this.use('fade')
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/addon/components/in-sidebar.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 | import layout from '../templates/components/in-sidebar';
3 |
4 | export default Ember.Component.extend({
5 | tagName: '',
6 | layout,
7 | sidebars: Ember.inject.service('ember-sidebars'),
8 | willRender() {
9 | this.get('sidebars').show(Ember.guidFor(this), this.get('name'), this.get('show'), this.get('hooks'));
10 | },
11 | willDestroyElement() {
12 | this.get('sidebars').clear(Ember.guidFor(this));
13 | }
14 |
15 | });
16 |
--------------------------------------------------------------------------------
/tests/helpers/start-app.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 | import Application from '../../app';
3 | import config from '../../config/environment';
4 |
5 | export default function startApp(attrs) {
6 | let application;
7 |
8 | let attributes = Ember.merge({}, config.APP);
9 | attributes = Ember.merge(attributes, attrs); // use defaults, but you can override;
10 |
11 | Ember.run(() => {
12 | application = Application.create(attributes);
13 | application.setupForTesting();
14 | application.injectTestHelpers();
15 | });
16 |
17 | return application;
18 | }
19 |
--------------------------------------------------------------------------------
/ember-cli-build.js:
--------------------------------------------------------------------------------
1 | /*jshint node:true*/
2 | /* global require, module */
3 | var EmberAddon = require('ember-cli/lib/broccoli/ember-addon');
4 |
5 | module.exports = function(defaults) {
6 | var app = new EmberAddon(defaults, {
7 | snippetSearchPaths: ['tests/dummy']
8 | });
9 |
10 | /*
11 | This build file specifies the options for the dummy test app of this
12 | addon, located in `/tests/dummy`
13 | This build file does *not* influence how the addon or the app using it
14 | behave. You most likely want to be modifying `./index.js` or app's build file
15 | */
16 |
17 | return app.toTree();
18 | };
19 |
--------------------------------------------------------------------------------
/tests/dummy/app/app.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 | import Resolver from './resolver';
3 | import loadInitializers from 'ember-load-initializers';
4 | import config from './config/environment';
5 |
6 | let App;
7 |
8 | Ember.MODEL_FACTORY_INJECTIONS = true;
9 |
10 | App = Ember.Application.extend({
11 | modulePrefix: config.modulePrefix,
12 | podModulePrefix: config.podModulePrefix,
13 | Resolver
14 | });
15 |
16 | loadInitializers(App, config.modulePrefix);
17 |
18 | export default App;
19 |
20 | if (window.location.host === 'ef4.github.io') {
21 | window.location.href = 'https://ef4.github.com/ember-elsewhere';
22 | }
23 |
--------------------------------------------------------------------------------
/tests/helpers/module-for-acceptance.js:
--------------------------------------------------------------------------------
1 | import { module } from 'qunit';
2 | import startApp from '../helpers/start-app';
3 | import destroyApp from '../helpers/destroy-app';
4 |
5 | export default function(name, options = {}) {
6 | module(name, {
7 | beforeEach() {
8 | this.application = startApp();
9 |
10 | if (options.beforeEach) {
11 | options.beforeEach.apply(this, arguments);
12 | }
13 | },
14 |
15 | afterEach() {
16 | if (options.afterEach) {
17 | options.afterEach.apply(this, arguments);
18 | }
19 |
20 | destroyApp(this.application);
21 | }
22 | });
23 | }
24 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "predef": [
3 | "document",
4 | "window",
5 | "-Promise"
6 | ],
7 | "browser": true,
8 | "boss": true,
9 | "curly": true,
10 | "debug": false,
11 | "devel": true,
12 | "eqeqeq": true,
13 | "evil": true,
14 | "forin": false,
15 | "immed": false,
16 | "laxbreak": false,
17 | "newcap": true,
18 | "noarg": true,
19 | "noempty": false,
20 | "nonew": false,
21 | "nomen": false,
22 | "onevar": false,
23 | "plusplus": false,
24 | "regexp": false,
25 | "undef": true,
26 | "sub": true,
27 | "strict": false,
28 | "white": false,
29 | "eqnull": true,
30 | "esnext": true,
31 | "unused": true
32 | }
33 |
--------------------------------------------------------------------------------
/tests/dummy/public/crossdomain.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
15 |
16 |
--------------------------------------------------------------------------------
/.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 | [*.js]
17 | indent_style = space
18 | indent_size = 2
19 |
20 | [*.hbs]
21 | insert_final_newline = false
22 | indent_style = space
23 | indent_size = 2
24 |
25 | [*.css]
26 | indent_style = space
27 | indent_size = 2
28 |
29 | [*.html]
30 | indent_style = space
31 | indent_size = 2
32 |
33 | [*.{diff,md}]
34 | trim_trailing_whitespace = false
35 |
--------------------------------------------------------------------------------
/addon/components/with-sidebar.js:
--------------------------------------------------------------------------------
1 | import ShowSidebar from './show-sidebar';
2 | import layout from '../templates/components/with-sidebar';
3 | import Ember from 'ember';
4 |
5 | export default ShowSidebar.extend({
6 | layout,
7 |
8 | // We don't yield any content on the very first render pass, because
9 | // we want to give any concurrent {{in-sidebar}} components a chance
10 | // to declare their intentions first. This allows the components
11 | // inside us to see a meaningful initial value on their initial
12 | // render.
13 | initialized: false,
14 | didInsertElement() {
15 | this._super();
16 | Ember.run.schedule('afterRender', () => this.set('initialized', true));
17 | }
18 | });
19 |
--------------------------------------------------------------------------------
/tests/dummy/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Ember Sidebars
7 |
8 |
9 |
10 | {{content-for "head"}}
11 |
12 |
13 |
14 |
15 | {{content-for "head-footer"}}
16 |
17 |
18 | {{content-for "body"}}
19 |
20 |
21 |
22 |
23 | {{content-for "body-footer"}}
24 |
25 |
26 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | ---
2 | language: node_js
3 | node_js:
4 | - "0.12"
5 |
6 | sudo: false
7 |
8 | cache:
9 | directories:
10 | - node_modules
11 |
12 | env:
13 | - EMBER_TRY_SCENARIO=default
14 | - EMBER_TRY_SCENARIO=ember-1-13
15 | - EMBER_TRY_SCENARIO=ember-release
16 | - EMBER_TRY_SCENARIO=ember-beta
17 | - EMBER_TRY_SCENARIO=ember-canary
18 |
19 | matrix:
20 | fast_finish: true
21 | allow_failures:
22 | - env: EMBER_TRY_SCENARIO=ember-canary
23 |
24 | before_install:
25 | - export PATH=/usr/local/phantomjs-2.0.0/bin:$PATH
26 | - "npm config set spin false"
27 | - "npm install -g npm@^2"
28 |
29 | install:
30 | - npm install -g bower
31 | - npm install
32 | - bower install
33 |
34 | script:
35 | - ember try $EMBER_TRY_SCENARIO test
36 |
--------------------------------------------------------------------------------
/tests/dummy/app/styles/app.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding: 0;
3 | margin: 0;
4 | }
5 | .v-container {
6 | display: flex;
7 | flex-direction: column;
8 | height: 100vh;
9 | }
10 | .container {
11 | display: flex;
12 | flex: 1;
13 | }
14 | main {
15 | flex: 1;
16 | padding: 1.5em;
17 | box-sizing: border-box;
18 | margin: 0;
19 | }
20 | .right-sidebar {
21 | padding: 1.5em;
22 | width: 15em;
23 | background-color: #B4B4E8;
24 | }
25 | .topbar {
26 | width: 100%;
27 | box-sizing: border-box;
28 | background-color: #BCD0B1;
29 | }
30 | .tools {
31 | padding: 1.5em;
32 | line-height: 1.5em;
33 | }
34 | nav {
35 | margin-bottom: 0.5em;
36 | }
37 | nav a {
38 | display: inline-block;
39 | padding: 0.5em;
40 | text-decoration: none;
41 | background-color: #EAEACB;
42 | color: black;
43 | }
44 | nav a.active {
45 | background-color: #E0E059;
46 | color: black;
47 | }
48 |
--------------------------------------------------------------------------------
/config/deploy.js:
--------------------------------------------------------------------------------
1 | /* jshint node: true */
2 |
3 | module.exports = function(deployTarget) {
4 | var ENV = {
5 | build: {}
6 | // include other plugin configuration that applies to all deploy targets here
7 | };
8 |
9 | if (deployTarget === 'development') {
10 | ENV.build.environment = 'development';
11 | // configure other plugins for development deploy target here
12 | }
13 |
14 | if (deployTarget === 'staging') {
15 | ENV.build.environment = 'production';
16 | // configure other plugins for staging deploy target here
17 | }
18 |
19 | if (deployTarget === 'production') {
20 | ENV.build.environment = 'production';
21 | // configure other plugins for production deploy target here
22 | }
23 |
24 | // Note: if you need to build some configuration asynchronously, you can return
25 | // a promise that resolves with the ENV object instead of returning the
26 | // ENV object synchronously.
27 | return ENV;
28 | };
29 |
--------------------------------------------------------------------------------
/tests/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "predef": [
3 | "document",
4 | "window",
5 | "location",
6 | "setTimeout",
7 | "$",
8 | "-Promise",
9 | "define",
10 | "console",
11 | "visit",
12 | "exists",
13 | "fillIn",
14 | "click",
15 | "keyEvent",
16 | "triggerEvent",
17 | "find",
18 | "findWithAssert",
19 | "wait",
20 | "DS",
21 | "andThen",
22 | "currentURL",
23 | "currentPath",
24 | "currentRouteName"
25 | ],
26 | "node": false,
27 | "browser": false,
28 | "boss": true,
29 | "curly": true,
30 | "debug": false,
31 | "devel": false,
32 | "eqeqeq": true,
33 | "evil": true,
34 | "forin": false,
35 | "immed": false,
36 | "laxbreak": false,
37 | "newcap": true,
38 | "noarg": true,
39 | "noempty": false,
40 | "nonew": false,
41 | "nomen": false,
42 | "onevar": false,
43 | "plusplus": false,
44 | "regexp": false,
45 | "undef": true,
46 | "sub": true,
47 | "strict": false,
48 | "white": false,
49 | "eqnull": true,
50 | "esnext": true,
51 | "unused": true
52 | }
53 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Edward Faulkner
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 |
--------------------------------------------------------------------------------
/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 |
31 | {{content-for "body-footer"}}
32 | {{content-for "test-body-footer"}}
33 |
34 |
35 |
--------------------------------------------------------------------------------
/config/ember-try.js:
--------------------------------------------------------------------------------
1 | /*jshint node:true*/
2 | module.exports = {
3 | scenarios: [
4 | {
5 | name: 'default',
6 | bower: {
7 | dependencies: { }
8 | }
9 | },
10 | {
11 | name: 'ember-1-13',
12 | bower: {
13 | dependencies: {
14 | 'ember': '~1.13.0'
15 | },
16 | resolutions: {
17 | 'ember': '~1.13.0'
18 | }
19 | }
20 | },
21 | {
22 | name: 'ember-release',
23 | bower: {
24 | dependencies: {
25 | 'ember': 'components/ember#release'
26 | },
27 | resolutions: {
28 | 'ember': 'release'
29 | }
30 | }
31 | },
32 | {
33 | name: 'ember-beta',
34 | bower: {
35 | dependencies: {
36 | 'ember': 'components/ember#beta'
37 | },
38 | resolutions: {
39 | 'ember': 'beta'
40 | }
41 | }
42 | },
43 | {
44 | name: 'ember-canary',
45 | bower: {
46 | dependencies: {
47 | 'ember': 'components/ember#canary'
48 | },
49 | resolutions: {
50 | 'ember': 'canary'
51 | }
52 | }
53 | }
54 | ]
55 | };
56 |
--------------------------------------------------------------------------------
/addon/services/ember-sidebars.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 | const { Service, run, Object: EmObject } = Ember;
3 |
4 | export default Service.extend({
5 | init() {
6 | this._super();
7 | this.set('actives', EmObject.create());
8 | this._alive = {};
9 | this._counter = 1;
10 | },
11 | show(sourceId, name, component, hooks) {
12 | this._alive[sourceId] = {
13 | target: name || 'default',
14 | component,
15 | hooks,
16 | order: this._counter++
17 | };
18 | this._schedule();
19 | },
20 | clear(sourceId) {
21 | delete this._alive[sourceId];
22 | this._schedule();
23 | },
24 | _schedule() {
25 | run.scheduleOnce('afterRender', this, this._process);
26 | },
27 | _process() {
28 | let newActives = {};
29 | let alive = this._alive;
30 |
31 | Object.keys(alive).forEach(sourceId => {
32 | let { target, component, hooks, order } = alive[sourceId];
33 | let existing = newActives[target];
34 | if (!existing || existing.order < order) {
35 | newActives[target] = component ? { component, hooks, order } : null;
36 | }
37 | });
38 | this.set('actives', EmObject.create(newActives));
39 | }
40 | });
41 |
--------------------------------------------------------------------------------
/tests/dummy/app/templates/application.hbs:
--------------------------------------------------------------------------------
1 |
2 | {{#with-sidebar name="tools" as |tools|}}
3 |
4 | {{#liquid-bind tools as |tools|}}
5 | {{component tools}}
6 | {{/liquid-bind}}
7 |
8 | {{/with-sidebar}}
9 |
10 |
11 |
12 | This app demonstrates two examples of Ember Sidebars .
13 |
14 |
15 | The blue area is a sidebar named "right", rendered by \{{show-sidebar name="right"}}.
16 |
17 | The green area (visible only on some pages) is a sidebar named "tools", rendered by a \{{#with-sidebar}} component that allows it to be composed with liquid-fire animations.
18 |
19 |
20 | As you use the links below to switch between the three routes, each route can choose to place content into either of the sidebars by including \{{in-sidebar}}.
21 |
22 |
23 | {{#link-to 'index'}}First Page{{/link-to}}
24 | {{#link-to 'second'}}Second Page{{/link-to}}
25 | {{#link-to 'third'}}Third Page{{/link-to}}
26 |
27 |
28 | {{outlet}}
29 |
30 |
31 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/tests/dummy/config/environment.js:
--------------------------------------------------------------------------------
1 | /* jshint node: true */
2 |
3 | module.exports = function(environment) {
4 | var ENV = {
5 | modulePrefix: 'dummy',
6 | environment: environment,
7 | baseURL: '/',
8 | locationType: 'auto',
9 | EmberENV: {
10 | FEATURES: {
11 | // Here you can enable experimental features on an ember canary build
12 | // e.g. 'with-controller': true
13 | }
14 | },
15 |
16 | APP: {
17 | // Here you can pass flags/options to your application instance
18 | // when it is created
19 | }
20 | };
21 |
22 | if (environment === 'development') {
23 | // ENV.APP.LOG_RESOLVER = true;
24 | // ENV.APP.LOG_ACTIVE_GENERATION = true;
25 | // ENV.APP.LOG_TRANSITIONS = true;
26 | // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
27 | // ENV.APP.LOG_VIEW_LOOKUPS = true;
28 | }
29 |
30 | if (environment === 'test') {
31 | // Testem prefers this...
32 | ENV.baseURL = '/';
33 | ENV.locationType = 'none';
34 |
35 | // keep test console output quieter
36 | ENV.APP.LOG_ACTIVE_GENERATION = false;
37 | ENV.APP.LOG_VIEW_LOOKUPS = false;
38 |
39 | ENV.APP.rootElement = '#ember-testing';
40 | }
41 |
42 | if (environment === 'production') {
43 | ENV.baseURL = '/ember-sidebars';
44 | ENV.locationType = 'hash';
45 | }
46 |
47 | return ENV;
48 | };
49 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ember-sidebars",
3 | "version": "0.2.2",
4 | "description": "Composable sidebar management.",
5 | "directories": {
6 | "doc": "doc",
7 | "test": "tests"
8 | },
9 | "scripts": {
10 | "build": "ember build",
11 | "start": "ember server",
12 | "test": "ember try:testall"
13 | },
14 | "repository": "https://github.com/ef4/ember-sidebars",
15 | "engines": {
16 | "node": ">= 0.10.0"
17 | },
18 | "author": "Edward Faulkner ",
19 | "license": "MIT",
20 | "devDependencies": {
21 | "broccoli-asset-rev": "^2.2.0",
22 | "ember-ajax": "0.7.1",
23 | "ember-cli": "2.4.1",
24 | "ember-cli-app-version": "^1.0.0",
25 | "ember-cli-dependency-checker": "^1.2.0",
26 | "ember-cli-deploy": "0.6.0",
27 | "ember-cli-deploy-build": "0.1.1",
28 | "ember-cli-deploy-git": "0.1.0",
29 | "ember-cli-htmlbars-inline-precompile": "^0.3.1",
30 | "ember-cli-inject-live-reload": "^1.3.1",
31 | "ember-cli-qunit": "^1.2.1",
32 | "ember-cli-release": "0.2.8",
33 | "ember-cli-sri": "^2.1.0",
34 | "ember-cli-uglify": "^1.2.0",
35 | "ember-code-snippet": "1.2.1",
36 | "ember-data": "^2.4.0",
37 | "ember-disable-prototype-extensions": "^1.1.0",
38 | "ember-disable-proxy-controllers": "^1.0.1",
39 | "ember-export-application-global": "^1.0.4",
40 | "ember-load-initializers": "^0.5.0",
41 | "ember-resolver": "^2.0.3",
42 | "ember-try": "^0.1.2",
43 | "liquid-fire": "0.23.0",
44 | "loader.js": "^4.0.0"
45 | },
46 | "keywords": [
47 | "ember-addon"
48 | ],
49 | "dependencies": {
50 | "ember-cli-babel": "^5.1.5",
51 | "ember-cli-htmlbars": "^1.0.1"
52 | },
53 | "ember-addon": {
54 | "configPath": "tests/dummy/config",
55 | "demoURL": "http://ef4.github.io/ember-sidebars/"
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/tests/unit/services/ember-sidebars-test.js:
--------------------------------------------------------------------------------
1 | import { moduleFor, test } from 'ember-qunit';
2 | import run from 'ember-runloop';
3 |
4 | moduleFor('service:ember-sidebars', 'Unit | Service | ember sidebars', {
5 | });
6 |
7 | test('it exposes currently active component', function(assert) {
8 | let service = this.subject();
9 | let component = {};
10 |
11 | run(() => {
12 | service.show('source', 'my-sidebar', component);
13 | });
14 |
15 | assert.equal(service.get('actives.my-sidebar.component'), component);
16 | });
17 |
18 | test('it removes cleared component', function(assert) {
19 | let service = this.subject();
20 | let component = {};
21 |
22 | run(() => {
23 | service.show('source', 'my-sidebar', component);
24 | });
25 |
26 | run(() => {
27 | service.clear('source');
28 | });
29 |
30 | assert.equal(service.get('actives.my-sidebar.component'), undefined);
31 | });
32 |
33 | test('last shown source wins', function(assert) {
34 | let service = this.subject();
35 | let componentA = {};
36 | let componentB = {};
37 |
38 | run(() => {
39 | service.show('sourceA', 'my-sidebar', componentA);
40 | service.show('sourceB', 'my-sidebar', componentB);
41 | });
42 |
43 | assert.equal(service.get('actives.my-sidebar.component'), componentB);
44 |
45 | run(() => {
46 | service.show('sourceB', 'my-sidebar', componentB);
47 | service.show('sourceA', 'my-sidebar', componentA);
48 | });
49 |
50 | assert.equal(service.get('actives.my-sidebar.component'), componentA);
51 |
52 | });
53 |
54 | test('earlier shown source takes back over when later source clears', function(assert) {
55 | let service = this.subject();
56 | let componentA = {};
57 | let componentB = {};
58 |
59 | run(() => {
60 | service.show('sourceA', 'my-sidebar', componentA);
61 | service.show('sourceB', 'my-sidebar', componentB);
62 | });
63 |
64 | assert.equal(service.get('actives.my-sidebar.component'), componentB);
65 |
66 | run(() => {
67 | service.clear('sourceB');
68 | });
69 |
70 | assert.equal(service.get('actives.my-sidebar.component'), componentA);
71 |
72 | });
73 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # This addon has been superceded by [ember-elsewhere](https://github.com/ef4/ember-elsewhere)
2 |
3 | Because it's really not just about sidebars, so it needed some better naming.
4 |
5 | # ember-sidebars
6 |
7 | [![NPM][npm-badge-img]][npm-badge-link]
8 | [![Ember Observer Score][ember-observer-badge]][ember-observer-url]
9 | ![Ember Version][ember-version]
10 |
11 | This addon makes it easy to manage sidebars, toolbars, or any piece of DOM that you want to lift outside your normal route hiearchy.
12 |
13 | It is similar to [ember-wormhole](https://github.com/yapplabs/ember-wormhole), but is more suitable when your target is your own Ember component (as opposed to arbitrary, potentially foreign DOM).
14 |
15 | The best documentation is the sample application in `tests/dummy`, which is also running at [http://ef4.github.io/ember-sidebars/](http://ef4.github.io/ember-sidebars/).
16 |
17 | ## Install
18 |
19 | ```no-highlight
20 | ember install ember-sidebars
21 | ```
22 |
23 | ## Components
24 |
25 | Create a sidebar named "my-right-sidebar":
26 |
27 | ```hbs
28 | {{show-sidebar name="my-right-sidebar"}}
29 | ```
30 |
31 | From elsewhere, declare which component should render in the sidebar -- complete with bound inputs and actions:
32 |
33 |
34 | ```hbs
35 | {{in-sidebar name="my-right-sidebar" show=(component "cool-thing" model=model launch=(action "launchIt"))}}
36 | ```
37 |
38 | For fancier behaviors, you can use `{{#with-sidebar}}` instead of `{{show-sidebar}}` which gives you an opportunity to extend the sidebar's behavior in arbitrary ways. For example, this lets your sidebar animate as its content changes:
39 |
40 | ```hbs
41 | {{#with-sidebar name="my-right-sidebar" as |sidebar|}}
42 |
43 | {{#liquid-bind sidebar as |currentSidebar|}}
44 | {{component currentSidebar}}
45 | {{/liquid-bind}}
46 |
47 | {{/with-sidebar}}
48 | ```
49 |
50 | ember-sidebars is also a great way to do modals, since modals are just another thing that you want to render "elsewhere" in the DOM. [Here is a gist with an example.](https://gist.github.com/ef4/0bcc6f7c99dafffdf6cc)
51 |
52 | ## Passing additional state through to sidebar
53 |
54 | Sometime you may want to pass an action or value into the sidebar that is accessible outside the closed-over component. There is an optional `hooks` argument for that.
55 |
56 | ```hbs
57 | {{in-sidebar name="modal" component=(component "warning-message") hooks=(hash onOutsideClick=(action "close"))}}
58 | ```
59 |
60 | ```hbs
61 | {{#with-sidebar name="modal" as |modalContent hooks|}}
62 |
63 |
64 | {{component modalContent}}
65 |
66 |
67 | {{/with-sidebar}}
68 | ```
69 |
70 | A more comprehensive example of the above modal behavior [is available here](https://gist.github.com/ef4/0bcc6f7c99dafffdf6cc).
71 |
72 | ## Installation
73 |
74 | * `git clone` this repository
75 | * `npm install`
76 | * `bower install`
77 |
78 | ## Running
79 |
80 | * `ember server`
81 | * Visit your app at http://localhost:4200.
82 |
83 | ## Running Tests
84 |
85 | * `npm test` (Runs `ember try:testall` to test your addon against multiple Ember versions)
86 | * `ember test`
87 | * `ember test --server`
88 |
89 | ## Building
90 |
91 | * `ember build`
92 |
93 | For more information on using ember-cli, visit [http://www.ember-cli.com/](http://www.ember-cli.com/).
94 |
95 | [npm-badge-img]: https://badge.fury.io/js/ember-sidebars.svg
96 | [npm-badge-link]: http://badge.fury.io/js/ember-sidebars
97 | [ember-observer-badge]: http://emberobserver.com/badges/ember-sidebars.svg
98 | [ember-observer-url]: http://emberobserver.com/addons/ember-sidebars
99 | [ember-version]: https://embadge.io/v1/badge.svg?start=1.13.0
100 |
--------------------------------------------------------------------------------