├── .editorconfig ├── .eslintrc.json ├── .github ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md └── ISSUE_TEMPLATE.md ├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE ├── README.md ├── bower.json ├── build ├── args.js ├── babel-options.js ├── paths.js ├── tasks │ ├── build.js │ ├── clean.js │ ├── dev.js │ ├── doc.js │ ├── lint.js │ ├── prepare-release.js │ ├── serve.js │ ├── test.js │ └── watch.js └── typescript-options.js ├── config.js ├── dist ├── amd │ ├── aurelia-notify.js │ ├── bs-notification.html │ ├── bs-notification.js │ ├── index.js │ ├── lifecycle.js │ ├── notification-controller.js │ ├── notification-level.js │ ├── notification-renderer.js │ ├── notification-service.js │ └── style.css ├── aurelia-notify.d.ts ├── aurelia-notify.js ├── commonjs │ ├── aurelia-notify.js │ ├── bs-notification.html │ ├── bs-notification.js │ ├── index.js │ ├── lifecycle.js │ ├── notification-controller.js │ ├── notification-level.js │ ├── notification-renderer.js │ ├── notification-service.js │ └── style.css ├── es2015 │ ├── aurelia-notify.js │ ├── bs-notification.html │ ├── bs-notification.js │ ├── index.js │ ├── lifecycle.js │ ├── notification-controller.js │ ├── notification-level.js │ ├── notification-renderer.js │ ├── notification-service.js │ └── style.css ├── native-modules │ ├── aurelia-notify.js │ ├── bs-notification.html │ ├── bs-notification.js │ ├── index.js │ ├── lifecycle.js │ ├── notification-controller.js │ ├── notification-level.js │ ├── notification-renderer.js │ ├── notification-service.js │ └── style.css ├── system │ ├── aurelia-notify.js │ ├── bs-notification.html │ ├── bs-notification.js │ ├── index.js │ ├── lifecycle.js │ ├── notification-controller.js │ ├── notification-level.js │ ├── notification-renderer.js │ ├── notification-service.js │ └── style.css └── temp │ └── aurelia-notify.js ├── doc ├── CHANGELOG.md ├── Intro.md ├── api.json └── core-js.d.ts ├── gulpfile.js ├── karma.conf.js ├── package-lock.json ├── package.json ├── sample ├── config.js ├── index.html ├── package.json └── src │ ├── app.html │ ├── app.js │ └── main.js ├── src ├── aurelia-notify.js ├── bs-notification.html ├── bs-notification.js ├── lifecycle.js ├── notification-controller.js ├── notification-level.js ├── notification-renderer.js ├── notification-service.js └── style.css ├── test └── unit │ ├── aurelia-notify.spec.js │ ├── bs-notification.spec.js │ ├── lifecycle.spec.js │ ├── notification-controller.spec.js │ ├── notification-level.spec.js │ ├── notification-renderer.spec.js │ ├── notification-service.spec.js │ └── setup.js ├── tsconfig.json ├── typings.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | 11 | # 2 space indentation 12 | [**.*] 13 | indent_style = space 14 | indent_size = 2 -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/aurelia-tools/.eslintrc.json" 3 | } 4 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at mail@cycrilab.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We'd love for you to contribute and to make this project even better than it is today! 4 | Here are the guidelines we'd like you to follow: 5 | 6 | - [Question or Problem?](#question) 7 | - [Issues and Bugs](#issue) 8 | - [Feature Requests](#feature) 9 | - [Docs Improvements](#docs) 10 | - [Submission Guidelines](#submit) 11 | - [Coding Rules](#rules) 12 | - [Commit Message Guidelines](#commit) 13 | 14 | ## Got a Question or Problem? 15 | 16 | If you have questions about how to use our plugins, please direct these to the respective repository issues 17 | or [StackOverflow][stackoverflow]. 18 | 19 | ## Found an Issue? 20 | If you find a bug in the source code or a mistake in the documentation, you can help us by 21 | submitting an issue to our [GitHub Repository][github]. Even better you can submit a Pull Request 22 | with a fix. 23 | 24 | **Please see the Submission Guidelines below**. 25 | 26 | ## Want a Feature? 27 | You can request a new feature by submitting an issue to our [GitHub Repository][github]. If you 28 | would like to implement a new feature then consider what kind of change it is: 29 | 30 | * **Major Changes** that you wish to contribute to the project should be discussed first 31 | so that we can better coordinate our efforts, prevent duplication of work, and help you to 32 | craft the change so that it is successfully accepted into the project. 33 | * **Small Changes** can be crafted and submitted to the [GitHub Repository][github] as a Pull Request. 34 | 35 | 36 | ## Want a Doc Fix? 37 | If you want to help improve the docs, it's a good idea to let others know what you're working on to 38 | minimize duplication of effort. Before starting, check out the open issues. 39 | Comment on an issue to let others know what you're working on, or create a new issue if your work 40 | doesn't fit within the scope of any of the existing doc fix projects. 41 | 42 | For large fixes, please build and test the documentation before submitting the Pull Request to be 43 | sure you haven't accidentally introduced any layout or formatting issues. You should also make 44 | sure that your commit message is labeled "docs:" and follows the **Git Commit Guidelines** outlined below. 45 | 46 | ## Submission Guidelines 47 | 48 | ### Submitting an Issue 49 | Before you submit your issue search the archive, maybe your question was already answered. 50 | 51 | If your issue appears to be a bug, and hasn't been reported, open a new issue. 52 | Help us to maximize the effort we can spend fixing issues and adding new 53 | features, by not reporting duplicate issues. Providing the following information will 54 | increase the chances of your issue being dealt with quickly: 55 | 56 | * **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps 57 | * **Motivation for or Use Case** - explain why this is a bug for you 58 | * **Version(s)** - is it a regression? 59 | * **Browsers and Operating System** - is this a problem with all browsers or only IE8? 60 | * **Reproduce the Error** - provide a live example (using Plunker or 61 | JSFiddle) or an unambiguous set of steps. 62 | * **Related Issues** - has a similar issue been reported before? 63 | * **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be 64 | causing the problem (line of code or commit) 65 | 66 | ### Submitting a Pull Request 67 | Before you submit your pull request consider the following guidelines: 68 | 69 | * Search the repository for an open or closed Pull Request 70 | that relates to your submission. You don't want to duplicate effort. 71 | * Make your changes in a new git branch: 72 | 73 | ```shell 74 | git checkout -b my-fix-branch master 75 | ``` 76 | 77 | * Create your patch, **including appropriate test cases**. 78 | * Follow our [Coding Rules](#rules). 79 | * Commit your changes using a descriptive commit message that follows our 80 | [commit message conventions](#commit-message-format). Adherence to 81 | the [commit message conventions](#commit-message-format) 82 | is required because release notes are automatically generated from these messages. 83 | 84 | ```shell 85 | git commit -a 86 | ``` 87 | Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files. 88 | 89 | * Build your changes locally to ensure all the tests pass: 90 | 91 | ```shell 92 | gulp test 93 | ``` 94 | 95 | * Push your branch to GitHub: 96 | 97 | ```shell 98 | git push origin my-fix-branch 99 | ``` 100 | 101 | * In GitHub, send a pull request to the `master` branch. 102 | * If we suggest changes then: 103 | * Make the required updates. 104 | * Commit your changes to your branch (e.g. `my-fix-branch`). 105 | * Push the changes to your GitHub repository (this will update your Pull Request). 106 | 107 | If the PR gets too outdated we may ask you to rebase and force push to update the PR: 108 | 109 | ```shell 110 | git rebase master -i 111 | git push origin my-fix-branch -f 112 | ``` 113 | 114 | *WARNING. Squashing or reverting commits and forced push thereafter may remove GitHub comments 115 | on code that were previously made by you and others in your commits.* 116 | 117 | #### After your pull request is merged 118 | 119 | After your pull request is merged, you can safely delete your branch and pull the changes 120 | from the main (upstream) repository: 121 | 122 | * Delete the remote branch on GitHub either through the GitHub web UI or your local shell as follows: 123 | 124 | ```shell 125 | git push origin --delete my-fix-branch 126 | ``` 127 | 128 | * Check out the master branch: 129 | 130 | ```shell 131 | git checkout master -f 132 | ``` 133 | 134 | * Delete the local branch: 135 | 136 | ```shell 137 | git branch -D my-fix-branch 138 | ``` 139 | 140 | * Update your master with the latest upstream version: 141 | 142 | ```shell 143 | git pull --ff upstream master 144 | ``` 145 | 146 | ## Coding Rules 147 | To ensure consistency throughout the source code, keep these rules in mind as you are working: 148 | 149 | * All features or bug fixes **must be tested** by one or more specs. 150 | * All public API methods **must be documented**. 151 | * Code should be check against our **lint rules**: ```gulp lint```. 152 | 153 | ## Git Commit Guidelines 154 | 155 | We have very precise rules over how our git commit messages can be formatted. This leads to **more 156 | readable messages** that are easy to follow when looking through the **project history**. But also, 157 | we use the git commit messages to **generate the change logs**. 158 | 159 | The commit message formatting can be added using a typical git workflow 160 | or through the use of a CLI wizard ([Commitizen](https://github.com/commitizen/cz-cli)). 161 | To use the wizard, run `npm run commit` in your terminal after staging your changes in git. 162 | 163 | ### Commit Message Format 164 | Each commit message consists of a **header** and a **body**. The header has a special 165 | format that includes a **type**, a **scope**, and a **subject**: 166 | 167 | ``` 168 | (): 169 | 170 | 171 | ``` 172 | 173 | The **header** is mandatory and the **scope** of the header is optional. 174 | 175 | The header line cannot be longer than 50 characters, any other line 176 | cannot be longer than 72 characters! This allows 177 | the message to be easier to read on GitHub as well as in various git tools. 178 | 179 | ### Revert 180 | If the commit reverts a previous commit, it should begin with `revert: `, 181 | followed by the header of the reverted commit. In the body it should 182 | say: `This reverts commit .`, where the hash is the SHA of the commit being reverted. 183 | 184 | ### Type 185 | Must be one of the following: 186 | 187 | * **feat**: A new feature 188 | * **fix**: A bug fix 189 | * **docs**: Documentation only changes 190 | * **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing 191 | semi-colons, etc) 192 | * **refactor**: A code change that neither fixes a bug nor adds a feature 193 | * **perf**: A code change that improves performance 194 | * **test**: Adding missing tests 195 | * **chore**: Changes to the build process or auxiliary tools and libraries such as documentation 196 | generation 197 | 198 | ### Scope 199 | The scope could be anything specifying place of the commit change. 200 | 201 | ### Subject 202 | The subject contains succinct description of the change: 203 | 204 | * use the imperative, present tense: "change" not "changed" nor "changes" 205 | * don't capitalize first letter 206 | * no dot (.) at the end 207 | 208 | ### Body 209 | Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes". 210 | The body should include the motivation for the change and contrast this with previous behavior. 211 | 212 | **Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. 213 | The rest of the commit message is then used for this. 214 | 215 | [github]: https://github.com/MarcScheib/aurelia-notify 216 | [stackoverflow]: http://stackoverflow.com/ 217 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | **I'm submitting a ...** (check one with "x") 6 | ``` 7 | [ ] bug report => search github for a similar issue or PR before submitting 8 | [ ] feature request 9 | ``` 10 | 11 | **Current behavior** 12 | 13 | 14 | **Expected behavior** 15 | 16 | 17 | **Minimal reproduction of the problem with instructions** 18 | 23 | 24 | **What is the motivation / use case for changing the behavior?** 25 | 26 | 27 | **Please tell us about your environment:** 28 | 29 | 30 | * **Version:** x.y.z 31 | 32 | 33 | * **Browser:** [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ] 34 | 35 | 36 | * **Language:** [all | TypeScript X.X | ES6/7 | ES5] 37 | 38 | * **Node (for AoT issues):** `node --version` = 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | jspm_packages 3 | bower_components 4 | .idea 5 | .DS_STORE 6 | *.swp 7 | build/reports 8 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | jspm_packages 2 | bower_components 3 | .idea -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | sudo: false 3 | node_js: 4 | - 'stable' 5 | 6 | notifications: 7 | email: false 8 | 9 | cache: 10 | directories: 11 | - node_modules 12 | - jspm_packages 13 | 14 | branches: 15 | only: 16 | - master 17 | - develop 18 | 19 | install: 20 | - npm install 21 | - ./node_modules/.bin/jspm config registries.github.auth $GH_TOKEN 22 | - ./node_modules/.bin/jspm install 23 | 24 | before_script: 25 | - export CHROME_BIN=chromium-browser 26 | - export DISPLAY=:99.0 27 | - sh -e /etc/init.d/xvfb start 28 | 29 | script: 30 | - ./node_modules/.bin/gulp build 31 | - ./node_modules/.bin/gulp coveralls 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 - 2017 Marc Scheib 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # aurelia-notify 2 | 3 | [![Build Status](https://img.shields.io/travis/MarcScheib/aurelia-notify/master.svg?style=flat-square)](https://travis-ci.org/MarcScheib/aurelia-notify) 4 | [![Coverage Status](https://img.shields.io/coveralls/MarcScheib/aurelia-notify/master.svg?style=flat-square)](https://coveralls.io/github/MarcScheib/aurelia-notify?branch=master) 5 | [![Dependency Status](https://img.shields.io/david/MarcScheib/aurelia-notify.svg?style=flat-square)](https://david-dm.org/MarcScheib/aurelia-notify) 6 | [![devDependency Status](https://img.shields.io/david/dev/MarcScheib/aurelia-notify.svg?style=flat-square)](https://david-dm.org/MarcScheib/aurelia-notify?type=dev) 7 | [![npm Version](https://img.shields.io/npm/v/aurelia-notify.svg?style=flat-square)](https://www.npmjs.com/package/aurelia-notify) 8 | 9 | A simple notification plugin for [Aurelia](http://www.aurelia.io/). 10 | 11 | ``` javascript 12 | notification.info('A simple info notification'); 13 | ``` 14 | 15 | ## Documentation 16 | 17 | - [Installation](https://github.com/MarcScheib/aurelia-notify/blob/master/doc/Intro.md#installation) 18 | - [Getting started](https://github.com/MarcScheib/aurelia-notify/blob/master/doc/Intro.md#getting-started) 19 | - [Configuration](https://github.com/MarcScheib/aurelia-notify/blob/master/doc/Intro.md#configuration) 20 | - [Customization](https://github.com/MarcScheib/aurelia-notify/blob/master/doc/Intro.md#customization) 21 | 22 | ## Dependencies 23 | 24 | This plugin has no external library dependencies and is completely based on [Aurelia](http://www.aurelia.io/). 25 | 26 | Aurelia dependencies: 27 | 28 | * [aurelia-dependency-injection](https://github.com/aurelia/dependency-injection) 29 | * [aurelia-metadata](https://github.com/aurelia/metadata) 30 | * [aurelia-pal](https://github.com/aurelia/pal) 31 | * [aurelia-templating](https://github.com/aurelia/templating) 32 | 33 | ## Used By 34 | 35 | This library is an optional plugin and not used by the core framework. 36 | 37 | ## Platform Support 38 | 39 | This library can be used in the **browser**. 40 | 41 | ## Building The Code 42 | 43 | To build the code, follow these steps. 44 | 45 | 1. Ensure that [NodeJS](http://nodejs.org/) is installed. This provides the platform on which the build tooling runs. 46 | 2. From the project folder, execute the following command: 47 | 48 | ```shell 49 | npm install 50 | ``` 51 | 3. Ensure that [Gulp](http://gulpjs.com/) is installed. If you need to install it, use the following command: 52 | 53 | ```shell 54 | npm install -g gulp 55 | ``` 56 | 4. To build the code, you can now run: 57 | 58 | ```shell 59 | gulp build 60 | ``` 61 | 5. You will find the compiled code in the `dist` folder, available in three module formats: AMD, CommonJS and ES6. 62 | 63 | 6. See `gulpfile.js` for other tasks related to generating the docs and linting. 64 | 65 | ## Running The Tests 66 | 67 | To run the unit tests, first ensure that you have followed the steps above in order to install all dependencies and successfully build the library. Once you have done that, proceed with these additional steps: 68 | 69 | 1. Ensure that the [Karma](http://karma-runner.github.io/) CLI is installed. If you need to install it, use the following command: 70 | 71 | ```shell 72 | npm install -g karma-cli 73 | ``` 74 | 2. Ensure that [jspm](http://jspm.io/) is installed. If you need to install it, use the following commnand: 75 | 76 | ```shell 77 | npm install -g jspm 78 | ``` 79 | 3. Install the client-side dependencies with jspm: 80 | 81 | ```shell 82 | jspm install 83 | ``` 84 | 4. Ensure that you have Chrome installed. Karma runs the test suite in Chrome. 85 | 86 | 5. You can now run the tests with this command: 87 | 88 | ```shell 89 | karma start 90 | ``` 91 | 92 | ## Running The Sample 93 | 94 | To run the sample code using this plugin proceed with these additional steps: 95 | 96 | 1. Go to the `sample` directory and install dependencies using `jspm`: 97 | 98 | ```shell 99 | cd sample 100 | jspm install 101 | ``` 102 | 2. Go back to the root of the project and use gulp to serve the sample project: 103 | 104 | ```shell 105 | cd .. 106 | gulp watch 107 | ``` 108 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aurelia-notify", 3 | "version": "0.8.1", 4 | "description": "A notification plugin for Aurelia.", 5 | "keywords": [ 6 | "aurelia", 7 | "notify", 8 | "notifications", 9 | "plugin" 10 | ], 11 | "homepage": "http://aurelia.io", 12 | "main": "dist/commonjs/aurelia-notify.js", 13 | "moduleType": "node", 14 | "license": "MIT", 15 | "authors": [ 16 | "Marc Scheib (http://cycrilab.com/)" 17 | ], 18 | "repository": { 19 | "type": "git", 20 | "url": "https://github.com/MarcScheib/aurelia-notify" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /build/args.js: -------------------------------------------------------------------------------- 1 | var yargs = require('yargs'); 2 | 3 | var argv = yargs.argv, 4 | validBumpTypes = "major|minor|patch|prerelease".split("|"), 5 | bump = (argv.bump || 'patch').toLowerCase(); 6 | 7 | if(validBumpTypes.indexOf(bump) === -1) { 8 | throw new Error('Unrecognized bump "' + bump + '".'); 9 | } 10 | 11 | module.exports = { 12 | bump: bump 13 | }; 14 | -------------------------------------------------------------------------------- /build/babel-options.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var paths = require('./paths'); 3 | 4 | exports.base = function () { 5 | var config = { 6 | filename: '', 7 | filenameRelative: '', 8 | sourceRoot: '', 9 | moduleRoot: path.resolve('src').replace(/\\/g, '/'), 10 | moduleIds: false, 11 | comments: false, 12 | compact: false, 13 | code: true, 14 | presets: [['es2015', {'loose': true}], 'stage-1'], 15 | plugins: [ 16 | 'syntax-flow', 17 | 'transform-decorators-legacy' 18 | ] 19 | }; 20 | 21 | if (!paths.useTypeScriptForDTS) { 22 | config.plugins.push( 23 | ['babel-dts-generator', { 24 | packageName: paths.packageName, 25 | typings: '', 26 | suppressModulePath: true, 27 | suppressComments: false, 28 | memberOutputFilter: /^_.*/, 29 | suppressAmbientDeclaration: true 30 | }] 31 | ); 32 | } 33 | config.plugins.push('transform-flow-strip-types'); 34 | return config; 35 | }; 36 | 37 | exports.commonjs = function () { 38 | var options = exports.base(); 39 | options.plugins.push('transform-es2015-modules-commonjs'); 40 | return options; 41 | }; 42 | 43 | exports.amd = function () { 44 | var options = exports.base(); 45 | options.plugins.push('transform-es2015-modules-amd'); 46 | return options; 47 | }; 48 | 49 | exports.system = function () { 50 | var options = exports.base(); 51 | options.plugins.push('transform-es2015-modules-systemjs'); 52 | return options; 53 | }; 54 | 55 | exports.es2015 = function () { 56 | var options = exports.base(); 57 | options.presets = ['stage-1']; 58 | return options; 59 | }; 60 | 61 | exports['native-modules'] = function () { 62 | var options = exports.base(); 63 | options.presets[0].modules = false; 64 | return options; 65 | }; 66 | -------------------------------------------------------------------------------- /build/paths.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var fs = require('fs'); 3 | 4 | // hide warning // 5 | var emitter = require('events'); 6 | emitter.defaultMaxListeners = 20; 7 | 8 | var appRoot = 'src/'; 9 | var pkg = JSON.parse(fs.readFileSync('./package.json', 'utf-8')); 10 | 11 | var paths = { 12 | root: appRoot, 13 | source: appRoot + '**/*.js', 14 | html: appRoot + '**/*.html', 15 | style: appRoot + '**/*.css', 16 | styleFolder: './styles', 17 | output: 'dist/', 18 | sample: 'sample', 19 | doc: './doc', 20 | tests: 'test/**/*.js', 21 | e2eSpecsSrc: 'test/e2e/src/*.js', 22 | e2eSpecsDist: 'test/e2e/dist/', 23 | packageName: pkg.name, 24 | useTypeScriptForDTS: false, 25 | importsToAdd: [], 26 | sort: true 27 | }; 28 | 29 | paths.ignore = ['aurelia-notify.js']; 30 | paths.files = [ 31 | 'bs-notification.js', 32 | 'lifecycle.js', 33 | 'notification-controller.js', 34 | 'notification-level.js', 35 | 'notification-renderer.js', 36 | 'notification-service.js' 37 | ].map(function(file) { 38 | return paths.root + file; 39 | }); 40 | 41 | module.exports = paths; 42 | -------------------------------------------------------------------------------- /build/tasks/build.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var runSequence = require('run-sequence'); 3 | var to5 = require('gulp-babel'); 4 | var paths = require('../paths'); 5 | var compilerOptions = require('../babel-options'); 6 | var compilerTsOptions = require('../typescript-options'); 7 | var assign = Object.assign || require('object.assign'); 8 | var through2 = require('through2'); 9 | var concat = require('gulp-concat'); 10 | var insert = require('gulp-insert'); 11 | var rename = require('gulp-rename'); 12 | var tools = require('aurelia-tools'); 13 | var ts = require('gulp-typescript'); 14 | var gutil = require('gulp-util'); 15 | var gulpIgnore = require('gulp-ignore'); 16 | var merge = require('merge2'); 17 | var jsName = paths.packageName + '.js'; 18 | var compileToModules = ['es2015', 'commonjs', 'amd', 'system', 'native-modules']; 19 | 20 | function cleanGeneratedCode() { 21 | return through2.obj(function(file, enc, callback) { 22 | file.contents = new Buffer(tools.cleanGeneratedCode(file.contents.toString('utf8'))); 23 | this.push(file); 24 | return callback(); 25 | }); 26 | } 27 | 28 | function removeDTSPlugin(options) { 29 | var found = options.plugins.find(function(x) { 30 | return x instanceof Array; 31 | }); 32 | 33 | var index = options.plugins.indexOf(found); 34 | options.plugins.splice(index, 1); 35 | return options; 36 | } 37 | 38 | gulp.task('build-index', function() { 39 | var importsToAdd = paths.importsToAdd.slice(); 40 | 41 | var src = gulp.src(paths.files); 42 | if (paths.sort) { 43 | src = src.pipe(tools.sortFiles()); 44 | } 45 | 46 | if (paths.ignore) { 47 | paths.ignore.forEach(function(filename) { 48 | src = src.pipe(gulpIgnore.exclude(filename)); 49 | }); 50 | } 51 | 52 | return src 53 | .pipe(through2.obj(function(file, enc, callback) { 54 | file.contents = new Buffer(tools.extractImports(file.contents.toString('utf8'), importsToAdd)); 55 | this.push(file); 56 | return callback(); 57 | })) 58 | .pipe(concat(jsName)) 59 | .pipe(insert.transform(function(contents) { 60 | return tools.createImportBlock(importsToAdd) + contents; 61 | })) 62 | .pipe(gulp.dest(paths.output)); 63 | }); 64 | 65 | gulp.task('build-es2015-temp', function() { 66 | return gulp.src(paths.output + jsName) 67 | .pipe(to5(assign({}, compilerOptions.commonjs()))) 68 | .pipe(gulp.dest(paths.output + 'temp')); 69 | }); 70 | 71 | function gulpFileFromString(filename, string) { 72 | var src = require('stream').Readable({objectMode: true}); 73 | src._read = function() { 74 | this.push(new gutil.File({cwd: paths.appRoot, base: paths.output, path: filename, contents: new Buffer(string)})); 75 | this.push(null); 76 | }; 77 | return src; 78 | } 79 | 80 | function srcForBabel() { 81 | return merge( 82 | gulp.src(paths.source), 83 | gulpFileFromString(paths.output + 'index.js', "export * from './" + paths.packageName + "';") 84 | ); 85 | } 86 | 87 | function srcForTypeScript() { 88 | return gulp 89 | .src(paths.output + paths.packageName + '.js') 90 | .pipe(rename(function(path) { 91 | if (path.extname === '.js') { 92 | path.extname = '.ts'; 93 | } 94 | })); 95 | } 96 | 97 | compileToModules.forEach(function(moduleType) { 98 | gulp.task('build-babel-' + moduleType, function() { 99 | return srcForBabel() 100 | .pipe(to5(assign({}, removeDTSPlugin(compilerOptions[moduleType]())))) 101 | .pipe(cleanGeneratedCode()) 102 | .pipe(gulp.dest(paths.output + moduleType)); 103 | }); 104 | 105 | gulp.task('build-html-' + moduleType, function() { 106 | return gulp.src(paths.html) 107 | .pipe(gulp.dest(paths.output + moduleType)); 108 | }); 109 | 110 | gulp.task('build-css-' + moduleType, function() { 111 | return gulp.src(paths.style) 112 | .pipe(gulp.dest(paths.output + moduleType)); 113 | }); 114 | 115 | if (moduleType === 'native-modules') return; // typescript doesn't support the combination of: es5 + native modules 116 | 117 | gulp.task('build-ts-' + moduleType, function() { 118 | var tsProject = ts.createProject( 119 | compilerTsOptions({ 120 | module: moduleType, 121 | target: moduleType === 'es2015' ? 'es2015' : 'es5' 122 | }), ts.reporter.defaultReporter()); 123 | var tsResult = srcForTypeScript().pipe(tsProject()); 124 | return tsResult.js 125 | .pipe(gulp.dest(paths.output + moduleType)); 126 | }); 127 | }); 128 | 129 | gulp.task('build-dts', function() { 130 | var tsProject = ts.createProject(compilerTsOptions( 131 | { 132 | removeComments: false, 133 | target: 'es2015', 134 | module: 'es2015' 135 | }), ts.reporter.defaultReporter()); 136 | var tsResult = srcForTypeScript().pipe(tsProject()); 137 | return tsResult.dts 138 | .pipe(gulp.dest(paths.output)); 139 | }); 140 | 141 | gulp.task('build', function(callback) { 142 | return runSequence( 143 | 'clean', 144 | 'build-index', 145 | 'build-es2015-temp', 146 | compileToModules.map(function(moduleType) { 147 | return 'build-babel-' + moduleType; 148 | }).concat(paths.useTypeScriptForDTS ? ['build-dts'] : []), 149 | compileToModules.map(function(moduleType) { 150 | return 'build-html-' + moduleType; 151 | }), 152 | compileToModules.map(function(moduleType) { 153 | return 'build-css-' + moduleType; 154 | }), 155 | callback 156 | ); 157 | }); 158 | 159 | gulp.task('build-ts', function(callback) { 160 | return runSequence( 161 | 'clean', 162 | 'build-index', 163 | 'build-babel-native-modules', 164 | compileToModules 165 | .filter(function(moduleType) { 166 | return moduleType !== 'native-modules'; 167 | }) 168 | .map(function(moduleType) { 169 | return 'build-ts-' + moduleType; 170 | }) 171 | .concat(paths.useTypeScriptForDTS ? ['build-dts'] : []), 172 | callback 173 | ); 174 | }); 175 | -------------------------------------------------------------------------------- /build/tasks/clean.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var paths = require('../paths'); 3 | var del = require('del'); 4 | var vinylPaths = require('vinyl-paths'); 5 | 6 | gulp.task('clean', function() { 7 | return gulp.src([paths.output]) 8 | .pipe(vinylPaths(del)); 9 | }); 10 | -------------------------------------------------------------------------------- /build/tasks/dev.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var tools = require('aurelia-tools'); 3 | 4 | gulp.task('update-own-deps', function(){ 5 | tools.updateOwnDependenciesFromLocalRepositories(); 6 | }); 7 | 8 | gulp.task('build-dev-env', function () { 9 | tools.buildDevEnv(); 10 | }); 11 | -------------------------------------------------------------------------------- /build/tasks/doc.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var paths = require('../paths'); 3 | var typedoc = require('gulp-typedoc'); 4 | var runSequence = require('run-sequence'); 5 | var through2 = require('through2'); 6 | 7 | gulp.task('doc-generate', function() { 8 | return gulp.src([paths.output + paths.packageName + '.d.ts']) 9 | .pipe(typedoc({ 10 | target: 'es6', 11 | includeDeclarations: true, 12 | moduleResolution: 'node', 13 | json: paths.doc + '/api.json', 14 | name: paths.packageName + '-docs', 15 | mode: 'modules', 16 | excludeExternals: true, 17 | ignoreCompilerErrors: false, 18 | version: true 19 | })); 20 | }); 21 | 22 | gulp.task('doc-shape', function() { 23 | return gulp.src([paths.doc + '/api.json']) 24 | .pipe(through2.obj(function(file, enc, callback) { 25 | var json = JSON.parse(file.contents.toString('utf8')).children[0]; 26 | 27 | json = { 28 | name: paths.packageName, 29 | children: json.children, 30 | groups: json.groups 31 | }; 32 | 33 | file.contents = new Buffer(JSON.stringify(json)); 34 | this.push(file); 35 | return callback(); 36 | })) 37 | .pipe(gulp.dest(paths.doc)); 38 | }); 39 | 40 | gulp.task('doc', function(callback) { 41 | return runSequence( 42 | 'doc-generate', 43 | 'doc-shape', 44 | callback 45 | ); 46 | }); 47 | -------------------------------------------------------------------------------- /build/tasks/lint.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var paths = require('../paths'); 3 | var eslint = require('gulp-eslint'); 4 | 5 | gulp.task('lint', function() { 6 | return gulp.src(paths.source) 7 | .pipe(eslint()) 8 | .pipe(eslint.format()) 9 | .pipe(eslint.failOnError()); 10 | }); 11 | -------------------------------------------------------------------------------- /build/tasks/prepare-release.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var runSequence = require('run-sequence'); 3 | var paths = require('../paths'); 4 | var changelog = require('gulp-conventional-changelog'); 5 | var fs = require('fs'); 6 | var bump = require('gulp-bump'); 7 | var args = require('../args'); 8 | 9 | gulp.task('bump-version', function() { 10 | return gulp.src(['./package.json', './bower.json']) 11 | .pipe(bump({type: args.bump})) //major|minor|patch|prerelease 12 | .pipe(gulp.dest('./')); 13 | }); 14 | 15 | gulp.task('changelog', function() { 16 | return gulp.src(paths.doc + '/CHANGELOG.md', { 17 | buffer: false 18 | }).pipe(changelog({ 19 | preset: 'angular' 20 | })) 21 | .pipe(gulp.dest(paths.doc)); 22 | }); 23 | 24 | gulp.task('prepare-release', function(callback) { 25 | return runSequence( 26 | 'build', 27 | 'lint', 28 | 'bump-version', 29 | 'doc', 30 | 'changelog', 31 | callback 32 | ); 33 | }); 34 | -------------------------------------------------------------------------------- /build/tasks/serve.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var browserSync = require('browser-sync'); 3 | var path = require('path'); 4 | var paths = require('../paths'); 5 | 6 | // this task utilizes the browsersync plugin 7 | // to create a dev server instance 8 | // at http://localhost:9000 9 | gulp.task('serve', ['build'], function(done) { 10 | var bs = browserSync.create('Sample server'); 11 | 12 | bs.init({ 13 | server: { 14 | baseDir: paths.sample, 15 | routes: { 16 | '/aurelia-notify': path.join(paths.output, 'amd') 17 | } 18 | } 19 | }, done); 20 | }); 21 | -------------------------------------------------------------------------------- /build/tasks/test.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var coveralls = require('gulp-coveralls'); 3 | var karma = require('karma'); 4 | 5 | /** 6 | * Run test once and exit 7 | */ 8 | gulp.task('test', function(done) { 9 | new karma.Server({ 10 | configFile: __dirname + '/../../karma.conf.js', 11 | singleRun: true 12 | }, function(e) { 13 | done(e === 0 ? null : 'karma exited with status ' + e); 14 | }).start(); 15 | }); 16 | 17 | /** 18 | * Watch for file changes and re-run tests on each change 19 | */ 20 | gulp.task('tdd', function(done) { 21 | new karma.Server({ 22 | configFile: __dirname + '/../../karma.conf.js' 23 | }, function(e) { 24 | done(); 25 | }).start(); 26 | }); 27 | 28 | gulp.task('cover', function(done) { 29 | new karma.Server({ 30 | configFile: __dirname + '/../../karma.conf.js', 31 | singleRun: true, 32 | reporters: ['coverage'], 33 | preprocessors: { 34 | 'test/**/*.js': ['babel'], 35 | 'src/**/*.js': ['babel'] 36 | }, 37 | coverageReporter: { 38 | dir: 'build/reports/coverage', 39 | reporters: [ 40 | // reporters not supporting the `file` property 41 | {type: 'html', subdir: 'html'}, 42 | {type: 'lcov', subdir: 'lcov'}, 43 | {type: 'text-summary'} 44 | ] 45 | } 46 | }, done).start(); 47 | }); 48 | 49 | /** 50 | * Report coverage to coveralls 51 | */ 52 | gulp.task('coveralls', ['cover'], function(done) { 53 | gulp.src('build/reports/coverage/lcov/lcov.info') 54 | .pipe(coveralls()); 55 | }); 56 | -------------------------------------------------------------------------------- /build/tasks/watch.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var browserSync = require('browser-sync'); 3 | var paths = require('../paths'); 4 | 5 | // outputs changes to files to the console 6 | function reportChange(event) { 7 | console.log('File ' + event.path + ' was ' + event.type + ', running tasks...'); 8 | } 9 | 10 | // this task wil watch for changes 11 | // to js, html, and css files and call the 12 | // reportChange method. Also, by depending on the 13 | // serve task, it will instantiate a browserSync session 14 | gulp.task('watch', ['serve'], function() { 15 | var bs = browserSync.get('Sample server'); 16 | 17 | gulp.watch(paths.source, ['build-babel-amd', bs.reload]).on('change', reportChange); 18 | gulp.watch(paths.html, ['build-html-amd', bs.reload]).on('change', reportChange); 19 | gulp.watch(paths.style, ['build-css-amd', bs.reload]).on('change', reportChange); 20 | gulp.watch(paths.sample + '/*', bs.reload).on('change', reportChange); 21 | gulp.watch(paths.sample + '/src/**/*', bs.reload).on('change', reportChange); 22 | }); 23 | -------------------------------------------------------------------------------- /build/typescript-options.js: -------------------------------------------------------------------------------- 1 | var tsconfig = require('../tsconfig.json'); 2 | var assign = Object.assign || require('object.assign'); 3 | 4 | module.exports = function (override) { 5 | return assign(tsconfig.compilerOptions, { 6 | "target": override && override.target || "es5", 7 | "typescript": require('typescript') 8 | }, override || {}); 9 | }; 10 | -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | System.config({ 2 | defaultJSExtensions: true, 3 | transpiler: "babel", 4 | babelOptions: { 5 | "optional": [ 6 | "runtime", 7 | "optimisation.modules.system", 8 | "es7.decorators", 9 | "es7.classProperties" 10 | ] 11 | }, 12 | paths: { 13 | "github:*": "jspm_packages/github/*", 14 | "npm:*": "jspm_packages/npm/*" 15 | }, 16 | 17 | map: { 18 | "aurelia-dependency-injection": "npm:aurelia-dependency-injection@1.3.1", 19 | "aurelia-framework": "npm:aurelia-framework@1.0.0-rc.1.0.0", 20 | "aurelia-metadata": "npm:aurelia-metadata@1.0.3", 21 | "aurelia-pal": "npm:aurelia-pal@1.3.0", 22 | "aurelia-pal-browser": "npm:aurelia-pal-browser@1.2.1", 23 | "aurelia-polyfills": "npm:aurelia-polyfills@1.2.1", 24 | "aurelia-templating": "npm:aurelia-templating@1.4.2", 25 | "babel": "npm:babel-core@5.8.38", 26 | "babel-runtime": "npm:babel-runtime@5.8.38", 27 | "core-js": "npm:core-js@1.2.7", 28 | "github:jspm/nodelibs-assert@0.1.0": { 29 | "assert": "npm:assert@1.4.1" 30 | }, 31 | "github:jspm/nodelibs-buffer@0.1.1": { 32 | "buffer": "npm:buffer@5.0.6" 33 | }, 34 | "github:jspm/nodelibs-path@0.1.0": { 35 | "path-browserify": "npm:path-browserify@0.0.0" 36 | }, 37 | "github:jspm/nodelibs-process@0.1.2": { 38 | "process": "npm:process@0.11.9" 39 | }, 40 | "github:jspm/nodelibs-util@0.1.0": { 41 | "util": "npm:util@0.10.3" 42 | }, 43 | "github:jspm/nodelibs-vm@0.1.0": { 44 | "vm-browserify": "npm:vm-browserify@0.0.4" 45 | }, 46 | "npm:assert@1.4.1": { 47 | "assert": "github:jspm/nodelibs-assert@0.1.0", 48 | "buffer": "github:jspm/nodelibs-buffer@0.1.1", 49 | "process": "github:jspm/nodelibs-process@0.1.2", 50 | "util": "npm:util@0.10.3" 51 | }, 52 | "npm:aurelia-binding@1.2.1": { 53 | "aurelia-logging": "npm:aurelia-logging@1.3.1", 54 | "aurelia-metadata": "npm:aurelia-metadata@1.0.3", 55 | "aurelia-pal": "npm:aurelia-pal@1.3.0", 56 | "aurelia-task-queue": "npm:aurelia-task-queue@1.2.0" 57 | }, 58 | "npm:aurelia-dependency-injection@1.3.1": { 59 | "aurelia-metadata": "npm:aurelia-metadata@1.0.3", 60 | "aurelia-pal": "npm:aurelia-pal@1.3.0" 61 | }, 62 | "npm:aurelia-framework@1.0.0-rc.1.0.0": { 63 | "aurelia-binding": "npm:aurelia-binding@1.2.1", 64 | "aurelia-dependency-injection": "npm:aurelia-dependency-injection@1.3.1", 65 | "aurelia-loader": "npm:aurelia-loader@1.0.0", 66 | "aurelia-logging": "npm:aurelia-logging@1.3.1", 67 | "aurelia-metadata": "npm:aurelia-metadata@1.0.3", 68 | "aurelia-pal": "npm:aurelia-pal@1.3.0", 69 | "aurelia-path": "npm:aurelia-path@1.1.1", 70 | "aurelia-task-queue": "npm:aurelia-task-queue@1.2.0", 71 | "aurelia-templating": "npm:aurelia-templating@1.4.2" 72 | }, 73 | "npm:aurelia-loader@1.0.0": { 74 | "aurelia-metadata": "npm:aurelia-metadata@1.0.3", 75 | "aurelia-path": "npm:aurelia-path@1.1.1" 76 | }, 77 | "npm:aurelia-metadata@1.0.3": { 78 | "aurelia-pal": "npm:aurelia-pal@1.3.0" 79 | }, 80 | "npm:aurelia-pal-browser@1.2.1": { 81 | "aurelia-pal": "npm:aurelia-pal@1.3.0" 82 | }, 83 | "npm:aurelia-polyfills@1.2.1": { 84 | "aurelia-pal": "npm:aurelia-pal@1.3.0" 85 | }, 86 | "npm:aurelia-task-queue@1.2.0": { 87 | "aurelia-pal": "npm:aurelia-pal@1.3.0" 88 | }, 89 | "npm:aurelia-templating@1.4.2": { 90 | "aurelia-binding": "npm:aurelia-binding@1.2.1", 91 | "aurelia-dependency-injection": "npm:aurelia-dependency-injection@1.3.1", 92 | "aurelia-loader": "npm:aurelia-loader@1.0.0", 93 | "aurelia-logging": "npm:aurelia-logging@1.3.1", 94 | "aurelia-metadata": "npm:aurelia-metadata@1.0.3", 95 | "aurelia-pal": "npm:aurelia-pal@1.3.0", 96 | "aurelia-path": "npm:aurelia-path@1.1.1", 97 | "aurelia-task-queue": "npm:aurelia-task-queue@1.2.0" 98 | }, 99 | "npm:babel-runtime@5.8.38": { 100 | "process": "github:jspm/nodelibs-process@0.1.2" 101 | }, 102 | "npm:buffer@5.0.6": { 103 | "base64-js": "npm:base64-js@1.2.0", 104 | "ieee754": "npm:ieee754@1.1.8" 105 | }, 106 | "npm:core-js@1.2.7": { 107 | "fs": "github:jspm/nodelibs-fs@0.1.2", 108 | "path": "github:jspm/nodelibs-path@0.1.0", 109 | "process": "github:jspm/nodelibs-process@0.1.2", 110 | "systemjs-json": "github:systemjs/plugin-json@0.1.2" 111 | }, 112 | "npm:inherits@2.0.1": { 113 | "util": "github:jspm/nodelibs-util@0.1.0" 114 | }, 115 | "npm:path-browserify@0.0.0": { 116 | "process": "github:jspm/nodelibs-process@0.1.2" 117 | }, 118 | "npm:process@0.11.9": { 119 | "assert": "github:jspm/nodelibs-assert@0.1.0", 120 | "fs": "github:jspm/nodelibs-fs@0.1.2", 121 | "vm": "github:jspm/nodelibs-vm@0.1.0" 122 | }, 123 | "npm:util@0.10.3": { 124 | "inherits": "npm:inherits@2.0.1", 125 | "process": "github:jspm/nodelibs-process@0.1.2" 126 | }, 127 | "npm:vm-browserify@0.0.4": { 128 | "indexof": "npm:indexof@0.0.1" 129 | } 130 | } 131 | }); 132 | -------------------------------------------------------------------------------- /dist/amd/aurelia-notify.js: -------------------------------------------------------------------------------- 1 | define(['exports', './bs-notification', './notification-level', './notification-service', './notification-controller', 'aurelia-pal', './notification-renderer'], function (exports, _bsNotification, _notificationLevel, _notificationService, _notificationController, _aureliaPal, _notificationRenderer) { 2 | 'use strict'; 3 | 4 | Object.defineProperty(exports, "__esModule", { 5 | value: true 6 | }); 7 | exports.NotificationController = exports.NotificationService = exports.NotificationLevel = exports.BSNotification = undefined; 8 | exports.configure = configure; 9 | Object.defineProperty(exports, 'BSNotification', { 10 | enumerable: true, 11 | get: function () { 12 | return _bsNotification.BSNotification; 13 | } 14 | }); 15 | Object.defineProperty(exports, 'NotificationLevel', { 16 | enumerable: true, 17 | get: function () { 18 | return _notificationLevel.NotificationLevel; 19 | } 20 | }); 21 | Object.defineProperty(exports, 'NotificationService', { 22 | enumerable: true, 23 | get: function () { 24 | return _notificationService.NotificationService; 25 | } 26 | }); 27 | Object.defineProperty(exports, 'NotificationController', { 28 | enumerable: true, 29 | get: function () { 30 | return _notificationController.NotificationController; 31 | } 32 | }); 33 | function configure(config, callback) { 34 | config.globalResources(_aureliaPal.PLATFORM.moduleName('./bs-notification')); 35 | 36 | if (typeof callback === 'function') { 37 | callback(_notificationRenderer.globalSettings); 38 | } 39 | } 40 | }); -------------------------------------------------------------------------------- /dist/amd/bs-notification.html: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /dist/amd/bs-notification.js: -------------------------------------------------------------------------------- 1 | define(['exports', './notification-controller'], function (exports, _notificationController) { 2 | 'use strict'; 3 | 4 | Object.defineProperty(exports, "__esModule", { 5 | value: true 6 | }); 7 | exports.BSNotification = undefined; 8 | 9 | 10 | 11 | var _class, _temp; 12 | 13 | var BSNotification = exports.BSNotification = (_temp = _class = function () { 14 | function BSNotification(controller) { 15 | 16 | 17 | this.controller = controller; 18 | } 19 | 20 | BSNotification.prototype.activate = function activate(model) { 21 | this.level = model.level; 22 | this.notification = model.notification; 23 | }; 24 | 25 | return BSNotification; 26 | }(), _class.inject = [_notificationController.NotificationController], _temp); 27 | }); -------------------------------------------------------------------------------- /dist/amd/index.js: -------------------------------------------------------------------------------- 1 | define(['exports', './aurelia-notify'], function (exports, _aureliaNotify) { 2 | 'use strict'; 3 | 4 | Object.defineProperty(exports, "__esModule", { 5 | value: true 6 | }); 7 | Object.keys(_aureliaNotify).forEach(function (key) { 8 | if (key === "default" || key === "__esModule") return; 9 | Object.defineProperty(exports, key, { 10 | enumerable: true, 11 | get: function () { 12 | return _aureliaNotify[key]; 13 | } 14 | }); 15 | }); 16 | }); -------------------------------------------------------------------------------- /dist/amd/lifecycle.js: -------------------------------------------------------------------------------- 1 | define(['exports'], function (exports) { 2 | 'use strict'; 3 | 4 | Object.defineProperty(exports, "__esModule", { 5 | value: true 6 | }); 7 | exports.invokeLifecycle = invokeLifecycle; 8 | function invokeLifecycle(instance, name, model) { 9 | if (typeof instance[name] === 'function') { 10 | return new Promise(function (resolve) { 11 | resolve(instance[name](model)); 12 | }).then(function (result) { 13 | if (result !== null && result !== undefined) { 14 | return result; 15 | } 16 | return true; 17 | }); 18 | } 19 | return Promise.resolve(true); 20 | } 21 | }); -------------------------------------------------------------------------------- /dist/amd/notification-controller.js: -------------------------------------------------------------------------------- 1 | define(['exports', './lifecycle'], function (exports, _lifecycle) { 2 | 'use strict'; 3 | 4 | Object.defineProperty(exports, "__esModule", { 5 | value: true 6 | }); 7 | exports.NotificationController = undefined; 8 | 9 | 10 | 11 | var NotificationController = exports.NotificationController = function () { 12 | function NotificationController(renderer, settings) { 13 | 14 | 15 | this.renderer = renderer; 16 | this.settings = settings; 17 | } 18 | 19 | NotificationController.prototype.close = function close() { 20 | var _this = this; 21 | 22 | if (this.closePromise) { 23 | return this.closePromise; 24 | } 25 | clearTimeout(this.timer); 26 | return this.closePromise = (0, _lifecycle.invokeLifecycle)(this.viewModel, 'canDeactivate').then(function (canDeactivate) { 27 | if (canDeactivate) { 28 | return (0, _lifecycle.invokeLifecycle)(_this.viewModel, 'deactivate').then(function () { 29 | return _this.renderer.hideNotification(_this); 30 | }).then(function () { 31 | return _this.renderer.destroyNotificationHost(_this); 32 | }).then(function () { 33 | _this.controller.unbind(); 34 | }); 35 | } 36 | }); 37 | }; 38 | 39 | return NotificationController; 40 | }(); 41 | }); -------------------------------------------------------------------------------- /dist/amd/notification-level.js: -------------------------------------------------------------------------------- 1 | define(['exports'], function (exports) { 2 | 'use strict'; 3 | 4 | Object.defineProperty(exports, "__esModule", { 5 | value: true 6 | }); 7 | var NotificationLevel = exports.NotificationLevel = { 8 | info: 'info', 9 | success: 'success', 10 | warning: 'warning', 11 | danger: 'danger' 12 | }; 13 | }); -------------------------------------------------------------------------------- /dist/amd/notification-renderer.js: -------------------------------------------------------------------------------- 1 | define(['exports', 'aurelia-pal', 'aurelia-templating', './bs-notification'], function (exports, _aureliaPal, _aureliaTemplating, _bsNotification) { 2 | 'use strict'; 3 | 4 | Object.defineProperty(exports, "__esModule", { 5 | value: true 6 | }); 7 | exports.NotificationRenderer = exports.globalSettings = undefined; 8 | 9 | 10 | 11 | var globalSettings = exports.globalSettings = { 12 | append: false, 13 | containerSelector: 'body', 14 | timeout: 0, 15 | viewModel: _bsNotification.BSNotification, 16 | limit: 5 17 | }; 18 | 19 | var transitionEvent = function () { 20 | var transition = null; 21 | 22 | return function () { 23 | if (transition) return transition; 24 | 25 | var t = void 0; 26 | var el = _aureliaPal.DOM.createElement('fakeelement'); 27 | var transitions = { 28 | 'transition': 'transitionend', 29 | 'OTransition': 'oTransitionEnd', 30 | 'MozTransition': 'transitionend', 31 | 'WebkitTransition': 'webkitTransitionEnd' 32 | }; 33 | for (t in transitions) { 34 | if (el.style[t] !== undefined) { 35 | transition = transitions[t]; 36 | return transition; 37 | } 38 | } 39 | 40 | return undefined; 41 | }; 42 | }(); 43 | 44 | var NotificationRenderer = exports.NotificationRenderer = function () { 45 | function NotificationRenderer() { 46 | 47 | 48 | this.defaultSettings = globalSettings; 49 | 50 | this.notificationControllers = []; 51 | } 52 | 53 | NotificationRenderer.prototype.createNotificationHost = function createNotificationHost(notificationController) { 54 | var _this = this; 55 | 56 | var settings = notificationController.settings; 57 | var notificationHost = _aureliaPal.DOM.createElement('notification-host'); 58 | var notificationContainer = this.getNotificationContainer(settings.containerSelector); 59 | 60 | if (settings.append === true) { 61 | notificationContainer.appendChild(notificationHost); 62 | } else { 63 | notificationContainer.insertBefore(notificationHost, notificationContainer.firstChild); 64 | } 65 | 66 | notificationController.slot = new _aureliaTemplating.ViewSlot(notificationHost, true); 67 | notificationController.slot.add(notificationController.view); 68 | 69 | notificationController.showNotification = function () { 70 | _this.notificationControllers.push(notificationController); 71 | 72 | if (_this.notificationControllers.length >= settings.limit + 1) { 73 | _this.notificationControllers[0].close(_this.notificationControllers[0]); 74 | } 75 | 76 | notificationController.slot.attached(); 77 | 78 | if (settings.timeout > 0) { 79 | notificationController.timer = setTimeout(notificationController.close.bind(notificationController), settings.timeout); 80 | } 81 | 82 | return new Promise(function (resolve) { 83 | function onTransitionEnd(e) { 84 | if (e.target !== notificationHost) { 85 | return; 86 | } 87 | notificationHost.removeEventListener(transitionEvent(), onTransitionEnd); 88 | resolve(); 89 | } 90 | 91 | notificationHost.addEventListener(transitionEvent(), onTransitionEnd); 92 | setTimeout(function () { 93 | notificationHost.classList.add('notification-host-active'); 94 | }, 0); 95 | }); 96 | }; 97 | 98 | notificationController.hideNotification = function () { 99 | var i = _this.notificationControllers.indexOf(notificationController); 100 | if (i !== -1) { 101 | _this.notificationControllers.splice(i, 1); 102 | } 103 | 104 | return new Promise(function (resolve) { 105 | function onTransitionEnd() { 106 | notificationHost.removeEventListener(transitionEvent(), onTransitionEnd); 107 | resolve(); 108 | } 109 | 110 | notificationHost.addEventListener(transitionEvent(), onTransitionEnd); 111 | notificationHost.classList.remove('notification-host-active'); 112 | }); 113 | }; 114 | 115 | notificationController.destroyNotificationHost = function () { 116 | notificationContainer.removeChild(notificationHost); 117 | notificationController.slot.detached(); 118 | 119 | return Promise.resolve(); 120 | }; 121 | 122 | return Promise.resolve(); 123 | }; 124 | 125 | NotificationRenderer.prototype.showNotification = function showNotification(notificationController) { 126 | return notificationController.showNotification(); 127 | }; 128 | 129 | NotificationRenderer.prototype.hideNotification = function hideNotification(notificationController) { 130 | return notificationController.hideNotification(); 131 | }; 132 | 133 | NotificationRenderer.prototype.destroyNotificationHost = function destroyNotificationHost(notificationController) { 134 | return notificationController.destroyNotificationHost(); 135 | }; 136 | 137 | NotificationRenderer.prototype.getNotificationContainer = function getNotificationContainer(containerSelector) { 138 | var notificationContainer = _aureliaPal.DOM.querySelectorAll(containerSelector); 139 | if (notificationContainer === null) { 140 | notificationContainer = _aureliaPal.DOM.querySelectorAll('body'); 141 | } 142 | 143 | return notificationContainer[0]; 144 | }; 145 | 146 | return NotificationRenderer; 147 | }(); 148 | }); -------------------------------------------------------------------------------- /dist/amd/notification-service.js: -------------------------------------------------------------------------------- 1 | define(['exports', 'aurelia-dependency-injection', 'aurelia-metadata', 'aurelia-templating', './lifecycle', './notification-controller', './notification-level', './notification-renderer'], function (exports, _aureliaDependencyInjection, _aureliaMetadata, _aureliaTemplating, _lifecycle, _notificationController, _notificationLevel, _notificationRenderer) { 2 | 'use strict'; 3 | 4 | Object.defineProperty(exports, "__esModule", { 5 | value: true 6 | }); 7 | exports.NotificationService = undefined; 8 | 9 | var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { 10 | return typeof obj; 11 | } : function (obj) { 12 | return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; 13 | }; 14 | 15 | 16 | 17 | var _class, _temp; 18 | 19 | var NotificationService = exports.NotificationService = (_temp = _class = function () { 20 | function NotificationService(compositionEngine, container, notificationRenderer) { 21 | 22 | 23 | this.compositionEngine = compositionEngine; 24 | this.container = container; 25 | this.notificationRenderer = notificationRenderer; 26 | } 27 | 28 | NotificationService.prototype.notify = function notify(model, settings, level) { 29 | var _this = this; 30 | 31 | var _settings = Object.assign({}, this.notificationRenderer.defaultSettings, settings); 32 | var notificationController = new _notificationController.NotificationController(this.notificationRenderer, _createSettings(model, _settings, level)); 33 | var childContainer = this.container.createChild(); 34 | childContainer.registerInstance(_notificationController.NotificationController, notificationController); 35 | 36 | return _getViewModel(this.container, childContainer, this.compositionEngine, notificationController).then(function (returnedCompositionContext) { 37 | notificationController.viewModel = returnedCompositionContext.viewModel; 38 | 39 | return (0, _lifecycle.invokeLifecycle)(returnedCompositionContext.viewModel, 'canActivate', _settings.model).then(function (canActivate) { 40 | if (canActivate) { 41 | _this.compositionEngine.createController(returnedCompositionContext).then(function (controller) { 42 | notificationController.controller = controller; 43 | notificationController.view = controller.view; 44 | controller.automate(); 45 | 46 | return _this.notificationRenderer.createNotificationHost(notificationController); 47 | }).then(function () { 48 | return _this.notificationRenderer.showNotification(notificationController); 49 | }); 50 | } 51 | }); 52 | }); 53 | }; 54 | 55 | NotificationService.prototype.info = function info(message, settings) { 56 | this.notify(message, settings, _notificationLevel.NotificationLevel.info); 57 | }; 58 | 59 | NotificationService.prototype.success = function success(message, settings) { 60 | this.notify(message, settings, _notificationLevel.NotificationLevel.success); 61 | }; 62 | 63 | NotificationService.prototype.warning = function warning(message, settings) { 64 | this.notify(message, settings, _notificationLevel.NotificationLevel.warning); 65 | }; 66 | 67 | NotificationService.prototype.danger = function danger(message, settings) { 68 | this.notify(message, settings, _notificationLevel.NotificationLevel.danger); 69 | }; 70 | 71 | return NotificationService; 72 | }(), _class.inject = [_aureliaTemplating.CompositionEngine, _aureliaDependencyInjection.Container, _notificationRenderer.NotificationRenderer], _temp); 73 | 74 | 75 | function _createSettings(model, settings, level) { 76 | var notification = void 0; 77 | if (typeof model === 'string') { 78 | notification = model; 79 | } else if ((typeof model === 'undefined' ? 'undefined' : _typeof(model)) === 'object') { 80 | if (model.notification === undefined) { 81 | throw new Error('model must implement `notification` property.'); 82 | } 83 | notification = model.notification; 84 | } else { 85 | throw new Error('type is not supported by `notify()`.'); 86 | } 87 | 88 | settings.model = { 89 | notification: notification, 90 | data: model, 91 | level: level || _notificationLevel.NotificationLevel.info 92 | }; 93 | return settings; 94 | } 95 | 96 | function _getViewModel(container, childContainer, compositionEngine, notificationController) { 97 | var compositionContext = { 98 | container: container, 99 | childContainer: childContainer, 100 | model: notificationController.settings.model, 101 | viewModel: notificationController.settings.viewModel 102 | }; 103 | 104 | if (typeof compositionContext.viewModel === 'function') { 105 | compositionContext.viewModel = _aureliaMetadata.Origin.get(compositionContext.viewModel).moduleId; 106 | } 107 | 108 | if (typeof compositionContext.viewModel === 'string') { 109 | return compositionEngine.ensureViewModel(compositionContext); 110 | } 111 | 112 | return Promise.resolve(compositionContext); 113 | } 114 | }); -------------------------------------------------------------------------------- /dist/amd/style.css: -------------------------------------------------------------------------------- 1 | notification-host { 2 | display: block; 3 | transition: opacity .2s linear; 4 | opacity: 0; 5 | } 6 | 7 | .notification-host-active { 8 | opacity: 1; 9 | } 10 | -------------------------------------------------------------------------------- /dist/aurelia-notify.d.ts: -------------------------------------------------------------------------------- 1 | import { 2 | DOM 3 | } from 'aurelia-pal'; 4 | import { 5 | ViewSlot, 6 | CompositionEngine 7 | } from 'aurelia-templating'; 8 | import { 9 | Container 10 | } from 'aurelia-dependency-injection'; 11 | import { 12 | Origin 13 | } from 'aurelia-metadata'; 14 | export declare let NotificationLevel: any; 15 | export declare function invokeLifecycle(instance: any, name: string, model?: any): Promise; 16 | export declare class NotificationController { 17 | constructor(renderer: NotificationRenderer, settings: any); 18 | close(): any; 19 | } 20 | export declare class BSNotification { 21 | static inject: any; 22 | constructor(controller: NotificationController); 23 | activate(model: any): any; 24 | } 25 | export declare let globalSettings: any; 26 | export declare class NotificationRenderer { 27 | defaultSettings: any; 28 | constructor(); 29 | createNotificationHost(notificationController: NotificationController): any; 30 | showNotification(notificationController: NotificationController): any; 31 | hideNotification(notificationController: NotificationController): any; 32 | destroyNotificationHost(notificationController: NotificationController): any; 33 | getNotificationContainer(containerSelector: string): any; 34 | } 35 | export declare class NotificationService { 36 | static inject: any; 37 | compositionEngine: CompositionEngine; 38 | container: Container; 39 | notificationRenderer: NotificationRenderer; 40 | constructor(compositionEngine: CompositionEngine, container: Container, notificationRenderer: NotificationRenderer); 41 | notify(model: any, settings?: any, level?: string): any; 42 | info(message: string, settings?: any): any; 43 | success(message: string, settings?: any): any; 44 | warning(message: string, settings?: any): any; 45 | danger(message: string, settings?: any): any; 46 | } -------------------------------------------------------------------------------- /dist/aurelia-notify.js: -------------------------------------------------------------------------------- 1 | import {DOM} from 'aurelia-pal'; 2 | import {ViewSlot,CompositionEngine} from 'aurelia-templating'; 3 | import {Container} from 'aurelia-dependency-injection'; 4 | import {Origin} from 'aurelia-metadata'; 5 | 6 | export let NotificationLevel = { 7 | info: 'info', 8 | success: 'success', 9 | warning: 'warning', 10 | danger: 'danger' 11 | }; 12 | 13 | export function invokeLifecycle(instance: any, name: string, model?: any): Promise { 14 | if (typeof instance[name] === 'function') { 15 | return new Promise(resolve => { 16 | resolve(instance[name](model)); 17 | }) 18 | .then(result => { 19 | if (result !== null && result !== undefined) { 20 | return result; 21 | } 22 | return true; 23 | }); 24 | } 25 | return Promise.resolve(true); 26 | } 27 | 28 | export class NotificationController { 29 | constructor(renderer: NotificationRenderer, settings: any) { 30 | this.renderer = renderer; 31 | this.settings = settings; 32 | } 33 | 34 | close() { 35 | if (this.closePromise) { 36 | return this.closePromise; 37 | } 38 | clearTimeout(this.timer); 39 | return this.closePromise = invokeLifecycle(this.viewModel, 'canDeactivate') 40 | .then(canDeactivate => { 41 | if (canDeactivate) { 42 | return invokeLifecycle(this.viewModel, 'deactivate') 43 | .then(() => { 44 | return this.renderer.hideNotification(this); 45 | }) 46 | .then(() => { 47 | return this.renderer.destroyNotificationHost(this); 48 | }) 49 | .then(() => { 50 | this.controller.unbind(); 51 | }); 52 | } 53 | }); 54 | } 55 | } 56 | 57 | export class BSNotification { 58 | static inject = [NotificationController]; 59 | 60 | constructor(controller: NotificationController) { 61 | this.controller = controller; 62 | } 63 | 64 | activate(model: any) { 65 | this.level = model.level; 66 | this.notification = model.notification; 67 | } 68 | } 69 | 70 | export let globalSettings = { 71 | append: false, 72 | containerSelector: 'body', 73 | timeout: 0, 74 | viewModel: BSNotification, 75 | limit: 5 76 | }; 77 | 78 | let transitionEvent = (function() { 79 | let transition = null; 80 | 81 | return function() { 82 | if (transition) return transition; 83 | 84 | let t; 85 | let el = DOM.createElement('fakeelement'); 86 | let transitions = { 87 | 'transition': 'transitionend', 88 | 'OTransition': 'oTransitionEnd', 89 | 'MozTransition': 'transitionend', 90 | 'WebkitTransition': 'webkitTransitionEnd' 91 | }; 92 | for (t in transitions) { 93 | if (el.style[t] !== undefined) { 94 | transition = transitions[t]; 95 | return transition; 96 | } 97 | } 98 | 99 | return undefined; 100 | }; 101 | }()); 102 | 103 | export class NotificationRenderer { 104 | defaultSettings = globalSettings; 105 | 106 | constructor() { 107 | this.notificationControllers = []; 108 | } 109 | 110 | createNotificationHost(notificationController: NotificationController) { 111 | let settings = notificationController.settings; 112 | let notificationHost = DOM.createElement('notification-host'); 113 | let notificationContainer = this.getNotificationContainer(settings.containerSelector); 114 | 115 | if (settings.append === true) { 116 | notificationContainer.appendChild(notificationHost); 117 | } else { 118 | notificationContainer.insertBefore(notificationHost, notificationContainer.firstChild); 119 | } 120 | 121 | notificationController.slot = new ViewSlot(notificationHost, true); 122 | notificationController.slot.add(notificationController.view); 123 | 124 | notificationController.showNotification = () => { 125 | this.notificationControllers.push(notificationController); 126 | 127 | if (this.notificationControllers.length >= (settings.limit + 1)) { 128 | this.notificationControllers[0].close(this.notificationControllers[0]); 129 | } 130 | 131 | notificationController.slot.attached(); 132 | 133 | if (settings.timeout > 0) { 134 | notificationController.timer = setTimeout(notificationController.close.bind(notificationController), settings.timeout); 135 | } 136 | 137 | return new Promise((resolve) => { 138 | function onTransitionEnd(e) { 139 | if (e.target !== notificationHost) { 140 | return; 141 | } 142 | notificationHost.removeEventListener(transitionEvent(), onTransitionEnd); 143 | resolve(); 144 | } 145 | 146 | notificationHost.addEventListener(transitionEvent(), onTransitionEnd); 147 | setTimeout(() => { 148 | notificationHost.classList.add('notification-host-active'); 149 | }, 0); 150 | }); 151 | }; 152 | 153 | notificationController.hideNotification = () => { 154 | let i = this.notificationControllers.indexOf(notificationController); 155 | if (i !== -1) { 156 | this.notificationControllers.splice(i, 1); 157 | } 158 | 159 | return new Promise((resolve) => { 160 | function onTransitionEnd() { 161 | notificationHost.removeEventListener(transitionEvent(), onTransitionEnd); 162 | resolve(); 163 | } 164 | 165 | notificationHost.addEventListener(transitionEvent(), onTransitionEnd); 166 | notificationHost.classList.remove('notification-host-active'); 167 | }); 168 | }; 169 | 170 | notificationController.destroyNotificationHost = () => { 171 | notificationContainer.removeChild(notificationHost); 172 | notificationController.slot.detached(); 173 | 174 | return Promise.resolve(); 175 | }; 176 | 177 | return Promise.resolve(); 178 | } 179 | 180 | showNotification(notificationController: NotificationController) { 181 | return notificationController.showNotification(); 182 | } 183 | 184 | hideNotification(notificationController: NotificationController) { 185 | return notificationController.hideNotification(); 186 | } 187 | 188 | destroyNotificationHost(notificationController: NotificationController) { 189 | return notificationController.destroyNotificationHost(); 190 | } 191 | 192 | getNotificationContainer(containerSelector: string) { 193 | let notificationContainer = DOM.querySelectorAll(containerSelector); 194 | if (notificationContainer === null) { 195 | notificationContainer = DOM.querySelectorAll('body'); 196 | } 197 | 198 | return notificationContainer[0]; 199 | } 200 | } 201 | 202 | export class NotificationService { 203 | static inject = [CompositionEngine, Container, NotificationRenderer]; 204 | 205 | compositionEngine: CompositionEngine; 206 | container: Container; 207 | notificationRenderer: NotificationRenderer; 208 | 209 | constructor(compositionEngine: CompositionEngine, container: Container, notificationRenderer: NotificationRenderer) { 210 | this.compositionEngine = compositionEngine; 211 | this.container = container; 212 | this.notificationRenderer = notificationRenderer; 213 | } 214 | 215 | notify(model: any, settings?: any, level?: string) { 216 | let _settings = Object.assign({}, this.notificationRenderer.defaultSettings, settings); 217 | let notificationController = new NotificationController(this.notificationRenderer, _createSettings(model, _settings, level)); 218 | let childContainer = this.container.createChild(); 219 | childContainer.registerInstance(NotificationController, notificationController); 220 | 221 | return _getViewModel(this.container, childContainer, this.compositionEngine, notificationController) 222 | .then(returnedCompositionContext => { 223 | notificationController.viewModel = returnedCompositionContext.viewModel; 224 | 225 | return invokeLifecycle(returnedCompositionContext.viewModel, 'canActivate', _settings.model) 226 | .then(canActivate => { 227 | if (canActivate) { 228 | this.compositionEngine.createController(returnedCompositionContext) 229 | .then(controller => { 230 | notificationController.controller = controller; 231 | notificationController.view = controller.view; 232 | controller.automate(); 233 | 234 | return this.notificationRenderer.createNotificationHost(notificationController); 235 | }) 236 | .then(() => { 237 | return this.notificationRenderer.showNotification(notificationController); 238 | }); 239 | } 240 | }); 241 | }); 242 | } 243 | 244 | info(message: string, settings?: any) { 245 | this.notify(message, settings, NotificationLevel.info); 246 | } 247 | 248 | success(message: string, settings?: any) { 249 | this.notify(message, settings, NotificationLevel.success); 250 | } 251 | 252 | warning(message: string, settings?: any) { 253 | this.notify(message, settings, NotificationLevel.warning); 254 | } 255 | 256 | danger(message: string, settings?: any) { 257 | this.notify(message, settings, NotificationLevel.danger); 258 | } 259 | } 260 | 261 | function _createSettings(model, settings, level) { 262 | let notification; 263 | if (typeof model === 'string') { 264 | notification = model; 265 | } else if (typeof model === 'object') { 266 | if (model.notification === undefined) { 267 | throw new Error('model must implement `notification` property.'); 268 | } 269 | notification = model.notification; 270 | } else { 271 | throw new Error('type is not supported by `notify()`.'); 272 | } 273 | 274 | settings.model = { 275 | notification: notification, 276 | data: model, 277 | level: level || NotificationLevel.info 278 | }; 279 | return settings; 280 | } 281 | 282 | function _getViewModel(container, childContainer, compositionEngine, notificationController) { 283 | let compositionContext = { 284 | container: container, 285 | childContainer: childContainer, 286 | model: notificationController.settings.model, 287 | viewModel: notificationController.settings.viewModel 288 | }; 289 | 290 | if (typeof compositionContext.viewModel === 'function') { 291 | compositionContext.viewModel = Origin.get(compositionContext.viewModel).moduleId; 292 | } 293 | 294 | if (typeof compositionContext.viewModel === 'string') { 295 | return compositionEngine.ensureViewModel(compositionContext); 296 | } 297 | 298 | return Promise.resolve(compositionContext); 299 | } 300 | -------------------------------------------------------------------------------- /dist/commonjs/aurelia-notify.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.NotificationController = exports.NotificationService = exports.NotificationLevel = exports.BSNotification = undefined; 7 | exports.configure = configure; 8 | 9 | var _bsNotification = require('./bs-notification'); 10 | 11 | Object.defineProperty(exports, 'BSNotification', { 12 | enumerable: true, 13 | get: function get() { 14 | return _bsNotification.BSNotification; 15 | } 16 | }); 17 | 18 | var _notificationLevel = require('./notification-level'); 19 | 20 | Object.defineProperty(exports, 'NotificationLevel', { 21 | enumerable: true, 22 | get: function get() { 23 | return _notificationLevel.NotificationLevel; 24 | } 25 | }); 26 | 27 | var _notificationService = require('./notification-service'); 28 | 29 | Object.defineProperty(exports, 'NotificationService', { 30 | enumerable: true, 31 | get: function get() { 32 | return _notificationService.NotificationService; 33 | } 34 | }); 35 | 36 | var _notificationController = require('./notification-controller'); 37 | 38 | Object.defineProperty(exports, 'NotificationController', { 39 | enumerable: true, 40 | get: function get() { 41 | return _notificationController.NotificationController; 42 | } 43 | }); 44 | 45 | var _aureliaPal = require('aurelia-pal'); 46 | 47 | var _notificationRenderer = require('./notification-renderer'); 48 | 49 | function configure(config, callback) { 50 | config.globalResources(_aureliaPal.PLATFORM.moduleName('./bs-notification')); 51 | 52 | if (typeof callback === 'function') { 53 | callback(_notificationRenderer.globalSettings); 54 | } 55 | } -------------------------------------------------------------------------------- /dist/commonjs/bs-notification.html: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /dist/commonjs/bs-notification.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.BSNotification = undefined; 7 | 8 | var _class, _temp; 9 | 10 | var _notificationController = require('./notification-controller'); 11 | 12 | 13 | 14 | var BSNotification = exports.BSNotification = (_temp = _class = function () { 15 | function BSNotification(controller) { 16 | 17 | 18 | this.controller = controller; 19 | } 20 | 21 | BSNotification.prototype.activate = function activate(model) { 22 | this.level = model.level; 23 | this.notification = model.notification; 24 | }; 25 | 26 | return BSNotification; 27 | }(), _class.inject = [_notificationController.NotificationController], _temp); -------------------------------------------------------------------------------- /dist/commonjs/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _aureliaNotify = require('./aurelia-notify'); 8 | 9 | Object.keys(_aureliaNotify).forEach(function (key) { 10 | if (key === "default" || key === "__esModule") return; 11 | Object.defineProperty(exports, key, { 12 | enumerable: true, 13 | get: function get() { 14 | return _aureliaNotify[key]; 15 | } 16 | }); 17 | }); -------------------------------------------------------------------------------- /dist/commonjs/lifecycle.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.invokeLifecycle = invokeLifecycle; 7 | function invokeLifecycle(instance, name, model) { 8 | if (typeof instance[name] === 'function') { 9 | return new Promise(function (resolve) { 10 | resolve(instance[name](model)); 11 | }).then(function (result) { 12 | if (result !== null && result !== undefined) { 13 | return result; 14 | } 15 | return true; 16 | }); 17 | } 18 | return Promise.resolve(true); 19 | } -------------------------------------------------------------------------------- /dist/commonjs/notification-controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.NotificationController = undefined; 7 | 8 | var _lifecycle = require('./lifecycle'); 9 | 10 | 11 | 12 | var NotificationController = exports.NotificationController = function () { 13 | function NotificationController(renderer, settings) { 14 | 15 | 16 | this.renderer = renderer; 17 | this.settings = settings; 18 | } 19 | 20 | NotificationController.prototype.close = function close() { 21 | var _this = this; 22 | 23 | if (this.closePromise) { 24 | return this.closePromise; 25 | } 26 | clearTimeout(this.timer); 27 | return this.closePromise = (0, _lifecycle.invokeLifecycle)(this.viewModel, 'canDeactivate').then(function (canDeactivate) { 28 | if (canDeactivate) { 29 | return (0, _lifecycle.invokeLifecycle)(_this.viewModel, 'deactivate').then(function () { 30 | return _this.renderer.hideNotification(_this); 31 | }).then(function () { 32 | return _this.renderer.destroyNotificationHost(_this); 33 | }).then(function () { 34 | _this.controller.unbind(); 35 | }); 36 | } 37 | }); 38 | }; 39 | 40 | return NotificationController; 41 | }(); -------------------------------------------------------------------------------- /dist/commonjs/notification-level.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | var NotificationLevel = exports.NotificationLevel = { 7 | info: 'info', 8 | success: 'success', 9 | warning: 'warning', 10 | danger: 'danger' 11 | }; -------------------------------------------------------------------------------- /dist/commonjs/notification-renderer.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.NotificationRenderer = exports.globalSettings = undefined; 7 | 8 | var _aureliaPal = require('aurelia-pal'); 9 | 10 | var _aureliaTemplating = require('aurelia-templating'); 11 | 12 | var _bsNotification = require('./bs-notification'); 13 | 14 | 15 | 16 | var globalSettings = exports.globalSettings = { 17 | append: false, 18 | containerSelector: 'body', 19 | timeout: 0, 20 | viewModel: _bsNotification.BSNotification, 21 | limit: 5 22 | }; 23 | 24 | var transitionEvent = function () { 25 | var transition = null; 26 | 27 | return function () { 28 | if (transition) return transition; 29 | 30 | var t = void 0; 31 | var el = _aureliaPal.DOM.createElement('fakeelement'); 32 | var transitions = { 33 | 'transition': 'transitionend', 34 | 'OTransition': 'oTransitionEnd', 35 | 'MozTransition': 'transitionend', 36 | 'WebkitTransition': 'webkitTransitionEnd' 37 | }; 38 | for (t in transitions) { 39 | if (el.style[t] !== undefined) { 40 | transition = transitions[t]; 41 | return transition; 42 | } 43 | } 44 | 45 | return undefined; 46 | }; 47 | }(); 48 | 49 | var NotificationRenderer = exports.NotificationRenderer = function () { 50 | function NotificationRenderer() { 51 | 52 | 53 | this.defaultSettings = globalSettings; 54 | 55 | this.notificationControllers = []; 56 | } 57 | 58 | NotificationRenderer.prototype.createNotificationHost = function createNotificationHost(notificationController) { 59 | var _this = this; 60 | 61 | var settings = notificationController.settings; 62 | var notificationHost = _aureliaPal.DOM.createElement('notification-host'); 63 | var notificationContainer = this.getNotificationContainer(settings.containerSelector); 64 | 65 | if (settings.append === true) { 66 | notificationContainer.appendChild(notificationHost); 67 | } else { 68 | notificationContainer.insertBefore(notificationHost, notificationContainer.firstChild); 69 | } 70 | 71 | notificationController.slot = new _aureliaTemplating.ViewSlot(notificationHost, true); 72 | notificationController.slot.add(notificationController.view); 73 | 74 | notificationController.showNotification = function () { 75 | _this.notificationControllers.push(notificationController); 76 | 77 | if (_this.notificationControllers.length >= settings.limit + 1) { 78 | _this.notificationControllers[0].close(_this.notificationControllers[0]); 79 | } 80 | 81 | notificationController.slot.attached(); 82 | 83 | if (settings.timeout > 0) { 84 | notificationController.timer = setTimeout(notificationController.close.bind(notificationController), settings.timeout); 85 | } 86 | 87 | return new Promise(function (resolve) { 88 | function onTransitionEnd(e) { 89 | if (e.target !== notificationHost) { 90 | return; 91 | } 92 | notificationHost.removeEventListener(transitionEvent(), onTransitionEnd); 93 | resolve(); 94 | } 95 | 96 | notificationHost.addEventListener(transitionEvent(), onTransitionEnd); 97 | setTimeout(function () { 98 | notificationHost.classList.add('notification-host-active'); 99 | }, 0); 100 | }); 101 | }; 102 | 103 | notificationController.hideNotification = function () { 104 | var i = _this.notificationControllers.indexOf(notificationController); 105 | if (i !== -1) { 106 | _this.notificationControllers.splice(i, 1); 107 | } 108 | 109 | return new Promise(function (resolve) { 110 | function onTransitionEnd() { 111 | notificationHost.removeEventListener(transitionEvent(), onTransitionEnd); 112 | resolve(); 113 | } 114 | 115 | notificationHost.addEventListener(transitionEvent(), onTransitionEnd); 116 | notificationHost.classList.remove('notification-host-active'); 117 | }); 118 | }; 119 | 120 | notificationController.destroyNotificationHost = function () { 121 | notificationContainer.removeChild(notificationHost); 122 | notificationController.slot.detached(); 123 | 124 | return Promise.resolve(); 125 | }; 126 | 127 | return Promise.resolve(); 128 | }; 129 | 130 | NotificationRenderer.prototype.showNotification = function showNotification(notificationController) { 131 | return notificationController.showNotification(); 132 | }; 133 | 134 | NotificationRenderer.prototype.hideNotification = function hideNotification(notificationController) { 135 | return notificationController.hideNotification(); 136 | }; 137 | 138 | NotificationRenderer.prototype.destroyNotificationHost = function destroyNotificationHost(notificationController) { 139 | return notificationController.destroyNotificationHost(); 140 | }; 141 | 142 | NotificationRenderer.prototype.getNotificationContainer = function getNotificationContainer(containerSelector) { 143 | var notificationContainer = _aureliaPal.DOM.querySelectorAll(containerSelector); 144 | if (notificationContainer === null) { 145 | notificationContainer = _aureliaPal.DOM.querySelectorAll('body'); 146 | } 147 | 148 | return notificationContainer[0]; 149 | }; 150 | 151 | return NotificationRenderer; 152 | }(); -------------------------------------------------------------------------------- /dist/commonjs/notification-service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.NotificationService = undefined; 7 | 8 | var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; 9 | 10 | var _class, _temp; 11 | 12 | var _aureliaDependencyInjection = require('aurelia-dependency-injection'); 13 | 14 | var _aureliaMetadata = require('aurelia-metadata'); 15 | 16 | var _aureliaTemplating = require('aurelia-templating'); 17 | 18 | var _lifecycle = require('./lifecycle'); 19 | 20 | var _notificationController = require('./notification-controller'); 21 | 22 | var _notificationLevel = require('./notification-level'); 23 | 24 | var _notificationRenderer = require('./notification-renderer'); 25 | 26 | 27 | 28 | var NotificationService = exports.NotificationService = (_temp = _class = function () { 29 | function NotificationService(compositionEngine, container, notificationRenderer) { 30 | 31 | 32 | this.compositionEngine = compositionEngine; 33 | this.container = container; 34 | this.notificationRenderer = notificationRenderer; 35 | } 36 | 37 | NotificationService.prototype.notify = function notify(model, settings, level) { 38 | var _this = this; 39 | 40 | var _settings = Object.assign({}, this.notificationRenderer.defaultSettings, settings); 41 | var notificationController = new _notificationController.NotificationController(this.notificationRenderer, _createSettings(model, _settings, level)); 42 | var childContainer = this.container.createChild(); 43 | childContainer.registerInstance(_notificationController.NotificationController, notificationController); 44 | 45 | return _getViewModel(this.container, childContainer, this.compositionEngine, notificationController).then(function (returnedCompositionContext) { 46 | notificationController.viewModel = returnedCompositionContext.viewModel; 47 | 48 | return (0, _lifecycle.invokeLifecycle)(returnedCompositionContext.viewModel, 'canActivate', _settings.model).then(function (canActivate) { 49 | if (canActivate) { 50 | _this.compositionEngine.createController(returnedCompositionContext).then(function (controller) { 51 | notificationController.controller = controller; 52 | notificationController.view = controller.view; 53 | controller.automate(); 54 | 55 | return _this.notificationRenderer.createNotificationHost(notificationController); 56 | }).then(function () { 57 | return _this.notificationRenderer.showNotification(notificationController); 58 | }); 59 | } 60 | }); 61 | }); 62 | }; 63 | 64 | NotificationService.prototype.info = function info(message, settings) { 65 | this.notify(message, settings, _notificationLevel.NotificationLevel.info); 66 | }; 67 | 68 | NotificationService.prototype.success = function success(message, settings) { 69 | this.notify(message, settings, _notificationLevel.NotificationLevel.success); 70 | }; 71 | 72 | NotificationService.prototype.warning = function warning(message, settings) { 73 | this.notify(message, settings, _notificationLevel.NotificationLevel.warning); 74 | }; 75 | 76 | NotificationService.prototype.danger = function danger(message, settings) { 77 | this.notify(message, settings, _notificationLevel.NotificationLevel.danger); 78 | }; 79 | 80 | return NotificationService; 81 | }(), _class.inject = [_aureliaTemplating.CompositionEngine, _aureliaDependencyInjection.Container, _notificationRenderer.NotificationRenderer], _temp); 82 | 83 | 84 | function _createSettings(model, settings, level) { 85 | var notification = void 0; 86 | if (typeof model === 'string') { 87 | notification = model; 88 | } else if ((typeof model === 'undefined' ? 'undefined' : _typeof(model)) === 'object') { 89 | if (model.notification === undefined) { 90 | throw new Error('model must implement `notification` property.'); 91 | } 92 | notification = model.notification; 93 | } else { 94 | throw new Error('type is not supported by `notify()`.'); 95 | } 96 | 97 | settings.model = { 98 | notification: notification, 99 | data: model, 100 | level: level || _notificationLevel.NotificationLevel.info 101 | }; 102 | return settings; 103 | } 104 | 105 | function _getViewModel(container, childContainer, compositionEngine, notificationController) { 106 | var compositionContext = { 107 | container: container, 108 | childContainer: childContainer, 109 | model: notificationController.settings.model, 110 | viewModel: notificationController.settings.viewModel 111 | }; 112 | 113 | if (typeof compositionContext.viewModel === 'function') { 114 | compositionContext.viewModel = _aureliaMetadata.Origin.get(compositionContext.viewModel).moduleId; 115 | } 116 | 117 | if (typeof compositionContext.viewModel === 'string') { 118 | return compositionEngine.ensureViewModel(compositionContext); 119 | } 120 | 121 | return Promise.resolve(compositionContext); 122 | } -------------------------------------------------------------------------------- /dist/commonjs/style.css: -------------------------------------------------------------------------------- 1 | notification-host { 2 | display: block; 3 | transition: opacity .2s linear; 4 | opacity: 0; 5 | } 6 | 7 | .notification-host-active { 8 | opacity: 1; 9 | } 10 | -------------------------------------------------------------------------------- /dist/es2015/aurelia-notify.js: -------------------------------------------------------------------------------- 1 | import { PLATFORM } from 'aurelia-pal'; 2 | import { globalSettings } from './notification-renderer'; 3 | 4 | export function configure(config, callback) { 5 | config.globalResources(PLATFORM.moduleName('./bs-notification')); 6 | 7 | if (typeof callback === 'function') { 8 | callback(globalSettings); 9 | } 10 | } 11 | 12 | export { BSNotification } from './bs-notification'; 13 | export { NotificationLevel } from './notification-level'; 14 | export { NotificationService } from './notification-service'; 15 | export { NotificationController } from './notification-controller'; -------------------------------------------------------------------------------- /dist/es2015/bs-notification.html: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /dist/es2015/bs-notification.js: -------------------------------------------------------------------------------- 1 | var _class, _temp; 2 | 3 | import { NotificationController } from './notification-controller'; 4 | 5 | export let BSNotification = (_temp = _class = class BSNotification { 6 | 7 | constructor(controller) { 8 | this.controller = controller; 9 | } 10 | 11 | activate(model) { 12 | this.level = model.level; 13 | this.notification = model.notification; 14 | } 15 | }, _class.inject = [NotificationController], _temp); -------------------------------------------------------------------------------- /dist/es2015/index.js: -------------------------------------------------------------------------------- 1 | export * from './aurelia-notify'; -------------------------------------------------------------------------------- /dist/es2015/lifecycle.js: -------------------------------------------------------------------------------- 1 | export function invokeLifecycle(instance, name, model) { 2 | if (typeof instance[name] === 'function') { 3 | return new Promise(resolve => { 4 | resolve(instance[name](model)); 5 | }).then(result => { 6 | if (result !== null && result !== undefined) { 7 | return result; 8 | } 9 | return true; 10 | }); 11 | } 12 | return Promise.resolve(true); 13 | } -------------------------------------------------------------------------------- /dist/es2015/notification-controller.js: -------------------------------------------------------------------------------- 1 | import { invokeLifecycle } from './lifecycle'; 2 | 3 | export let NotificationController = class NotificationController { 4 | constructor(renderer, settings) { 5 | this.renderer = renderer; 6 | this.settings = settings; 7 | } 8 | 9 | close() { 10 | if (this.closePromise) { 11 | return this.closePromise; 12 | } 13 | clearTimeout(this.timer); 14 | return this.closePromise = invokeLifecycle(this.viewModel, 'canDeactivate').then(canDeactivate => { 15 | if (canDeactivate) { 16 | return invokeLifecycle(this.viewModel, 'deactivate').then(() => { 17 | return this.renderer.hideNotification(this); 18 | }).then(() => { 19 | return this.renderer.destroyNotificationHost(this); 20 | }).then(() => { 21 | this.controller.unbind(); 22 | }); 23 | } 24 | }); 25 | } 26 | }; -------------------------------------------------------------------------------- /dist/es2015/notification-level.js: -------------------------------------------------------------------------------- 1 | export let NotificationLevel = { 2 | info: 'info', 3 | success: 'success', 4 | warning: 'warning', 5 | danger: 'danger' 6 | }; -------------------------------------------------------------------------------- /dist/es2015/notification-renderer.js: -------------------------------------------------------------------------------- 1 | import { DOM } from 'aurelia-pal'; 2 | import { ViewSlot } from 'aurelia-templating'; 3 | 4 | import { BSNotification } from './bs-notification'; 5 | 6 | export let globalSettings = { 7 | append: false, 8 | containerSelector: 'body', 9 | timeout: 0, 10 | viewModel: BSNotification, 11 | limit: 5 12 | }; 13 | 14 | let transitionEvent = function () { 15 | let transition = null; 16 | 17 | return function () { 18 | if (transition) return transition; 19 | 20 | let t; 21 | let el = DOM.createElement('fakeelement'); 22 | let transitions = { 23 | 'transition': 'transitionend', 24 | 'OTransition': 'oTransitionEnd', 25 | 'MozTransition': 'transitionend', 26 | 'WebkitTransition': 'webkitTransitionEnd' 27 | }; 28 | for (t in transitions) { 29 | if (el.style[t] !== undefined) { 30 | transition = transitions[t]; 31 | return transition; 32 | } 33 | } 34 | 35 | return undefined; 36 | }; 37 | }(); 38 | 39 | export let NotificationRenderer = class NotificationRenderer { 40 | 41 | constructor() { 42 | this.defaultSettings = globalSettings; 43 | 44 | this.notificationControllers = []; 45 | } 46 | 47 | createNotificationHost(notificationController) { 48 | let settings = notificationController.settings; 49 | let notificationHost = DOM.createElement('notification-host'); 50 | let notificationContainer = this.getNotificationContainer(settings.containerSelector); 51 | 52 | if (settings.append === true) { 53 | notificationContainer.appendChild(notificationHost); 54 | } else { 55 | notificationContainer.insertBefore(notificationHost, notificationContainer.firstChild); 56 | } 57 | 58 | notificationController.slot = new ViewSlot(notificationHost, true); 59 | notificationController.slot.add(notificationController.view); 60 | 61 | notificationController.showNotification = () => { 62 | this.notificationControllers.push(notificationController); 63 | 64 | if (this.notificationControllers.length >= settings.limit + 1) { 65 | this.notificationControllers[0].close(this.notificationControllers[0]); 66 | } 67 | 68 | notificationController.slot.attached(); 69 | 70 | if (settings.timeout > 0) { 71 | notificationController.timer = setTimeout(notificationController.close.bind(notificationController), settings.timeout); 72 | } 73 | 74 | return new Promise(resolve => { 75 | function onTransitionEnd(e) { 76 | if (e.target !== notificationHost) { 77 | return; 78 | } 79 | notificationHost.removeEventListener(transitionEvent(), onTransitionEnd); 80 | resolve(); 81 | } 82 | 83 | notificationHost.addEventListener(transitionEvent(), onTransitionEnd); 84 | setTimeout(() => { 85 | notificationHost.classList.add('notification-host-active'); 86 | }, 0); 87 | }); 88 | }; 89 | 90 | notificationController.hideNotification = () => { 91 | let i = this.notificationControllers.indexOf(notificationController); 92 | if (i !== -1) { 93 | this.notificationControllers.splice(i, 1); 94 | } 95 | 96 | return new Promise(resolve => { 97 | function onTransitionEnd() { 98 | notificationHost.removeEventListener(transitionEvent(), onTransitionEnd); 99 | resolve(); 100 | } 101 | 102 | notificationHost.addEventListener(transitionEvent(), onTransitionEnd); 103 | notificationHost.classList.remove('notification-host-active'); 104 | }); 105 | }; 106 | 107 | notificationController.destroyNotificationHost = () => { 108 | notificationContainer.removeChild(notificationHost); 109 | notificationController.slot.detached(); 110 | 111 | return Promise.resolve(); 112 | }; 113 | 114 | return Promise.resolve(); 115 | } 116 | 117 | showNotification(notificationController) { 118 | return notificationController.showNotification(); 119 | } 120 | 121 | hideNotification(notificationController) { 122 | return notificationController.hideNotification(); 123 | } 124 | 125 | destroyNotificationHost(notificationController) { 126 | return notificationController.destroyNotificationHost(); 127 | } 128 | 129 | getNotificationContainer(containerSelector) { 130 | let notificationContainer = DOM.querySelectorAll(containerSelector); 131 | if (notificationContainer === null) { 132 | notificationContainer = DOM.querySelectorAll('body'); 133 | } 134 | 135 | return notificationContainer[0]; 136 | } 137 | }; -------------------------------------------------------------------------------- /dist/es2015/notification-service.js: -------------------------------------------------------------------------------- 1 | var _class, _temp; 2 | 3 | import { Container } from 'aurelia-dependency-injection'; 4 | import { Origin } from 'aurelia-metadata'; 5 | import { CompositionEngine } from 'aurelia-templating'; 6 | 7 | import { invokeLifecycle } from './lifecycle'; 8 | import { NotificationController } from './notification-controller'; 9 | import { NotificationLevel } from './notification-level'; 10 | import { NotificationRenderer } from './notification-renderer'; 11 | 12 | export let NotificationService = (_temp = _class = class NotificationService { 13 | 14 | constructor(compositionEngine, container, notificationRenderer) { 15 | this.compositionEngine = compositionEngine; 16 | this.container = container; 17 | this.notificationRenderer = notificationRenderer; 18 | } 19 | 20 | notify(model, settings, level) { 21 | let _settings = Object.assign({}, this.notificationRenderer.defaultSettings, settings); 22 | let notificationController = new NotificationController(this.notificationRenderer, _createSettings(model, _settings, level)); 23 | let childContainer = this.container.createChild(); 24 | childContainer.registerInstance(NotificationController, notificationController); 25 | 26 | return _getViewModel(this.container, childContainer, this.compositionEngine, notificationController).then(returnedCompositionContext => { 27 | notificationController.viewModel = returnedCompositionContext.viewModel; 28 | 29 | return invokeLifecycle(returnedCompositionContext.viewModel, 'canActivate', _settings.model).then(canActivate => { 30 | if (canActivate) { 31 | this.compositionEngine.createController(returnedCompositionContext).then(controller => { 32 | notificationController.controller = controller; 33 | notificationController.view = controller.view; 34 | controller.automate(); 35 | 36 | return this.notificationRenderer.createNotificationHost(notificationController); 37 | }).then(() => { 38 | return this.notificationRenderer.showNotification(notificationController); 39 | }); 40 | } 41 | }); 42 | }); 43 | } 44 | 45 | info(message, settings) { 46 | this.notify(message, settings, NotificationLevel.info); 47 | } 48 | 49 | success(message, settings) { 50 | this.notify(message, settings, NotificationLevel.success); 51 | } 52 | 53 | warning(message, settings) { 54 | this.notify(message, settings, NotificationLevel.warning); 55 | } 56 | 57 | danger(message, settings) { 58 | this.notify(message, settings, NotificationLevel.danger); 59 | } 60 | }, _class.inject = [CompositionEngine, Container, NotificationRenderer], _temp); 61 | 62 | function _createSettings(model, settings, level) { 63 | let notification; 64 | if (typeof model === 'string') { 65 | notification = model; 66 | } else if (typeof model === 'object') { 67 | if (model.notification === undefined) { 68 | throw new Error('model must implement `notification` property.'); 69 | } 70 | notification = model.notification; 71 | } else { 72 | throw new Error('type is not supported by `notify()`.'); 73 | } 74 | 75 | settings.model = { 76 | notification: notification, 77 | data: model, 78 | level: level || NotificationLevel.info 79 | }; 80 | return settings; 81 | } 82 | 83 | function _getViewModel(container, childContainer, compositionEngine, notificationController) { 84 | let compositionContext = { 85 | container: container, 86 | childContainer: childContainer, 87 | model: notificationController.settings.model, 88 | viewModel: notificationController.settings.viewModel 89 | }; 90 | 91 | if (typeof compositionContext.viewModel === 'function') { 92 | compositionContext.viewModel = Origin.get(compositionContext.viewModel).moduleId; 93 | } 94 | 95 | if (typeof compositionContext.viewModel === 'string') { 96 | return compositionEngine.ensureViewModel(compositionContext); 97 | } 98 | 99 | return Promise.resolve(compositionContext); 100 | } -------------------------------------------------------------------------------- /dist/es2015/style.css: -------------------------------------------------------------------------------- 1 | notification-host { 2 | display: block; 3 | transition: opacity .2s linear; 4 | opacity: 0; 5 | } 6 | 7 | .notification-host-active { 8 | opacity: 1; 9 | } 10 | -------------------------------------------------------------------------------- /dist/native-modules/aurelia-notify.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.__esModule = true; 4 | exports.NotificationController = exports.NotificationService = exports.NotificationLevel = exports.BSNotification = undefined; 5 | exports.configure = configure; 6 | 7 | var _bsNotification = require('./bs-notification'); 8 | 9 | Object.defineProperty(exports, 'BSNotification', { 10 | enumerable: true, 11 | get: function get() { 12 | return _bsNotification.BSNotification; 13 | } 14 | }); 15 | 16 | var _notificationLevel = require('./notification-level'); 17 | 18 | Object.defineProperty(exports, 'NotificationLevel', { 19 | enumerable: true, 20 | get: function get() { 21 | return _notificationLevel.NotificationLevel; 22 | } 23 | }); 24 | 25 | var _notificationService = require('./notification-service'); 26 | 27 | Object.defineProperty(exports, 'NotificationService', { 28 | enumerable: true, 29 | get: function get() { 30 | return _notificationService.NotificationService; 31 | } 32 | }); 33 | 34 | var _notificationController = require('./notification-controller'); 35 | 36 | Object.defineProperty(exports, 'NotificationController', { 37 | enumerable: true, 38 | get: function get() { 39 | return _notificationController.NotificationController; 40 | } 41 | }); 42 | 43 | var _aureliaPal = require('aurelia-pal'); 44 | 45 | var _notificationRenderer = require('./notification-renderer'); 46 | 47 | function configure(config, callback) { 48 | config.globalResources(_aureliaPal.PLATFORM.moduleName('./bs-notification')); 49 | 50 | if (typeof callback === 'function') { 51 | callback(_notificationRenderer.globalSettings); 52 | } 53 | } -------------------------------------------------------------------------------- /dist/native-modules/bs-notification.html: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /dist/native-modules/bs-notification.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.__esModule = true; 4 | exports.BSNotification = undefined; 5 | 6 | var _class, _temp; 7 | 8 | var _notificationController = require('./notification-controller'); 9 | 10 | 11 | 12 | var BSNotification = exports.BSNotification = (_temp = _class = function () { 13 | function BSNotification(controller) { 14 | 15 | 16 | this.controller = controller; 17 | } 18 | 19 | BSNotification.prototype.activate = function activate(model) { 20 | this.level = model.level; 21 | this.notification = model.notification; 22 | }; 23 | 24 | return BSNotification; 25 | }(), _class.inject = [_notificationController.NotificationController], _temp); -------------------------------------------------------------------------------- /dist/native-modules/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.__esModule = true; 4 | 5 | var _aureliaNotify = require('./aurelia-notify'); 6 | 7 | Object.keys(_aureliaNotify).forEach(function (key) { 8 | if (key === "default" || key === "__esModule") return; 9 | Object.defineProperty(exports, key, { 10 | enumerable: true, 11 | get: function get() { 12 | return _aureliaNotify[key]; 13 | } 14 | }); 15 | }); -------------------------------------------------------------------------------- /dist/native-modules/lifecycle.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.__esModule = true; 4 | exports.invokeLifecycle = invokeLifecycle; 5 | function invokeLifecycle(instance, name, model) { 6 | if (typeof instance[name] === 'function') { 7 | return new Promise(function (resolve) { 8 | resolve(instance[name](model)); 9 | }).then(function (result) { 10 | if (result !== null && result !== undefined) { 11 | return result; 12 | } 13 | return true; 14 | }); 15 | } 16 | return Promise.resolve(true); 17 | } -------------------------------------------------------------------------------- /dist/native-modules/notification-controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.__esModule = true; 4 | exports.NotificationController = undefined; 5 | 6 | var _lifecycle = require('./lifecycle'); 7 | 8 | 9 | 10 | var NotificationController = exports.NotificationController = function () { 11 | function NotificationController(renderer, settings) { 12 | 13 | 14 | this.renderer = renderer; 15 | this.settings = settings; 16 | } 17 | 18 | NotificationController.prototype.close = function close() { 19 | var _this = this; 20 | 21 | if (this.closePromise) { 22 | return this.closePromise; 23 | } 24 | clearTimeout(this.timer); 25 | return this.closePromise = (0, _lifecycle.invokeLifecycle)(this.viewModel, 'canDeactivate').then(function (canDeactivate) { 26 | if (canDeactivate) { 27 | return (0, _lifecycle.invokeLifecycle)(_this.viewModel, 'deactivate').then(function () { 28 | return _this.renderer.hideNotification(_this); 29 | }).then(function () { 30 | return _this.renderer.destroyNotificationHost(_this); 31 | }).then(function () { 32 | _this.controller.unbind(); 33 | }); 34 | } 35 | }); 36 | }; 37 | 38 | return NotificationController; 39 | }(); -------------------------------------------------------------------------------- /dist/native-modules/notification-level.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.__esModule = true; 4 | var NotificationLevel = exports.NotificationLevel = { 5 | info: 'info', 6 | success: 'success', 7 | warning: 'warning', 8 | danger: 'danger' 9 | }; -------------------------------------------------------------------------------- /dist/native-modules/notification-renderer.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.__esModule = true; 4 | exports.NotificationRenderer = exports.globalSettings = undefined; 5 | 6 | var _aureliaPal = require('aurelia-pal'); 7 | 8 | var _aureliaTemplating = require('aurelia-templating'); 9 | 10 | var _bsNotification = require('./bs-notification'); 11 | 12 | 13 | 14 | var globalSettings = exports.globalSettings = { 15 | append: false, 16 | containerSelector: 'body', 17 | timeout: 0, 18 | viewModel: _bsNotification.BSNotification, 19 | limit: 5 20 | }; 21 | 22 | var transitionEvent = function () { 23 | var transition = null; 24 | 25 | return function () { 26 | if (transition) return transition; 27 | 28 | var t = void 0; 29 | var el = _aureliaPal.DOM.createElement('fakeelement'); 30 | var transitions = { 31 | 'transition': 'transitionend', 32 | 'OTransition': 'oTransitionEnd', 33 | 'MozTransition': 'transitionend', 34 | 'WebkitTransition': 'webkitTransitionEnd' 35 | }; 36 | for (t in transitions) { 37 | if (el.style[t] !== undefined) { 38 | transition = transitions[t]; 39 | return transition; 40 | } 41 | } 42 | 43 | return undefined; 44 | }; 45 | }(); 46 | 47 | var NotificationRenderer = exports.NotificationRenderer = function () { 48 | function NotificationRenderer() { 49 | 50 | 51 | this.defaultSettings = globalSettings; 52 | 53 | this.notificationControllers = []; 54 | } 55 | 56 | NotificationRenderer.prototype.createNotificationHost = function createNotificationHost(notificationController) { 57 | var _this = this; 58 | 59 | var settings = notificationController.settings; 60 | var notificationHost = _aureliaPal.DOM.createElement('notification-host'); 61 | var notificationContainer = this.getNotificationContainer(settings.containerSelector); 62 | 63 | if (settings.append === true) { 64 | notificationContainer.appendChild(notificationHost); 65 | } else { 66 | notificationContainer.insertBefore(notificationHost, notificationContainer.firstChild); 67 | } 68 | 69 | notificationController.slot = new _aureliaTemplating.ViewSlot(notificationHost, true); 70 | notificationController.slot.add(notificationController.view); 71 | 72 | notificationController.showNotification = function () { 73 | _this.notificationControllers.push(notificationController); 74 | 75 | if (_this.notificationControllers.length >= settings.limit + 1) { 76 | _this.notificationControllers[0].close(_this.notificationControllers[0]); 77 | } 78 | 79 | notificationController.slot.attached(); 80 | 81 | if (settings.timeout > 0) { 82 | notificationController.timer = setTimeout(notificationController.close.bind(notificationController), settings.timeout); 83 | } 84 | 85 | return new Promise(function (resolve) { 86 | function onTransitionEnd(e) { 87 | if (e.target !== notificationHost) { 88 | return; 89 | } 90 | notificationHost.removeEventListener(transitionEvent(), onTransitionEnd); 91 | resolve(); 92 | } 93 | 94 | notificationHost.addEventListener(transitionEvent(), onTransitionEnd); 95 | setTimeout(function () { 96 | notificationHost.classList.add('notification-host-active'); 97 | }, 0); 98 | }); 99 | }; 100 | 101 | notificationController.hideNotification = function () { 102 | var i = _this.notificationControllers.indexOf(notificationController); 103 | if (i !== -1) { 104 | _this.notificationControllers.splice(i, 1); 105 | } 106 | 107 | return new Promise(function (resolve) { 108 | function onTransitionEnd() { 109 | notificationHost.removeEventListener(transitionEvent(), onTransitionEnd); 110 | resolve(); 111 | } 112 | 113 | notificationHost.addEventListener(transitionEvent(), onTransitionEnd); 114 | notificationHost.classList.remove('notification-host-active'); 115 | }); 116 | }; 117 | 118 | notificationController.destroyNotificationHost = function () { 119 | notificationContainer.removeChild(notificationHost); 120 | notificationController.slot.detached(); 121 | 122 | return Promise.resolve(); 123 | }; 124 | 125 | return Promise.resolve(); 126 | }; 127 | 128 | NotificationRenderer.prototype.showNotification = function showNotification(notificationController) { 129 | return notificationController.showNotification(); 130 | }; 131 | 132 | NotificationRenderer.prototype.hideNotification = function hideNotification(notificationController) { 133 | return notificationController.hideNotification(); 134 | }; 135 | 136 | NotificationRenderer.prototype.destroyNotificationHost = function destroyNotificationHost(notificationController) { 137 | return notificationController.destroyNotificationHost(); 138 | }; 139 | 140 | NotificationRenderer.prototype.getNotificationContainer = function getNotificationContainer(containerSelector) { 141 | var notificationContainer = _aureliaPal.DOM.querySelectorAll(containerSelector); 142 | if (notificationContainer === null) { 143 | notificationContainer = _aureliaPal.DOM.querySelectorAll('body'); 144 | } 145 | 146 | return notificationContainer[0]; 147 | }; 148 | 149 | return NotificationRenderer; 150 | }(); -------------------------------------------------------------------------------- /dist/native-modules/notification-service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.__esModule = true; 4 | exports.NotificationService = undefined; 5 | 6 | var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; 7 | 8 | var _class, _temp; 9 | 10 | var _aureliaDependencyInjection = require('aurelia-dependency-injection'); 11 | 12 | var _aureliaMetadata = require('aurelia-metadata'); 13 | 14 | var _aureliaTemplating = require('aurelia-templating'); 15 | 16 | var _lifecycle = require('./lifecycle'); 17 | 18 | var _notificationController = require('./notification-controller'); 19 | 20 | var _notificationLevel = require('./notification-level'); 21 | 22 | var _notificationRenderer = require('./notification-renderer'); 23 | 24 | 25 | 26 | var NotificationService = exports.NotificationService = (_temp = _class = function () { 27 | function NotificationService(compositionEngine, container, notificationRenderer) { 28 | 29 | 30 | this.compositionEngine = compositionEngine; 31 | this.container = container; 32 | this.notificationRenderer = notificationRenderer; 33 | } 34 | 35 | NotificationService.prototype.notify = function notify(model, settings, level) { 36 | var _this = this; 37 | 38 | var _settings = Object.assign({}, this.notificationRenderer.defaultSettings, settings); 39 | var notificationController = new _notificationController.NotificationController(this.notificationRenderer, _createSettings(model, _settings, level)); 40 | var childContainer = this.container.createChild(); 41 | childContainer.registerInstance(_notificationController.NotificationController, notificationController); 42 | 43 | return _getViewModel(this.container, childContainer, this.compositionEngine, notificationController).then(function (returnedCompositionContext) { 44 | notificationController.viewModel = returnedCompositionContext.viewModel; 45 | 46 | return (0, _lifecycle.invokeLifecycle)(returnedCompositionContext.viewModel, 'canActivate', _settings.model).then(function (canActivate) { 47 | if (canActivate) { 48 | _this.compositionEngine.createController(returnedCompositionContext).then(function (controller) { 49 | notificationController.controller = controller; 50 | notificationController.view = controller.view; 51 | controller.automate(); 52 | 53 | return _this.notificationRenderer.createNotificationHost(notificationController); 54 | }).then(function () { 55 | return _this.notificationRenderer.showNotification(notificationController); 56 | }); 57 | } 58 | }); 59 | }); 60 | }; 61 | 62 | NotificationService.prototype.info = function info(message, settings) { 63 | this.notify(message, settings, _notificationLevel.NotificationLevel.info); 64 | }; 65 | 66 | NotificationService.prototype.success = function success(message, settings) { 67 | this.notify(message, settings, _notificationLevel.NotificationLevel.success); 68 | }; 69 | 70 | NotificationService.prototype.warning = function warning(message, settings) { 71 | this.notify(message, settings, _notificationLevel.NotificationLevel.warning); 72 | }; 73 | 74 | NotificationService.prototype.danger = function danger(message, settings) { 75 | this.notify(message, settings, _notificationLevel.NotificationLevel.danger); 76 | }; 77 | 78 | return NotificationService; 79 | }(), _class.inject = [_aureliaTemplating.CompositionEngine, _aureliaDependencyInjection.Container, _notificationRenderer.NotificationRenderer], _temp); 80 | 81 | 82 | function _createSettings(model, settings, level) { 83 | var notification = void 0; 84 | if (typeof model === 'string') { 85 | notification = model; 86 | } else if ((typeof model === 'undefined' ? 'undefined' : _typeof(model)) === 'object') { 87 | if (model.notification === undefined) { 88 | throw new Error('model must implement `notification` property.'); 89 | } 90 | notification = model.notification; 91 | } else { 92 | throw new Error('type is not supported by `notify()`.'); 93 | } 94 | 95 | settings.model = { 96 | notification: notification, 97 | data: model, 98 | level: level || _notificationLevel.NotificationLevel.info 99 | }; 100 | return settings; 101 | } 102 | 103 | function _getViewModel(container, childContainer, compositionEngine, notificationController) { 104 | var compositionContext = { 105 | container: container, 106 | childContainer: childContainer, 107 | model: notificationController.settings.model, 108 | viewModel: notificationController.settings.viewModel 109 | }; 110 | 111 | if (typeof compositionContext.viewModel === 'function') { 112 | compositionContext.viewModel = _aureliaMetadata.Origin.get(compositionContext.viewModel).moduleId; 113 | } 114 | 115 | if (typeof compositionContext.viewModel === 'string') { 116 | return compositionEngine.ensureViewModel(compositionContext); 117 | } 118 | 119 | return Promise.resolve(compositionContext); 120 | } -------------------------------------------------------------------------------- /dist/native-modules/style.css: -------------------------------------------------------------------------------- 1 | notification-host { 2 | display: block; 3 | transition: opacity .2s linear; 4 | opacity: 0; 5 | } 6 | 7 | .notification-host-active { 8 | opacity: 1; 9 | } 10 | -------------------------------------------------------------------------------- /dist/system/aurelia-notify.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | System.register(['aurelia-pal', './notification-renderer', './bs-notification', './notification-level', './notification-service', './notification-controller'], function (_export, _context) { 4 | "use strict"; 5 | 6 | var PLATFORM, globalSettings; 7 | function configure(config, callback) { 8 | config.globalResources(PLATFORM.moduleName('./bs-notification')); 9 | 10 | if (typeof callback === 'function') { 11 | callback(globalSettings); 12 | } 13 | } 14 | 15 | _export('configure', configure); 16 | 17 | return { 18 | setters: [function (_aureliaPal) { 19 | PLATFORM = _aureliaPal.PLATFORM; 20 | }, function (_notificationRenderer) { 21 | globalSettings = _notificationRenderer.globalSettings; 22 | }, function (_bsNotification) { 23 | var _exportObj = {}; 24 | _exportObj.BSNotification = _bsNotification.BSNotification; 25 | 26 | _export(_exportObj); 27 | }, function (_notificationLevel) { 28 | var _exportObj2 = {}; 29 | _exportObj2.NotificationLevel = _notificationLevel.NotificationLevel; 30 | 31 | _export(_exportObj2); 32 | }, function (_notificationService) { 33 | var _exportObj3 = {}; 34 | _exportObj3.NotificationService = _notificationService.NotificationService; 35 | 36 | _export(_exportObj3); 37 | }, function (_notificationController) { 38 | var _exportObj4 = {}; 39 | _exportObj4.NotificationController = _notificationController.NotificationController; 40 | 41 | _export(_exportObj4); 42 | }], 43 | execute: function () {} 44 | }; 45 | }); -------------------------------------------------------------------------------- /dist/system/bs-notification.html: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /dist/system/bs-notification.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | System.register(['./notification-controller'], function (_export, _context) { 4 | "use strict"; 5 | 6 | var NotificationController, _class, _temp, BSNotification; 7 | 8 | 9 | 10 | return { 11 | setters: [function (_notificationController) { 12 | NotificationController = _notificationController.NotificationController; 13 | }], 14 | execute: function () { 15 | _export('BSNotification', BSNotification = (_temp = _class = function () { 16 | function BSNotification(controller) { 17 | 18 | 19 | this.controller = controller; 20 | } 21 | 22 | BSNotification.prototype.activate = function activate(model) { 23 | this.level = model.level; 24 | this.notification = model.notification; 25 | }; 26 | 27 | return BSNotification; 28 | }(), _class.inject = [NotificationController], _temp)); 29 | 30 | _export('BSNotification', BSNotification); 31 | } 32 | }; 33 | }); -------------------------------------------------------------------------------- /dist/system/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | System.register(['./aurelia-notify'], function (_export, _context) { 4 | "use strict"; 5 | 6 | return { 7 | setters: [function (_aureliaNotify) { 8 | var _exportObj = {}; 9 | 10 | for (var _key in _aureliaNotify) { 11 | if (_key !== "default" && _key !== "__esModule") _exportObj[_key] = _aureliaNotify[_key]; 12 | } 13 | 14 | _export(_exportObj); 15 | }], 16 | execute: function () {} 17 | }; 18 | }); -------------------------------------------------------------------------------- /dist/system/lifecycle.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | System.register([], function (_export, _context) { 4 | "use strict"; 5 | 6 | function invokeLifecycle(instance, name, model) { 7 | if (typeof instance[name] === 'function') { 8 | return new Promise(function (resolve) { 9 | resolve(instance[name](model)); 10 | }).then(function (result) { 11 | if (result !== null && result !== undefined) { 12 | return result; 13 | } 14 | return true; 15 | }); 16 | } 17 | return Promise.resolve(true); 18 | } 19 | 20 | _export('invokeLifecycle', invokeLifecycle); 21 | 22 | return { 23 | setters: [], 24 | execute: function () {} 25 | }; 26 | }); -------------------------------------------------------------------------------- /dist/system/notification-controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | System.register(['./lifecycle'], function (_export, _context) { 4 | "use strict"; 5 | 6 | var invokeLifecycle, NotificationController; 7 | 8 | 9 | 10 | return { 11 | setters: [function (_lifecycle) { 12 | invokeLifecycle = _lifecycle.invokeLifecycle; 13 | }], 14 | execute: function () { 15 | _export('NotificationController', NotificationController = function () { 16 | function NotificationController(renderer, settings) { 17 | 18 | 19 | this.renderer = renderer; 20 | this.settings = settings; 21 | } 22 | 23 | NotificationController.prototype.close = function close() { 24 | var _this = this; 25 | 26 | if (this.closePromise) { 27 | return this.closePromise; 28 | } 29 | clearTimeout(this.timer); 30 | return this.closePromise = invokeLifecycle(this.viewModel, 'canDeactivate').then(function (canDeactivate) { 31 | if (canDeactivate) { 32 | return invokeLifecycle(_this.viewModel, 'deactivate').then(function () { 33 | return _this.renderer.hideNotification(_this); 34 | }).then(function () { 35 | return _this.renderer.destroyNotificationHost(_this); 36 | }).then(function () { 37 | _this.controller.unbind(); 38 | }); 39 | } 40 | }); 41 | }; 42 | 43 | return NotificationController; 44 | }()); 45 | 46 | _export('NotificationController', NotificationController); 47 | } 48 | }; 49 | }); -------------------------------------------------------------------------------- /dist/system/notification-level.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | System.register([], function (_export, _context) { 4 | "use strict"; 5 | 6 | var NotificationLevel; 7 | return { 8 | setters: [], 9 | execute: function () { 10 | _export('NotificationLevel', NotificationLevel = { 11 | info: 'info', 12 | success: 'success', 13 | warning: 'warning', 14 | danger: 'danger' 15 | }); 16 | 17 | _export('NotificationLevel', NotificationLevel); 18 | } 19 | }; 20 | }); -------------------------------------------------------------------------------- /dist/system/notification-renderer.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | System.register(['aurelia-pal', 'aurelia-templating', './bs-notification'], function (_export, _context) { 4 | "use strict"; 5 | 6 | var DOM, ViewSlot, BSNotification, globalSettings, transitionEvent, NotificationRenderer; 7 | 8 | 9 | 10 | return { 11 | setters: [function (_aureliaPal) { 12 | DOM = _aureliaPal.DOM; 13 | }, function (_aureliaTemplating) { 14 | ViewSlot = _aureliaTemplating.ViewSlot; 15 | }, function (_bsNotification) { 16 | BSNotification = _bsNotification.BSNotification; 17 | }], 18 | execute: function () { 19 | _export('globalSettings', globalSettings = { 20 | append: false, 21 | containerSelector: 'body', 22 | timeout: 0, 23 | viewModel: BSNotification, 24 | limit: 5 25 | }); 26 | 27 | _export('globalSettings', globalSettings); 28 | 29 | transitionEvent = function () { 30 | var transition = null; 31 | 32 | return function () { 33 | if (transition) return transition; 34 | 35 | var t = void 0; 36 | var el = DOM.createElement('fakeelement'); 37 | var transitions = { 38 | 'transition': 'transitionend', 39 | 'OTransition': 'oTransitionEnd', 40 | 'MozTransition': 'transitionend', 41 | 'WebkitTransition': 'webkitTransitionEnd' 42 | }; 43 | for (t in transitions) { 44 | if (el.style[t] !== undefined) { 45 | transition = transitions[t]; 46 | return transition; 47 | } 48 | } 49 | 50 | return undefined; 51 | }; 52 | }(); 53 | 54 | _export('NotificationRenderer', NotificationRenderer = function () { 55 | function NotificationRenderer() { 56 | 57 | 58 | this.defaultSettings = globalSettings; 59 | 60 | this.notificationControllers = []; 61 | } 62 | 63 | NotificationRenderer.prototype.createNotificationHost = function createNotificationHost(notificationController) { 64 | var _this = this; 65 | 66 | var settings = notificationController.settings; 67 | var notificationHost = DOM.createElement('notification-host'); 68 | var notificationContainer = this.getNotificationContainer(settings.containerSelector); 69 | 70 | if (settings.append === true) { 71 | notificationContainer.appendChild(notificationHost); 72 | } else { 73 | notificationContainer.insertBefore(notificationHost, notificationContainer.firstChild); 74 | } 75 | 76 | notificationController.slot = new ViewSlot(notificationHost, true); 77 | notificationController.slot.add(notificationController.view); 78 | 79 | notificationController.showNotification = function () { 80 | _this.notificationControllers.push(notificationController); 81 | 82 | if (_this.notificationControllers.length >= settings.limit + 1) { 83 | _this.notificationControllers[0].close(_this.notificationControllers[0]); 84 | } 85 | 86 | notificationController.slot.attached(); 87 | 88 | if (settings.timeout > 0) { 89 | notificationController.timer = setTimeout(notificationController.close.bind(notificationController), settings.timeout); 90 | } 91 | 92 | return new Promise(function (resolve) { 93 | function onTransitionEnd(e) { 94 | if (e.target !== notificationHost) { 95 | return; 96 | } 97 | notificationHost.removeEventListener(transitionEvent(), onTransitionEnd); 98 | resolve(); 99 | } 100 | 101 | notificationHost.addEventListener(transitionEvent(), onTransitionEnd); 102 | setTimeout(function () { 103 | notificationHost.classList.add('notification-host-active'); 104 | }, 0); 105 | }); 106 | }; 107 | 108 | notificationController.hideNotification = function () { 109 | var i = _this.notificationControllers.indexOf(notificationController); 110 | if (i !== -1) { 111 | _this.notificationControllers.splice(i, 1); 112 | } 113 | 114 | return new Promise(function (resolve) { 115 | function onTransitionEnd() { 116 | notificationHost.removeEventListener(transitionEvent(), onTransitionEnd); 117 | resolve(); 118 | } 119 | 120 | notificationHost.addEventListener(transitionEvent(), onTransitionEnd); 121 | notificationHost.classList.remove('notification-host-active'); 122 | }); 123 | }; 124 | 125 | notificationController.destroyNotificationHost = function () { 126 | notificationContainer.removeChild(notificationHost); 127 | notificationController.slot.detached(); 128 | 129 | return Promise.resolve(); 130 | }; 131 | 132 | return Promise.resolve(); 133 | }; 134 | 135 | NotificationRenderer.prototype.showNotification = function showNotification(notificationController) { 136 | return notificationController.showNotification(); 137 | }; 138 | 139 | NotificationRenderer.prototype.hideNotification = function hideNotification(notificationController) { 140 | return notificationController.hideNotification(); 141 | }; 142 | 143 | NotificationRenderer.prototype.destroyNotificationHost = function destroyNotificationHost(notificationController) { 144 | return notificationController.destroyNotificationHost(); 145 | }; 146 | 147 | NotificationRenderer.prototype.getNotificationContainer = function getNotificationContainer(containerSelector) { 148 | var notificationContainer = DOM.querySelectorAll(containerSelector); 149 | if (notificationContainer === null) { 150 | notificationContainer = DOM.querySelectorAll('body'); 151 | } 152 | 153 | return notificationContainer[0]; 154 | }; 155 | 156 | return NotificationRenderer; 157 | }()); 158 | 159 | _export('NotificationRenderer', NotificationRenderer); 160 | } 161 | }; 162 | }); -------------------------------------------------------------------------------- /dist/system/notification-service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | System.register(['aurelia-dependency-injection', 'aurelia-metadata', 'aurelia-templating', './lifecycle', './notification-controller', './notification-level', './notification-renderer'], function (_export, _context) { 4 | "use strict"; 5 | 6 | var Container, Origin, CompositionEngine, invokeLifecycle, NotificationController, NotificationLevel, NotificationRenderer, _typeof, _class, _temp, NotificationService; 7 | 8 | 9 | 10 | function _createSettings(model, settings, level) { 11 | var notification = void 0; 12 | if (typeof model === 'string') { 13 | notification = model; 14 | } else if ((typeof model === 'undefined' ? 'undefined' : _typeof(model)) === 'object') { 15 | if (model.notification === undefined) { 16 | throw new Error('model must implement `notification` property.'); 17 | } 18 | notification = model.notification; 19 | } else { 20 | throw new Error('type is not supported by `notify()`.'); 21 | } 22 | 23 | settings.model = { 24 | notification: notification, 25 | data: model, 26 | level: level || NotificationLevel.info 27 | }; 28 | return settings; 29 | } 30 | 31 | function _getViewModel(container, childContainer, compositionEngine, notificationController) { 32 | var compositionContext = { 33 | container: container, 34 | childContainer: childContainer, 35 | model: notificationController.settings.model, 36 | viewModel: notificationController.settings.viewModel 37 | }; 38 | 39 | if (typeof compositionContext.viewModel === 'function') { 40 | compositionContext.viewModel = Origin.get(compositionContext.viewModel).moduleId; 41 | } 42 | 43 | if (typeof compositionContext.viewModel === 'string') { 44 | return compositionEngine.ensureViewModel(compositionContext); 45 | } 46 | 47 | return Promise.resolve(compositionContext); 48 | } 49 | return { 50 | setters: [function (_aureliaDependencyInjection) { 51 | Container = _aureliaDependencyInjection.Container; 52 | }, function (_aureliaMetadata) { 53 | Origin = _aureliaMetadata.Origin; 54 | }, function (_aureliaTemplating) { 55 | CompositionEngine = _aureliaTemplating.CompositionEngine; 56 | }, function (_lifecycle) { 57 | invokeLifecycle = _lifecycle.invokeLifecycle; 58 | }, function (_notificationController) { 59 | NotificationController = _notificationController.NotificationController; 60 | }, function (_notificationLevel) { 61 | NotificationLevel = _notificationLevel.NotificationLevel; 62 | }, function (_notificationRenderer) { 63 | NotificationRenderer = _notificationRenderer.NotificationRenderer; 64 | }], 65 | execute: function () { 66 | _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { 67 | return typeof obj; 68 | } : function (obj) { 69 | return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; 70 | }; 71 | 72 | _export('NotificationService', NotificationService = (_temp = _class = function () { 73 | function NotificationService(compositionEngine, container, notificationRenderer) { 74 | 75 | 76 | this.compositionEngine = compositionEngine; 77 | this.container = container; 78 | this.notificationRenderer = notificationRenderer; 79 | } 80 | 81 | NotificationService.prototype.notify = function notify(model, settings, level) { 82 | var _this = this; 83 | 84 | var _settings = Object.assign({}, this.notificationRenderer.defaultSettings, settings); 85 | var notificationController = new NotificationController(this.notificationRenderer, _createSettings(model, _settings, level)); 86 | var childContainer = this.container.createChild(); 87 | childContainer.registerInstance(NotificationController, notificationController); 88 | 89 | return _getViewModel(this.container, childContainer, this.compositionEngine, notificationController).then(function (returnedCompositionContext) { 90 | notificationController.viewModel = returnedCompositionContext.viewModel; 91 | 92 | return invokeLifecycle(returnedCompositionContext.viewModel, 'canActivate', _settings.model).then(function (canActivate) { 93 | if (canActivate) { 94 | _this.compositionEngine.createController(returnedCompositionContext).then(function (controller) { 95 | notificationController.controller = controller; 96 | notificationController.view = controller.view; 97 | controller.automate(); 98 | 99 | return _this.notificationRenderer.createNotificationHost(notificationController); 100 | }).then(function () { 101 | return _this.notificationRenderer.showNotification(notificationController); 102 | }); 103 | } 104 | }); 105 | }); 106 | }; 107 | 108 | NotificationService.prototype.info = function info(message, settings) { 109 | this.notify(message, settings, NotificationLevel.info); 110 | }; 111 | 112 | NotificationService.prototype.success = function success(message, settings) { 113 | this.notify(message, settings, NotificationLevel.success); 114 | }; 115 | 116 | NotificationService.prototype.warning = function warning(message, settings) { 117 | this.notify(message, settings, NotificationLevel.warning); 118 | }; 119 | 120 | NotificationService.prototype.danger = function danger(message, settings) { 121 | this.notify(message, settings, NotificationLevel.danger); 122 | }; 123 | 124 | return NotificationService; 125 | }(), _class.inject = [CompositionEngine, Container, NotificationRenderer], _temp)); 126 | 127 | _export('NotificationService', NotificationService); 128 | } 129 | }; 130 | }); -------------------------------------------------------------------------------- /dist/system/style.css: -------------------------------------------------------------------------------- 1 | notification-host { 2 | display: block; 3 | transition: opacity .2s linear; 4 | opacity: 0; 5 | } 6 | 7 | .notification-host-active { 8 | opacity: 1; 9 | } 10 | -------------------------------------------------------------------------------- /dist/temp/aurelia-notify.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.NotificationService = exports.NotificationRenderer = exports.globalSettings = exports.BSNotification = exports.NotificationController = exports.NotificationLevel = undefined; 7 | 8 | var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; 9 | 10 | var _class, _temp, _class3, _temp2; 11 | 12 | exports.invokeLifecycle = invokeLifecycle; 13 | 14 | var _aureliaPal = require('aurelia-pal'); 15 | 16 | var _aureliaTemplating = require('aurelia-templating'); 17 | 18 | var _aureliaDependencyInjection = require('aurelia-dependency-injection'); 19 | 20 | var _aureliaMetadata = require('aurelia-metadata'); 21 | 22 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 23 | 24 | var NotificationLevel = exports.NotificationLevel = { 25 | info: 'info', 26 | success: 'success', 27 | warning: 'warning', 28 | danger: 'danger' 29 | }; 30 | 31 | function invokeLifecycle(instance, name, model) { 32 | if (typeof instance[name] === 'function') { 33 | return new Promise(function (resolve) { 34 | resolve(instance[name](model)); 35 | }).then(function (result) { 36 | if (result !== null && result !== undefined) { 37 | return result; 38 | } 39 | return true; 40 | }); 41 | } 42 | return Promise.resolve(true); 43 | } 44 | 45 | var NotificationController = exports.NotificationController = function () { 46 | function NotificationController(renderer, settings) { 47 | _classCallCheck(this, NotificationController); 48 | 49 | this.renderer = renderer; 50 | this.settings = settings; 51 | } 52 | 53 | NotificationController.prototype.close = function close() { 54 | var _this = this; 55 | 56 | if (this.closePromise) { 57 | return this.closePromise; 58 | } 59 | clearTimeout(this.timer); 60 | return this.closePromise = invokeLifecycle(this.viewModel, 'canDeactivate').then(function (canDeactivate) { 61 | if (canDeactivate) { 62 | return invokeLifecycle(_this.viewModel, 'deactivate').then(function () { 63 | return _this.renderer.hideNotification(_this); 64 | }).then(function () { 65 | return _this.renderer.destroyNotificationHost(_this); 66 | }).then(function () { 67 | _this.controller.unbind(); 68 | }); 69 | } 70 | }); 71 | }; 72 | 73 | return NotificationController; 74 | }(); 75 | 76 | var BSNotification = exports.BSNotification = (_temp = _class = function () { 77 | function BSNotification(controller) { 78 | _classCallCheck(this, BSNotification); 79 | 80 | this.controller = controller; 81 | } 82 | 83 | BSNotification.prototype.activate = function activate(model) { 84 | this.level = model.level; 85 | this.notification = model.notification; 86 | }; 87 | 88 | return BSNotification; 89 | }(), _class.inject = [NotificationController], _temp); 90 | var globalSettings = exports.globalSettings = { 91 | append: false, 92 | containerSelector: 'body', 93 | timeout: 0, 94 | viewModel: BSNotification, 95 | limit: 5 96 | }; 97 | 98 | var transitionEvent = function () { 99 | var transition = null; 100 | 101 | return function () { 102 | if (transition) return transition; 103 | 104 | var t = void 0; 105 | var el = _aureliaPal.DOM.createElement('fakeelement'); 106 | var transitions = { 107 | 'transition': 'transitionend', 108 | 'OTransition': 'oTransitionEnd', 109 | 'MozTransition': 'transitionend', 110 | 'WebkitTransition': 'webkitTransitionEnd' 111 | }; 112 | for (t in transitions) { 113 | if (el.style[t] !== undefined) { 114 | transition = transitions[t]; 115 | return transition; 116 | } 117 | } 118 | 119 | return undefined; 120 | }; 121 | }(); 122 | 123 | var NotificationRenderer = exports.NotificationRenderer = function () { 124 | function NotificationRenderer() { 125 | _classCallCheck(this, NotificationRenderer); 126 | 127 | this.defaultSettings = globalSettings; 128 | 129 | this.notificationControllers = []; 130 | } 131 | 132 | NotificationRenderer.prototype.createNotificationHost = function createNotificationHost(notificationController) { 133 | var _this2 = this; 134 | 135 | var settings = notificationController.settings; 136 | var notificationHost = _aureliaPal.DOM.createElement('notification-host'); 137 | var notificationContainer = this.getNotificationContainer(settings.containerSelector); 138 | 139 | if (settings.append === true) { 140 | notificationContainer.appendChild(notificationHost); 141 | } else { 142 | notificationContainer.insertBefore(notificationHost, notificationContainer.firstChild); 143 | } 144 | 145 | notificationController.slot = new _aureliaTemplating.ViewSlot(notificationHost, true); 146 | notificationController.slot.add(notificationController.view); 147 | 148 | notificationController.showNotification = function () { 149 | _this2.notificationControllers.push(notificationController); 150 | 151 | if (_this2.notificationControllers.length >= settings.limit + 1) { 152 | _this2.notificationControllers[0].close(_this2.notificationControllers[0]); 153 | } 154 | 155 | notificationController.slot.attached(); 156 | 157 | if (settings.timeout > 0) { 158 | notificationController.timer = setTimeout(notificationController.close.bind(notificationController), settings.timeout); 159 | } 160 | 161 | return new Promise(function (resolve) { 162 | function onTransitionEnd(e) { 163 | if (e.target !== notificationHost) { 164 | return; 165 | } 166 | notificationHost.removeEventListener(transitionEvent(), onTransitionEnd); 167 | resolve(); 168 | } 169 | 170 | notificationHost.addEventListener(transitionEvent(), onTransitionEnd); 171 | setTimeout(function () { 172 | notificationHost.classList.add('notification-host-active'); 173 | }, 0); 174 | }); 175 | }; 176 | 177 | notificationController.hideNotification = function () { 178 | var i = _this2.notificationControllers.indexOf(notificationController); 179 | if (i !== -1) { 180 | _this2.notificationControllers.splice(i, 1); 181 | } 182 | 183 | return new Promise(function (resolve) { 184 | function onTransitionEnd() { 185 | notificationHost.removeEventListener(transitionEvent(), onTransitionEnd); 186 | resolve(); 187 | } 188 | 189 | notificationHost.addEventListener(transitionEvent(), onTransitionEnd); 190 | notificationHost.classList.remove('notification-host-active'); 191 | }); 192 | }; 193 | 194 | notificationController.destroyNotificationHost = function () { 195 | notificationContainer.removeChild(notificationHost); 196 | notificationController.slot.detached(); 197 | 198 | return Promise.resolve(); 199 | }; 200 | 201 | return Promise.resolve(); 202 | }; 203 | 204 | NotificationRenderer.prototype.showNotification = function showNotification(notificationController) { 205 | return notificationController.showNotification(); 206 | }; 207 | 208 | NotificationRenderer.prototype.hideNotification = function hideNotification(notificationController) { 209 | return notificationController.hideNotification(); 210 | }; 211 | 212 | NotificationRenderer.prototype.destroyNotificationHost = function destroyNotificationHost(notificationController) { 213 | return notificationController.destroyNotificationHost(); 214 | }; 215 | 216 | NotificationRenderer.prototype.getNotificationContainer = function getNotificationContainer(containerSelector) { 217 | var notificationContainer = _aureliaPal.DOM.querySelectorAll(containerSelector); 218 | if (notificationContainer === null) { 219 | notificationContainer = _aureliaPal.DOM.querySelectorAll('body'); 220 | } 221 | 222 | return notificationContainer[0]; 223 | }; 224 | 225 | return NotificationRenderer; 226 | }(); 227 | 228 | var NotificationService = exports.NotificationService = (_temp2 = _class3 = function () { 229 | function NotificationService(compositionEngine, container, notificationRenderer) { 230 | _classCallCheck(this, NotificationService); 231 | 232 | this.compositionEngine = compositionEngine; 233 | this.container = container; 234 | this.notificationRenderer = notificationRenderer; 235 | } 236 | 237 | NotificationService.prototype.notify = function notify(model, settings, level) { 238 | var _this3 = this; 239 | 240 | var _settings = Object.assign({}, this.notificationRenderer.defaultSettings, settings); 241 | var notificationController = new NotificationController(this.notificationRenderer, _createSettings(model, _settings, level)); 242 | var childContainer = this.container.createChild(); 243 | childContainer.registerInstance(NotificationController, notificationController); 244 | 245 | return _getViewModel(this.container, childContainer, this.compositionEngine, notificationController).then(function (returnedCompositionContext) { 246 | notificationController.viewModel = returnedCompositionContext.viewModel; 247 | 248 | return invokeLifecycle(returnedCompositionContext.viewModel, 'canActivate', _settings.model).then(function (canActivate) { 249 | if (canActivate) { 250 | _this3.compositionEngine.createController(returnedCompositionContext).then(function (controller) { 251 | notificationController.controller = controller; 252 | notificationController.view = controller.view; 253 | controller.automate(); 254 | 255 | return _this3.notificationRenderer.createNotificationHost(notificationController); 256 | }).then(function () { 257 | return _this3.notificationRenderer.showNotification(notificationController); 258 | }); 259 | } 260 | }); 261 | }); 262 | }; 263 | 264 | NotificationService.prototype.info = function info(message, settings) { 265 | this.notify(message, settings, NotificationLevel.info); 266 | }; 267 | 268 | NotificationService.prototype.success = function success(message, settings) { 269 | this.notify(message, settings, NotificationLevel.success); 270 | }; 271 | 272 | NotificationService.prototype.warning = function warning(message, settings) { 273 | this.notify(message, settings, NotificationLevel.warning); 274 | }; 275 | 276 | NotificationService.prototype.danger = function danger(message, settings) { 277 | this.notify(message, settings, NotificationLevel.danger); 278 | }; 279 | 280 | return NotificationService; 281 | }(), _class3.inject = [_aureliaTemplating.CompositionEngine, _aureliaDependencyInjection.Container, NotificationRenderer], _temp2); 282 | 283 | 284 | function _createSettings(model, settings, level) { 285 | var notification = void 0; 286 | if (typeof model === 'string') { 287 | notification = model; 288 | } else if ((typeof model === 'undefined' ? 'undefined' : _typeof(model)) === 'object') { 289 | if (model.notification === undefined) { 290 | throw new Error('model must implement `notification` property.'); 291 | } 292 | notification = model.notification; 293 | } else { 294 | throw new Error('type is not supported by `notify()`.'); 295 | } 296 | 297 | settings.model = { 298 | notification: notification, 299 | data: model, 300 | level: level || NotificationLevel.info 301 | }; 302 | return settings; 303 | } 304 | 305 | function _getViewModel(container, childContainer, compositionEngine, notificationController) { 306 | var compositionContext = { 307 | container: container, 308 | childContainer: childContainer, 309 | model: notificationController.settings.model, 310 | viewModel: notificationController.settings.viewModel 311 | }; 312 | 313 | if (typeof compositionContext.viewModel === 'function') { 314 | compositionContext.viewModel = _aureliaMetadata.Origin.get(compositionContext.viewModel).moduleId; 315 | } 316 | 317 | if (typeof compositionContext.viewModel === 'string') { 318 | return compositionEngine.ensureViewModel(compositionContext); 319 | } 320 | 321 | return Promise.resolve(compositionContext); 322 | } -------------------------------------------------------------------------------- /doc/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | ## [0.8.1](https://github.com/MarcScheib/aurelia-notify/compare/0.8.0...0.8.1) (2017-05-16) 3 | 4 | 5 | ### Bug Fixes 6 | 7 | * **controller:** return deactivation lifecycle promise ([58c647a](https://github.com/MarcScheib/aurelia-notify/commit/58c647a)) 8 | 9 | 10 | 11 | 12 | # [0.8.0](https://github.com/MarcScheib/aurelia-notify/compare/0.7.1...0.8.0) (2017-05-15) 13 | 14 | 15 | ### Features 16 | 17 | * **webpack:** add webpack resources ([8404de9](https://github.com/MarcScheib/aurelia-notify/commit/8404de9)) 18 | 19 | 20 | 21 | 22 | ## [0.7.1](https://github.com/MarcScheib/aurelia-notify/compare/0.7.0...0.7.1) (2017-04-23) 23 | 24 | 25 | ### Bug Fixes 26 | 27 | * **controller:** fix creating multiple close promises ([60ef415](https://github.com/MarcScheib/aurelia-notify/commit/60ef415)) 28 | 29 | 30 | 31 | 32 | # [0.7.0](https://github.com/MarcScheib/aurelia-notify/compare/0.6.0...v0.7.0) (2016-10-09) 33 | 34 | 35 | ### Features 36 | 37 | * **service:** add support for additional model data ([7c054ce](https://github.com/MarcScheib/aurelia-notify/commit/7c054ce)) 38 | 39 | 40 | 41 | 42 | # [0.6.0](https://github.com/MarcScheib/aurelia-notify/compare/0.5.0...v0.6.0) (2016-07-28) 43 | 44 | 45 | 46 | 47 | 48 | # [0.5.0](https://github.com/MarcScheib/aurelia-notify/compare/0.4.0...v0.5.0) (2016-06-29) 49 | 50 | 51 | ### Bug Fixes 52 | 53 | * **renderer:** fix dom query selector call ([451d32d](https://github.com/MarcScheib/aurelia-notify/commit/451d32d)) 54 | * **sample:** add aurelia-pal ([30ee1ba](https://github.com/MarcScheib/aurelia-notify/commit/30ee1ba)) 55 | 56 | 57 | 58 | 59 | # [0.4.0](https://github.com/MarcScheib/aurelia-notify/compare/0.3.0...v0.4.0) (2016-05-29) 60 | 61 | 62 | ### Features 63 | 64 | * add transitions on show/hide notification ([97438d6](https://github.com/MarcScheib/aurelia-notify/commit/97438d6)) 65 | 66 | 67 | 68 | 69 | # [0.3.0](https://github.com/MarcScheib/aurelia-notify/compare/0.2.5...v0.3.0) (2016-05-19) 70 | 71 | 72 | ### Features 73 | 74 | * Added limit to number of notifications to be displayed at once. ([b74c8f7](https://github.com/MarcScheib/aurelia-notify/commit/b74c8f7)) 75 | 76 | 77 | 78 | 79 | ## [0.2.5](https://github.com/MarcScheib/aurelia-notify/compare/0.2.4...v0.2.5) (2016-05-19) 80 | 81 | 82 | 83 | 84 | 85 | ## [0.2.4](https://github.com/MarcScheib/aurelia-notify/compare/0.2.3...v0.2.4) (2016-05-09) 86 | 87 | 88 | 89 | 90 | 91 | ## [0.2.3](https://github.com/MarcScheib/aurelia-notify/compare/0.2.2...v0.2.3) (2016-05-09) 92 | 93 | 94 | ### Bug Fixes 95 | 96 | * **service:** make service method parameters optional ([c4d4dfc](https://github.com/MarcScheib/aurelia-notify/commit/c4d4dfc)) 97 | 98 | 99 | 100 | 101 | ## [0.2.2](https://github.com/MarcScheib/aurelia-notify/compare/0.2.1...v0.2.2) (2016-05-02) 102 | 103 | 104 | 105 | 106 | 107 | ## [0.2.1](https://github.com/MarcScheib/aurelia-notify/compare/0.2.0...v0.2.1) (2016-05-02) 108 | 109 | 110 | 111 | 112 | 113 | # [0.2.0](https://github.com/MarcScheib/aurelia-notify/compare/0.1.5...v0.2.0) (2016-03-28) 114 | 115 | ### Breaking Changes 116 | 117 | Rename the plugin from aurelia-notification to aurelia-notify. 118 | 119 | 120 | 121 | ## [0.1.5](https://github.com/MarcScheib/aurelia-notify/compare/0.1.4...0.1.5) (2016-03-28) 122 | 123 | 124 | 125 | 126 | 127 | ## [0.1.4](https://github.com/MarcScheib/aurelia-notify/compare/0.1.3...0.1.4) (2016-03-25) 128 | 129 | 130 | 131 | 132 | 133 | ## [0.1.3](https://github.com/MarcScheib/aurelia-notify/compare/0.1.2...0.1.3) (2016-03-23) 134 | 135 | 136 | 137 | 138 | 139 | ## [0.1.2](https://github.com/MarcScheib/aurelia-notify/compare/0.1.1...0.1.2) (2016-03-04) 140 | 141 | 142 | 143 | 144 | 145 | ## [0.1.1](https://github.com/MarcScheib/aurelia-notify/compare/0.1.0...0.1.1) (2016-02-26) 146 | 147 | 148 | ### Bug Fixes 149 | 150 | * Exposed the Notification controller so a custom viewModel can use the controller ([19fbed1](https://github.com/MarcScheib/aurelia-notify/commit/19fbed1)) 151 | 152 | 153 | 154 | 155 | # [0.1.0](https://github.com/MarcScheib/aurelia-notify/compare/0.0.2...0.1.0) (2016-02-22) 156 | 157 | 158 | ### Features 159 | 160 | * **ts:** add types to methods ([8c53b54](https://github.com/MarcScheib/aurelia-notify/commit/8c53b54)) 161 | 162 | 163 | 164 | 165 | ## [0.0.2](https://github.com/MarcScheib/aurelia-notify/compare/0.0.1...0.0.2) (2016-02-14) 166 | 167 | 168 | ### Features 169 | 170 | * **renderer:** allow to distingush inserting notifications before others or appending them ([69a516b](https://github.com/MarcScheib/aurelia-notify/commit/69a516b)) 171 | * **selector:** add dynamic container selection ([3a55eec](https://github.com/MarcScheib/aurelia-notify/commit/3a55eec)) 172 | 173 | 174 | 175 | 176 | ## [0.0.1](https://github.com/MarcScheib/aurelia-notify/compare/d9a5072...0.0.1) (2016-02-14) 177 | 178 | 179 | ### Bug Fixes 180 | 181 | * use info level as default if none is given ([cbd7ce3](https://github.com/MarcScheib/aurelia-notify/commit/cbd7ce3)) 182 | 183 | ### Features 184 | 185 | * add close functionality ([0fde99f](https://github.com/MarcScheib/aurelia-notify/commit/0fde99f)) 186 | * add helper methods for different notification levels ([ba5ece3](https://github.com/MarcScheib/aurelia-notify/commit/ba5ece3)) 187 | * add settings for timeout and notification host ([46ee934](https://github.com/MarcScheib/aurelia-notify/commit/46ee934)) 188 | * add timeout for removel of notification ([657e731](https://github.com/MarcScheib/aurelia-notify/commit/657e731)) 189 | * **sample:** add a sample sub project ([d9a5072](https://github.com/MarcScheib/aurelia-notify/commit/d9a5072)) 190 | * **sample:** add sample files ([b6a1c81](https://github.com/MarcScheib/aurelia-notify/commit/b6a1c81)) 191 | 192 | ### Performance Improvements 193 | 194 | * setup basic plugin ([0003b2d](https://github.com/MarcScheib/aurelia-notify/commit/0003b2d)) 195 | 196 | 197 | 198 | -------------------------------------------------------------------------------- /doc/Intro.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | ## Plugin Installation for Aurelia CLI 4 | 5 | For the plugin installation in a project created via Aurelia CLI, navigate to your project root and exute the following command: 6 | 7 | ``` 8 | npm install aurelia-notify --save 9 | ``` 10 | 11 | This will download the plugin and add it to your `package.json`. After that, open the `aurelia_project/aurelia.json` file and scroll down to the `build.bundles` section. Add the following to the `dependencies` section: 12 | 13 | ```json 14 | { 15 | "name": "aurelia-notify", 16 | "path": "../node_modules/aurelia-notify/dist/amd", 17 | "main": "aurelia-notify", 18 | "resources": [ 19 | "bs-notification.html", 20 | "style.css" 21 | ] 22 | } 23 | ``` 24 | 25 | ## Plugin Installation via JSPM 26 | 27 | For the plugin installation via JSPM, go to your project root and verify npm (```npm install```) and jspm (```jspm install```) installation was already executed. 28 | 29 | Now, you can install the notification plugin via the following command: 30 | 31 | ``` 32 | jspm install aurelia-notify 33 | ``` 34 | 35 | The command will add the plugin source code to your _jspm_packages_ directory as well as a mapping into your _config.js_ which looks similar to the following: 36 | 37 | ``` 38 | "aurelia-notify": "github:MarcScheib/aurelia-notify@x.y.z" 39 | ``` 40 | 41 | You can also add a specific branch to your application if you are looking for technical previews by executing the following command: 42 | 43 | ``` 44 | jspm install aurelia-notify=github:MarcScheib/aurelia-notify@master 45 | ``` 46 | 47 | This will add the current _master_ branch instead of the latest tagged version. 48 | 49 | ## Plugin Configuration in your Application 50 | 51 | During the bootstrapping of the Aurelia Framework, you can include the notification plugin by simply adding it to the list of loaded plugins: 52 | 53 | ```javascript 54 | export function configure(aurelia) { 55 | aurelia.use 56 | .standardConfiguration() 57 | .developmentLogging() 58 | ... 59 | .plugin('aurelia-notify'); // Add this line to load the plugin 60 | 61 | aurelia.start().then(a => a.setRoot('app', document.body)); 62 | } 63 | ``` 64 | 65 | # Getting started 66 | 67 | A simple introduction for the **aurelia-notify** plugin is shown by using the Aurelia demo application [skeleton-navigation](https://github.com/aurelia/skeleton-navigation). 68 | 69 | We start by setting up the project. Afterwards, we install and configure the plugin as shown in [Installation](https://github.com/MarcScheib/aurelia-notify/blob/master/doc/Intro.md#installation). 70 | 71 | 1. Clone the repository into your local project folder: 72 | 73 | ``` 74 | git clone https://github.com/aurelia/skeleton-navigation.git 75 | ``` 76 | 2. Switch into the _skeleton-navigation_ directory and choose one of your preferred starter kits. In this example, we choose the _skeleton-es2016_. Switch into that directory and install all _npm_ dependencies: 77 | 78 | ``` 79 | cd skeleton-navigation 80 | cd skeleton-es2016 81 | npm install 82 | ``` 83 | 3. In the same directory, install the _jspm_ dependencies: 84 | 85 | ``` 86 | jspm install 87 | ``` 88 | 4. Install the **aurelia-notify** dependency via _jspm_: 89 | 90 | ``` 91 | jspm install aurelia-notify 92 | ``` 93 | 94 | The project is now set up together with the notification plugin and we can start using it. Via executing ```gulp watch``` you can start a server running the application. 95 | It is then available via the shown URL on the command line (e.g. http://localhost:9000). 96 | 97 | The next step is to configure the _aurelia-notify_ plugin. In your favored IDE, open the file _skeleton-navigation/skeleton-es2016/src/main.js_ and adjust it as follows: 98 | 99 | ```javascript 100 | import 'bootstrap'; 101 | 102 | export function configure(aurelia) { 103 | aurelia.use 104 | .standardConfiguration() 105 | .developmentLogging() 106 | .plugin('aurelia-notify'); 107 | 108 | //Uncomment the line below to enable animation. 109 | //aurelia.use.plugin('aurelia-animator-css'); 110 | //if the css animator is enabled, add swap-order="after" to all router-view elements 111 | 112 | //Anyone wanting to use HTMLImports to load views, will need to install the following plugin. 113 | //aurelia.use.plugin('aurelia-html-import-template-loader') 114 | 115 | aurelia.start().then(() => aurelia.setRoot()); 116 | } 117 | 118 | ``` 119 | 120 | We simply added the ```.plugin('aurelia-notify')``` line. With this basic configuration, the plugin makes use of the available Bootstrap CSS styling. In case you want to use a different configuration, see the [Configuration](https://github.com/MarcScheib/aurelia-notify/blob/master/doc/Intro.md#configuration) section. 121 | 122 | We can start adding notifications to our application now. The plugin exposes a **NotificationService** which is used to display our notifications. 123 | Open the file _skeleton-navigation/skeleton-es2016/src/welcome.js_ and edit the file as follows: 124 | 125 | 1. We need to import the **NotificationService** from the plugin. On top of the file, add the following line: 126 | 127 | ```javascript 128 | import {NotificationService} from 'aurelia-notify'; 129 | ``` 130 | 2. Inject the service into the constructor of the view-model as shown in the following snippet: 131 | 132 | ```javascript 133 | static inject = [NotificationService]; 134 | constructor(notificationService){ 135 | this.notificationService = notificationService; 136 | } 137 | ``` 138 | 3. Now, we can add notifications, e.g. by showing an info notification instead of an alert box when submitting our name. Adjust the ```submit()``` method as follows: 139 | 140 | ```javascript 141 | submit() { 142 | this.previousValue = this.fullName; 143 | this.notificationService.info(`Welcome, ${this.fullName}!`); 144 | } 145 | ``` 146 | > **Note:** Make sure you use \` (backtick) instead of ' (apostrophe) for the ```info()``` method to use the ES2016 Template Literals and having the name replaced. 147 | 148 | The page should update automatically when adding those changes if you started the application via ```gulp watch```. If you press the _Submit_ button multiple times, you can see how the notifications pop up. As you can see, the display of the notifications is not optimal. 149 | 150 | By default, notifications are added to the `````` tag as the first child. We can change this, by configuring a different attachment point. Modify the service call in the ```submit()``` method as follows: 151 | 152 | ```javascript 153 | this.notificationService.info(`Welcome, ${this.fullName}!`, {containerSelector: '#page-host'}); 154 | ``` 155 | 156 | The notification is now displayed below the form and visible to the user directly. 157 | 158 | Beside the ```info()``` notification, there are three different methods available which in the base configuration make use of Bootstraps alert styles. Those are ```success()```, ```warning()```, and ```danger()```. 159 | 160 | For more information on the configuration, see the Section [Configuration](https://github.com/MarcScheib/aurelia-notify/blob/master/doc/Intro.md#configuration). API information will be available soon. 161 | 162 | # Configuration 163 | 164 | The plugin supports global configuration for all notifications as well as a specialized configuration for each single notification. 165 | 166 | ## Global Configuration 167 | 168 | The global configuration is handled together with the plugin registration during Aurelia's bootstrapping process. The following snippet shows, how configuration parameters are handed over to the plugin: 169 | 170 | ```javascript 171 | export function configure(aurelia) { 172 | aurelia.use 173 | .standardConfiguration() 174 | .developmentLogging() 175 | .plugin('aurelia-notify', settings => { 176 | settings.timeout = 10000; 177 | }); 178 | 179 | aurelia.start().then(a => a.setRoot('app', document.body)); 180 | } 181 | ``` 182 | 183 | For all available configuration parameters, see Section [Configuration Parameters](https://github.com/MarcScheib/aurelia-notify/blob/master/doc/Intro.md#configuration-parameters). 184 | 185 | ## Specialized Configuration 186 | 187 | Beside the global configuration, it is also possible to specify a different configuration for each notification itself. Simply add another parameter to the notification service call holding the configuration parameters. The following snippet shows an example: 188 | 189 | ```javascript 190 | this.notificationService.info('This notification lasts for 5s before it is closed automatically.', {timeout: 5000}); 191 | this.notificationService.danger('This notification lasts for 10s before it is closed automatically.', {timeout: 10000}); 192 | ``` 193 | 194 | For all available configuration parameters, see Section [Configuration Parameters](https://github.com/MarcScheib/aurelia-notify/blob/master/doc/Intro.md#configuration-parameters). 195 | 196 | ## Configuration Parameters 197 | 198 | The **aurelia-notify** plugin provides the following configuration parameters: 199 | - `append` 200 | - Specifies whether notifications should be appended to the notification container instead of inserted as the first element. 201 | - **Default**: false 202 | - `containerSelector` 203 | - Specifies to which DOM element the created notification will be attached to. The container selector is applied to DOM tree and the first element returned will be used. If no element is found, the default value is used. 204 | - **Default**: 'body' 205 | - `timeout` 206 | - Specifies the duration of the notification visibility. After the timeout, the notification is removed automatically if the user is not closing it. If zero is specified, the notification can only be cleared manually by the user. 207 | - **Default**: 0 208 | - `viewModel` 209 | - Specifies which view model is used for the notification. This allows to specify own customized elements and data. The default settings makes use of Bootstrap styles. 210 | - **Default**: BSNotification 211 | - `limit` 212 | - Specifies the amount of notifications that are shown at the same time. If additional notifications are added, the oldest ones are closed. 213 | - **Default**: 5 214 | 215 | # Customization 216 | 217 | The plugin allows several different customizations based on the [Configuration Parameters](https://github.com/MarcScheib/aurelia-notify/blob/master/doc/Intro.md#configuration-parameters). 218 | 219 | ## Customize service method calls 220 | 221 | At the moment, the notification plugin supports four built-in methods to show notifications: 222 | 223 | - ```info(message, settings)``` 224 | - ```success(message, settings)``` 225 | - ```warning(message, settings)``` 226 | - ```danger(message, settings)``` 227 | 228 | Each method takes a message parameter which is shown as the notification message and, optionally, a settings object base on above's configuration parameters. 229 | The methods internally call ```notify(model, settings, level)```, which can also be used to show notifications. It has a third parameter specifying the level or severity of the notification and, thus, the color of the notification box (when using the default). 230 | By default, the levels map to Bootstraps equivalents. The following code snippets show some examples: 231 | 232 | This snippet shows a success notification which hides automatically after 5 seconds. 233 | 234 | ```javascript 235 | this.notificationService.notify('A success message', {timeout: 5}, NotificationLevel.success); 236 | ``` 237 | 238 | ## Customize the notification element 239 | 240 | Instead of using the default Bootstrap notification view/view-model, it is also possible to use an own pair. 241 | 242 | First of all, it is necessary to specify a view file and a view-model, e.g. the following: 243 | 244 | The view may look like this: 245 | ```html 246 | 251 | ``` 252 | 253 | And the corresponding view-model: 254 | ```javascript 255 | export class SimpleNotification { 256 | activate(model) { 257 | this.notification = model.notification; 258 | } 259 | } 260 | ``` 261 | 262 | The next step is to configure the plugin to use this view/view-model (it is also possible to use it for one service call only by adjusting the settings of a service method). 263 | It may look like this: 264 | 265 | ```javascript 266 | import {SimpleNotification} from './simple-notification'; 267 | 268 | export function configure(aurelia) { 269 | aurelia.use 270 | .standardConfiguration() 271 | .developmentLogging() 272 | .plugin('aurelia-notify', settings => { 273 | settings.viewModel = SimpleNotification; 274 | }); 275 | 276 | aurelia.start().then(a => a.setRoot('app', document.body)); 277 | } 278 | ``` 279 | 280 | Now, the customized view/view-model is used instead of the default one. 281 | 282 | It is also possible to hand over additional data to the view model beside the notification message and the notification level. 283 | The ```notify(model, settings, level)``` method can take a complete data object as the first argument. It must at least contain a ```notification``` property, otherwise, an exception is thrown. 284 | The data is available in the view models ```activate()``` method via the ```data``` property of the activation parameter, e.g: 285 | 286 | ```javascript 287 | export class SimpleNotification { 288 | activate(model) { 289 | this.notification = model.notification; 290 | this.date = model.data.date; 291 | this.username = model.data.username; 292 | } 293 | } 294 | ``` 295 | 296 | And the corresponding service call: 297 | 298 | ```javascript 299 | this.notificationService.notify({notification: 'A success message', date: '2016/10/09', username: 'Marc'}, {timeout: 5}, NotificationLevel.success); 300 | ``` 301 | -------------------------------------------------------------------------------- /doc/api.json: -------------------------------------------------------------------------------- 1 | {"name":"aurelia-notify","children":[{"id":9,"name":"BSNotification","kind":128,"kindString":"Class","flags":{"isExported":true},"children":[{"id":11,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":12,"name":"new BSNotification","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":13,"name":"controller","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"NotificationController","id":2}}],"type":{"type":"reference","name":"BSNotification","id":9}}],"sources":[{"fileName":"aurelia-notify.d.ts","line":21,"character":21}]},{"id":10,"name":"inject","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-notify.d.ts","line":21,"character":15}],"type":{"type":"instrinct","name":"any"}},{"id":14,"name":"activate","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":15,"name":"activate","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":16,"name":"model","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"instrinct","name":"any"}}],"type":{"type":"instrinct","name":"any"}}],"sources":[{"fileName":"aurelia-notify.d.ts","line":23,"character":10}]}],"groups":[{"title":"Constructors","kind":512,"children":[11]},{"title":"Properties","kind":1024,"children":[10]},{"title":"Methods","kind":2048,"children":[14]}],"sources":[{"fileName":"aurelia-notify.d.ts","line":20,"character":35}]},{"id":2,"name":"NotificationController","kind":128,"kindString":"Class","flags":{"isExported":true},"children":[{"id":3,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":4,"name":"new NotificationController","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":5,"name":"renderer","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"NotificationRenderer","id":17}},{"id":6,"name":"settings","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"instrinct","name":"any"}}],"type":{"type":"reference","name":"NotificationController","id":2}}],"sources":[{"fileName":"aurelia-notify.d.ts","line":16,"character":45}]},{"id":7,"name":"close","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":8,"name":"close","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"instrinct","name":"any"}}],"sources":[{"fileName":"aurelia-notify.d.ts","line":18,"character":7}]}],"groups":[{"title":"Constructors","kind":512,"children":[3]},{"title":"Methods","kind":2048,"children":[7]}],"sources":[{"fileName":"aurelia-notify.d.ts","line":16,"character":43}]},{"id":17,"name":"NotificationRenderer","kind":128,"kindString":"Class","flags":{"isExported":true},"children":[{"id":19,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":20,"name":"new NotificationRenderer","kind":16384,"kindString":"Constructor signature","flags":{},"type":{"type":"reference","name":"NotificationRenderer","id":17}}],"sources":[{"fileName":"aurelia-notify.d.ts","line":27,"character":23}]},{"id":18,"name":"defaultSettings","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-notify.d.ts","line":27,"character":17}],"type":{"type":"instrinct","name":"any"}},{"id":21,"name":"createNotificationHost","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":22,"name":"createNotificationHost","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":23,"name":"notificationController","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"NotificationController","id":2}}],"type":{"type":"instrinct","name":"any"}}],"sources":[{"fileName":"aurelia-notify.d.ts","line":29,"character":24}]},{"id":30,"name":"destroyNotificationHost","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":31,"name":"destroyNotificationHost","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":32,"name":"notificationController","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"NotificationController","id":2}}],"type":{"type":"instrinct","name":"any"}}],"sources":[{"fileName":"aurelia-notify.d.ts","line":32,"character":25}]},{"id":33,"name":"getNotificationContainer","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":34,"name":"getNotificationContainer","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":35,"name":"containerSelector","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"instrinct","name":"string"}}],"type":{"type":"instrinct","name":"any"}}],"sources":[{"fileName":"aurelia-notify.d.ts","line":33,"character":26}]},{"id":27,"name":"hideNotification","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":28,"name":"hideNotification","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":29,"name":"notificationController","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"NotificationController","id":2}}],"type":{"type":"instrinct","name":"any"}}],"sources":[{"fileName":"aurelia-notify.d.ts","line":31,"character":18}]},{"id":24,"name":"showNotification","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":25,"name":"showNotification","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":26,"name":"notificationController","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"NotificationController","id":2}}],"type":{"type":"instrinct","name":"any"}}],"sources":[{"fileName":"aurelia-notify.d.ts","line":30,"character":18}]}],"groups":[{"title":"Constructors","kind":512,"children":[19]},{"title":"Properties","kind":1024,"children":[18]},{"title":"Methods","kind":2048,"children":[21,30,33,27,24]}],"sources":[{"fileName":"aurelia-notify.d.ts","line":26,"character":41}]},{"id":36,"name":"NotificationService","kind":128,"kindString":"Class","flags":{"isExported":true},"children":[{"id":41,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":42,"name":"new NotificationService","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":43,"name":"compositionEngine","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"CompositionEngine"}},{"id":44,"name":"container","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Container"}},{"id":45,"name":"notificationRenderer","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"NotificationRenderer","id":17}}],"type":{"type":"reference","name":"NotificationService","id":36}}],"sources":[{"fileName":"aurelia-notify.d.ts","line":39,"character":45}]},{"id":38,"name":"compositionEngine","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-notify.d.ts","line":37,"character":19}],"type":{"type":"reference","name":"CompositionEngine"}},{"id":39,"name":"container","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-notify.d.ts","line":38,"character":11}],"type":{"type":"reference","name":"Container"}},{"id":40,"name":"notificationRenderer","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-notify.d.ts","line":39,"character":22}],"type":{"type":"reference","name":"NotificationRenderer","id":17}},{"id":37,"name":"inject","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-notify.d.ts","line":36,"character":15}],"type":{"type":"instrinct","name":"any"}},{"id":63,"name":"danger","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":64,"name":"danger","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":65,"name":"message","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"instrinct","name":"string"}},{"id":66,"name":"settings","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"instrinct","name":"any"}}],"type":{"type":"instrinct","name":"any"}}],"sources":[{"fileName":"aurelia-notify.d.ts","line":45,"character":8}]},{"id":51,"name":"info","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":52,"name":"info","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":53,"name":"message","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"instrinct","name":"string"}},{"id":54,"name":"settings","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"instrinct","name":"any"}}],"type":{"type":"instrinct","name":"any"}}],"sources":[{"fileName":"aurelia-notify.d.ts","line":42,"character":6}]},{"id":46,"name":"notify","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":47,"name":"notify","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":48,"name":"model","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"instrinct","name":"any"}},{"id":49,"name":"settings","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"instrinct","name":"any"}},{"id":50,"name":"level","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"instrinct","name":"string"}}],"type":{"type":"instrinct","name":"any"}}],"sources":[{"fileName":"aurelia-notify.d.ts","line":41,"character":8}]},{"id":55,"name":"success","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":56,"name":"success","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":57,"name":"message","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"instrinct","name":"string"}},{"id":58,"name":"settings","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"instrinct","name":"any"}}],"type":{"type":"instrinct","name":"any"}}],"sources":[{"fileName":"aurelia-notify.d.ts","line":43,"character":9}]},{"id":59,"name":"warning","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":60,"name":"warning","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":61,"name":"message","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"instrinct","name":"string"}},{"id":62,"name":"settings","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"instrinct","name":"any"}}],"type":{"type":"instrinct","name":"any"}}],"sources":[{"fileName":"aurelia-notify.d.ts","line":44,"character":9}]}],"groups":[{"title":"Constructors","kind":512,"children":[41]},{"title":"Properties","kind":1024,"children":[38,39,40,37]},{"title":"Methods","kind":2048,"children":[63,51,46,55,59]}],"sources":[{"fileName":"aurelia-notify.d.ts","line":35,"character":40}]},{"id":67,"name":"NotificationLevel","kind":32,"kindString":"Variable","flags":{"isExported":true},"sources":[{"fileName":"aurelia-notify.d.ts","line":14,"character":36}],"type":{"type":"instrinct","name":"any"}},{"id":73,"name":"globalSettings","kind":32,"kindString":"Variable","flags":{"isExported":true},"sources":[{"fileName":"aurelia-notify.d.ts","line":25,"character":33}],"type":{"type":"instrinct","name":"any"}},{"id":68,"name":"invokeLifecycle","kind":64,"kindString":"Function","flags":{"isExported":true},"signatures":[{"id":69,"name":"invokeLifecycle","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":70,"name":"instance","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"instrinct","name":"any"}},{"id":71,"name":"name","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"instrinct","name":"string"}},{"id":72,"name":"model","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"instrinct","name":"any"}}],"type":{"type":"reference","name":"Promise","typeArguments":[{"type":"instrinct","name":"any"}]}}],"sources":[{"fileName":"aurelia-notify.d.ts","line":15,"character":39}]}],"groups":[{"title":"Classes","kind":128,"children":[9,2,17,36]},{"title":"Variables","kind":32,"children":[67,73]},{"title":"Functions","kind":64,"children":[68]}]} -------------------------------------------------------------------------------- /doc/core-js.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'core-js' { 2 | var coreJs; 3 | export default coreJs; 4 | } 5 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | require('require-dir')('build/tasks'); 2 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | let paths = require('./build/paths'); 2 | 3 | module.exports = function (config) { 4 | let configuration = { 5 | basePath: '', 6 | 7 | frameworks: ['jspm', 'jasmine'], 8 | 9 | jspm: { 10 | loadFiles: ['test/unit/setup.js', paths.tests], 11 | serveFiles: [paths.source] 12 | }, 13 | 14 | // list of files / patterns to load in the browser 15 | files: [], 16 | 17 | // list of files to exclude 18 | exclude: [], 19 | 20 | // preprocess matching files before serving them to the browser 21 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 22 | preprocessors: { 23 | [paths.tests]: ['babel'], 24 | [paths.source]: ['babel'] 25 | }, 26 | 27 | 'babelPreprocessor': { 28 | options: { 29 | sourceMap: 'inline', 30 | presets: [['es2015', {loose: true}], 'stage-1'], 31 | plugins: [ 32 | 'syntax-flow', 33 | 'transform-decorators-legacy', 34 | 'transform-flow-strip-types', 35 | 'istanbul' 36 | ] 37 | } 38 | }, 39 | 40 | reporters: ['progress'], 41 | 42 | port: 9876, 43 | 44 | colors: true, 45 | 46 | logLevel: config.LOG_INFO, 47 | 48 | autoWatch: true, 49 | 50 | customLaunchers: { 51 | Chrome_travis_ci: { 52 | base: 'Chrome', 53 | flags: ['--no-sandbox'] 54 | } 55 | }, 56 | 57 | browsers: ['Chrome'], 58 | 59 | singleRun: false 60 | }; 61 | 62 | if (process.env.TRAVIS) { 63 | configuration.browsers = ['Chrome_travis_ci']; 64 | } 65 | 66 | config.set(configuration); 67 | }; 68 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aurelia-notify", 3 | "version": "0.8.1", 4 | "description": "A notification plugin for Aurelia.", 5 | "keywords": [ 6 | "aurelia", 7 | "notify", 8 | "notifications", 9 | "plugin" 10 | ], 11 | "homepage": "http://aurelia.io", 12 | "bugs": { 13 | "url": "https://github.com/MarcScheib/aurelia-notify/issues" 14 | }, 15 | "license": "MIT", 16 | "author": "Marc Scheib ", 17 | "main": "dist/commonjs/aurelia-notify.js", 18 | "typings": "dist/aurelia-notify.d.ts", 19 | "repository": { 20 | "type": "git", 21 | "url": "https://github.com/MarcScheib/aurelia-notify" 22 | }, 23 | "jspm": { 24 | "registry": "npm", 25 | "main": "aurelia-notify", 26 | "format": "amd", 27 | "directories": { 28 | "lib": "dist/amd" 29 | }, 30 | "peerDependencies": { 31 | "aurelia-dependency-injection": "^1.3.1", 32 | "aurelia-metadata": "^1.0.3", 33 | "aurelia-pal": "^1.3.0", 34 | "aurelia-templating": "^1.4.2" 35 | }, 36 | "dependencies": { 37 | "aurelia-dependency-injection": "^1.3.1", 38 | "aurelia-metadata": "^1.0.3", 39 | "aurelia-pal": "^1.3.0", 40 | "aurelia-templating": "^1.4.2" 41 | }, 42 | "devDependencies": { 43 | "aurelia-pal-browser": "^1.2.1", 44 | "aurelia-polyfills": "^1.2.1", 45 | "babel": "babel-core@^5.8.38", 46 | "babel-runtime": "^5.8.38", 47 | "core-js": "^1.2.7" 48 | } 49 | }, 50 | "dependencies": { 51 | "aurelia-dependency-injection": "^1.3.1", 52 | "aurelia-metadata": "^1.0.3", 53 | "aurelia-pal": "^1.3.0", 54 | "aurelia-templating": "^1.4.2" 55 | }, 56 | "devDependencies": { 57 | "aurelia-tools": "^1.0.0", 58 | "babel-dts-generator": "^0.6.3", 59 | "babel-eslint": "^7.2.3", 60 | "babel-plugin-istanbul": "^4.1.4", 61 | "babel-plugin-syntax-flow": "^6.18.0", 62 | "babel-plugin-transform-decorators-legacy": "^1.3.4", 63 | "babel-plugin-transform-es2015-modules-amd": "^6.24.1", 64 | "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", 65 | "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", 66 | "babel-plugin-transform-flow-strip-types": "^6.22.0", 67 | "babel-preset-es2015": "^6.24.1", 68 | "babel-preset-stage-1": "^6.24.1", 69 | "browser-sync": "^2.18.12", 70 | "del": "^3.0.0", 71 | "event-stream": "^3.3.4", 72 | "gulp": "^3.9.1", 73 | "gulp-babel": "^6.1.2", 74 | "gulp-bump": "^2.7.0", 75 | "gulp-changed": "^3.1.0", 76 | "gulp-concat": "^2.6.1", 77 | "gulp-conventional-changelog": "^1.1.3", 78 | "gulp-coveralls": "0.1.4", 79 | "gulp-eslint": "^4.0.0", 80 | "gulp-ignore": "^2.0.2", 81 | "gulp-insert": "^0.5.0", 82 | "gulp-rename": "^1.2.2", 83 | "gulp-typedoc": "^2.0.2", 84 | "gulp-typedoc-extractor": "0.0.8", 85 | "gulp-typescript": "^3.2.0", 86 | "gulp-util": "^3.0.8", 87 | "jasmine-core": "^2.6.4", 88 | "jspm": "^0.16.53", 89 | "karma": "^1.7.0", 90 | "karma-babel-preprocessor": "^6.0.1", 91 | "karma-chrome-launcher": "^2.2.0", 92 | "karma-coverage": "^1.1.1", 93 | "karma-jasmine": "^1.1.0", 94 | "karma-jspm": "^2.2.3", 95 | "merge2": "^1.1.0", 96 | "object.assign": "^4.0.4", 97 | "require-dir": "^0.3.2", 98 | "run-sequence": "^2.0.0", 99 | "through2": "^2.0.3", 100 | "typedoc": "^0.7.1", 101 | "typescript": "^2.4.1", 102 | "vinyl": "^2.1.0", 103 | "vinyl-paths": "^2.1.0", 104 | "yargs": "^8.0.2" 105 | }, 106 | "aurelia": { 107 | "build": { 108 | "resources": [ 109 | "bs-notification", 110 | "bs-notification.html" 111 | ] 112 | }, 113 | "usedBy": [], 114 | "documentation": { 115 | "links": [ 116 | { 117 | "rel": "license", 118 | "mediaType": "text/plain", 119 | "title": "The MIT License (MIT)", 120 | "href": "LICENSE" 121 | }, 122 | { 123 | "rel": "describedby", 124 | "mediaType": "application/aurelia-doc+json", 125 | "title": "API", 126 | "href": "doc/api.json" 127 | }, 128 | { 129 | "rel": "version-history", 130 | "mediaType": "text/markdown", 131 | "title": "Change Log", 132 | "href": "doc/CHANGELOG.md" 133 | } 134 | ] 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /sample/config.js: -------------------------------------------------------------------------------- 1 | System.config({ 2 | defaultJSExtensions: true, 3 | transpiler: "babel", 4 | babelOptions: { 5 | "optional": [ 6 | "runtime", 7 | "optimisation.modules.system", 8 | "es7.decorators", 9 | "es7.classProperties" 10 | ] 11 | }, 12 | paths: { 13 | "github:*": "jspm_packages/github/*", 14 | "npm:*": "jspm_packages/npm/*" 15 | }, 16 | 17 | packages: { 18 | "/aurelia-notify": { 19 | "main": "index", 20 | "dependencies": { 21 | "aurelia-framework": "npm:aurelia-framework@1.1.2" 22 | } 23 | } 24 | }, 25 | 26 | map: { 27 | "aurelia-bootstrapper": "npm:aurelia-bootstrapper@2.1.1", 28 | "aurelia-dependency-injection": "npm:aurelia-dependency-injection@1.3.1", 29 | "aurelia-framework": "npm:aurelia-framework@1.1.2", 30 | "aurelia-metadata": "npm:aurelia-metadata@1.0.3", 31 | "aurelia-pal": "npm:aurelia-pal@1.3.0", 32 | "aurelia-pal-browser": "npm:aurelia-pal-browser@1.2.1", 33 | "aurelia-templating": "npm:aurelia-templating@1.4.2", 34 | "babel": "npm:babel-core@5.8.38", 35 | "babel-runtime": "npm:babel-runtime@5.8.38", 36 | "core-js": "npm:core-js@1.2.7", 37 | "font-awesome": "npm:font-awesome@4.7.0", 38 | "twbs/bootstrap": "github:twbs/bootstrap@3.3.6", 39 | "github:jspm/nodelibs-assert@0.1.0": { 40 | "assert": "npm:assert@1.4.1" 41 | }, 42 | "github:jspm/nodelibs-buffer@0.1.1": { 43 | "buffer": "npm:buffer@5.0.6" 44 | }, 45 | "github:jspm/nodelibs-path@0.1.0": { 46 | "path-browserify": "npm:path-browserify@0.0.0" 47 | }, 48 | "github:jspm/nodelibs-process@0.1.2": { 49 | "process": "npm:process@0.11.9" 50 | }, 51 | "github:jspm/nodelibs-util@0.1.0": { 52 | "util": "npm:util@0.10.3" 53 | }, 54 | "github:jspm/nodelibs-vm@0.1.0": { 55 | "vm-browserify": "npm:vm-browserify@0.0.4" 56 | }, 57 | "github:twbs/bootstrap@3.3.6": { 58 | "jquery": "npm:jquery@2.2.4" 59 | }, 60 | "npm:assert@1.4.1": { 61 | "assert": "github:jspm/nodelibs-assert@0.1.0", 62 | "buffer": "github:jspm/nodelibs-buffer@0.1.1", 63 | "process": "github:jspm/nodelibs-process@0.1.2", 64 | "util": "npm:util@0.10.3" 65 | }, 66 | "npm:aurelia-binding@1.2.1": { 67 | "aurelia-logging": "npm:aurelia-logging@1.3.1", 68 | "aurelia-metadata": "npm:aurelia-metadata@1.0.3", 69 | "aurelia-pal": "npm:aurelia-pal@1.3.0", 70 | "aurelia-task-queue": "npm:aurelia-task-queue@1.2.0" 71 | }, 72 | "npm:aurelia-bootstrapper@2.1.1": { 73 | "aurelia-event-aggregator": "npm:aurelia-event-aggregator@1.0.1", 74 | "aurelia-framework": "npm:aurelia-framework@1.1.2", 75 | "aurelia-history": "npm:aurelia-history@1.0.0", 76 | "aurelia-history-browser": "npm:aurelia-history-browser@1.0.0", 77 | "aurelia-loader-default": "npm:aurelia-loader-default@1.0.2", 78 | "aurelia-logging-console": "npm:aurelia-logging-console@1.0.0", 79 | "aurelia-pal": "npm:aurelia-pal@1.3.0", 80 | "aurelia-pal-browser": "npm:aurelia-pal-browser@1.2.1", 81 | "aurelia-polyfills": "npm:aurelia-polyfills@1.2.1", 82 | "aurelia-router": "npm:aurelia-router@1.3.0", 83 | "aurelia-templating": "npm:aurelia-templating@1.4.2", 84 | "aurelia-templating-binding": "npm:aurelia-templating-binding@1.3.0", 85 | "aurelia-templating-resources": "npm:aurelia-templating-resources@1.4.0", 86 | "aurelia-templating-router": "npm:aurelia-templating-router@1.1.0" 87 | }, 88 | "npm:aurelia-dependency-injection@1.3.1": { 89 | "aurelia-metadata": "npm:aurelia-metadata@1.0.3", 90 | "aurelia-pal": "npm:aurelia-pal@1.3.0" 91 | }, 92 | "npm:aurelia-event-aggregator@1.0.1": { 93 | "aurelia-logging": "npm:aurelia-logging@1.3.1" 94 | }, 95 | "npm:aurelia-framework@1.1.2": { 96 | "aurelia-binding": "npm:aurelia-binding@1.2.1", 97 | "aurelia-dependency-injection": "npm:aurelia-dependency-injection@1.3.1", 98 | "aurelia-loader": "npm:aurelia-loader@1.0.0", 99 | "aurelia-logging": "npm:aurelia-logging@1.3.1", 100 | "aurelia-metadata": "npm:aurelia-metadata@1.0.3", 101 | "aurelia-pal": "npm:aurelia-pal@1.3.0", 102 | "aurelia-path": "npm:aurelia-path@1.1.1", 103 | "aurelia-task-queue": "npm:aurelia-task-queue@1.2.0", 104 | "aurelia-templating": "npm:aurelia-templating@1.4.2" 105 | }, 106 | "npm:aurelia-history-browser@1.0.0": { 107 | "aurelia-history": "npm:aurelia-history@1.0.0", 108 | "aurelia-pal": "npm:aurelia-pal@1.3.0" 109 | }, 110 | "npm:aurelia-loader-default@1.0.2": { 111 | "aurelia-loader": "npm:aurelia-loader@1.0.0", 112 | "aurelia-metadata": "npm:aurelia-metadata@1.0.3", 113 | "aurelia-pal": "npm:aurelia-pal@1.3.0" 114 | }, 115 | "npm:aurelia-loader@1.0.0": { 116 | "aurelia-metadata": "npm:aurelia-metadata@1.0.3", 117 | "aurelia-path": "npm:aurelia-path@1.1.1" 118 | }, 119 | "npm:aurelia-logging-console@1.0.0": { 120 | "aurelia-logging": "npm:aurelia-logging@1.3.1" 121 | }, 122 | "npm:aurelia-metadata@1.0.3": { 123 | "aurelia-pal": "npm:aurelia-pal@1.3.0" 124 | }, 125 | "npm:aurelia-pal-browser@1.2.1": { 126 | "aurelia-pal": "npm:aurelia-pal@1.3.0" 127 | }, 128 | "npm:aurelia-polyfills@1.2.1": { 129 | "aurelia-pal": "npm:aurelia-pal@1.3.0" 130 | }, 131 | "npm:aurelia-route-recognizer@1.1.0": { 132 | "aurelia-path": "npm:aurelia-path@1.1.1" 133 | }, 134 | "npm:aurelia-router@1.3.0": { 135 | "aurelia-dependency-injection": "npm:aurelia-dependency-injection@1.3.1", 136 | "aurelia-event-aggregator": "npm:aurelia-event-aggregator@1.0.1", 137 | "aurelia-history": "npm:aurelia-history@1.0.0", 138 | "aurelia-logging": "npm:aurelia-logging@1.3.1", 139 | "aurelia-path": "npm:aurelia-path@1.1.1", 140 | "aurelia-route-recognizer": "npm:aurelia-route-recognizer@1.1.0" 141 | }, 142 | "npm:aurelia-task-queue@1.2.0": { 143 | "aurelia-pal": "npm:aurelia-pal@1.3.0" 144 | }, 145 | "npm:aurelia-templating-binding@1.3.0": { 146 | "aurelia-binding": "npm:aurelia-binding@1.2.1", 147 | "aurelia-logging": "npm:aurelia-logging@1.3.1", 148 | "aurelia-templating": "npm:aurelia-templating@1.4.2" 149 | }, 150 | "npm:aurelia-templating-resources@1.4.0": { 151 | "aurelia-binding": "npm:aurelia-binding@1.2.1", 152 | "aurelia-dependency-injection": "npm:aurelia-dependency-injection@1.3.1", 153 | "aurelia-loader": "npm:aurelia-loader@1.0.0", 154 | "aurelia-logging": "npm:aurelia-logging@1.3.1", 155 | "aurelia-metadata": "npm:aurelia-metadata@1.0.3", 156 | "aurelia-pal": "npm:aurelia-pal@1.3.0", 157 | "aurelia-path": "npm:aurelia-path@1.1.1", 158 | "aurelia-task-queue": "npm:aurelia-task-queue@1.2.0", 159 | "aurelia-templating": "npm:aurelia-templating@1.4.2" 160 | }, 161 | "npm:aurelia-templating-router@1.1.0": { 162 | "aurelia-binding": "npm:aurelia-binding@1.2.1", 163 | "aurelia-dependency-injection": "npm:aurelia-dependency-injection@1.3.1", 164 | "aurelia-logging": "npm:aurelia-logging@1.3.1", 165 | "aurelia-metadata": "npm:aurelia-metadata@1.0.3", 166 | "aurelia-pal": "npm:aurelia-pal@1.3.0", 167 | "aurelia-path": "npm:aurelia-path@1.1.1", 168 | "aurelia-router": "npm:aurelia-router@1.3.0", 169 | "aurelia-templating": "npm:aurelia-templating@1.4.2" 170 | }, 171 | "npm:aurelia-templating@1.4.2": { 172 | "aurelia-binding": "npm:aurelia-binding@1.2.1", 173 | "aurelia-dependency-injection": "npm:aurelia-dependency-injection@1.3.1", 174 | "aurelia-loader": "npm:aurelia-loader@1.0.0", 175 | "aurelia-logging": "npm:aurelia-logging@1.3.1", 176 | "aurelia-metadata": "npm:aurelia-metadata@1.0.3", 177 | "aurelia-pal": "npm:aurelia-pal@1.3.0", 178 | "aurelia-path": "npm:aurelia-path@1.1.1", 179 | "aurelia-task-queue": "npm:aurelia-task-queue@1.2.0" 180 | }, 181 | "npm:babel-runtime@5.8.38": { 182 | "process": "github:jspm/nodelibs-process@0.1.2" 183 | }, 184 | "npm:buffer@5.0.6": { 185 | "base64-js": "npm:base64-js@1.2.0", 186 | "ieee754": "npm:ieee754@1.1.8" 187 | }, 188 | "npm:core-js@1.2.7": { 189 | "fs": "github:jspm/nodelibs-fs@0.1.2", 190 | "path": "github:jspm/nodelibs-path@0.1.0", 191 | "process": "github:jspm/nodelibs-process@0.1.2", 192 | "systemjs-json": "github:systemjs/plugin-json@0.1.2" 193 | }, 194 | "npm:font-awesome@4.7.0": { 195 | "css": "github:systemjs/plugin-css@0.1.33" 196 | }, 197 | "npm:inherits@2.0.1": { 198 | "util": "github:jspm/nodelibs-util@0.1.0" 199 | }, 200 | "npm:path-browserify@0.0.0": { 201 | "process": "github:jspm/nodelibs-process@0.1.2" 202 | }, 203 | "npm:process@0.11.9": { 204 | "assert": "github:jspm/nodelibs-assert@0.1.0", 205 | "fs": "github:jspm/nodelibs-fs@0.1.2", 206 | "vm": "github:jspm/nodelibs-vm@0.1.0" 207 | }, 208 | "npm:util@0.10.3": { 209 | "inherits": "npm:inherits@2.0.1", 210 | "process": "github:jspm/nodelibs-process@0.1.2" 211 | }, 212 | "npm:vm-browserify@0.0.4": { 213 | "indexof": "npm:indexof@0.0.1" 214 | } 215 | } 216 | }); 217 | -------------------------------------------------------------------------------- /sample/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Aurelia Notify 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
Aurelia Notify Sample
14 | 15 |
16 | 17 | 18 | 19 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /sample/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "jspm": { 3 | "dependencies": { 4 | "aurelia-bootstrapper": "npm:aurelia-bootstrapper@^2.1.1", 5 | "aurelia-dependency-injection": "npm:aurelia-dependency-injection@^1.3.1", 6 | "aurelia-framework": "npm:aurelia-framework@^1.1.2", 7 | "aurelia-metadata": "npm:aurelia-metadata@^1.0.3", 8 | "aurelia-pal": "npm:aurelia-pal@^1.3.0", 9 | "aurelia-pal-browser": "npm:aurelia-pal-browser@^1.2.1", 10 | "aurelia-templating": "npm:aurelia-templating@^1.4.2", 11 | "font-awesome": "npm:font-awesome@^4.7.0", 12 | "twbs/bootstrap": "github:twbs/bootstrap@3.3.6" 13 | }, 14 | "devDependencies": { 15 | "babel": "npm:babel-core@^5.8.38", 16 | "babel-runtime": "npm:babel-runtime@^5.8.38", 17 | "core-js": "npm:core-js@^1.2.7" 18 | } 19 | }, 20 | "devDependencies": { 21 | "jspm": "^0.16.34" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /sample/src/app.html: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /sample/src/app.js: -------------------------------------------------------------------------------- 1 | import {inject} from 'aurelia-framework'; 2 | import {NotificationService, Notification} from 'aurelia-notify'; 3 | 4 | @inject(NotificationService) 5 | export class App { 6 | constructor(notificationService) { 7 | this.notificationService = notificationService; 8 | } 9 | 10 | info() { 11 | this.notificationService.info('Info Message'); 12 | } 13 | 14 | success() { 15 | this.notificationService.success('Success Message'); 16 | } 17 | 18 | warning() { 19 | this.notificationService.warning('Warning Message'); 20 | } 21 | 22 | danger() { 23 | this.notificationService.danger('Danger Message'); 24 | } 25 | 26 | custom() { 27 | this.notificationService.notify({notification: 'test'}, {}, 'info'); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /sample/src/main.js: -------------------------------------------------------------------------------- 1 | import 'github:twbs/bootstrap@3.3.6'; 2 | 3 | export function configure(aurelia) { 4 | aurelia.use 5 | .standardConfiguration() 6 | .developmentLogging() 7 | .plugin('aurelia-notify'); 8 | 9 | aurelia.start().then(a => a.setRoot('src/app')); 10 | } 11 | -------------------------------------------------------------------------------- /src/aurelia-notify.js: -------------------------------------------------------------------------------- 1 | import {PLATFORM} from 'aurelia-pal'; 2 | import {globalSettings} from './notification-renderer'; 3 | 4 | export function configure(config, callback) { 5 | config.globalResources( 6 | PLATFORM.moduleName('./bs-notification') 7 | ); 8 | 9 | if (typeof callback === 'function') { 10 | callback(globalSettings); 11 | } 12 | } 13 | 14 | export {BSNotification} from './bs-notification'; 15 | export {NotificationLevel} from './notification-level'; 16 | export {NotificationService} from './notification-service'; 17 | export {NotificationController} from './notification-controller'; 18 | -------------------------------------------------------------------------------- /src/bs-notification.html: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /src/bs-notification.js: -------------------------------------------------------------------------------- 1 | import {NotificationController} from './notification-controller'; 2 | 3 | export class BSNotification { 4 | static inject = [NotificationController]; 5 | 6 | constructor(controller: NotificationController) { 7 | this.controller = controller; 8 | } 9 | 10 | activate(model: any) { 11 | this.level = model.level; 12 | this.notification = model.notification; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/lifecycle.js: -------------------------------------------------------------------------------- 1 | export function invokeLifecycle(instance: any, name: string, model?: any): Promise { 2 | if (typeof instance[name] === 'function') { 3 | return new Promise(resolve => { 4 | resolve(instance[name](model)); 5 | }) 6 | .then(result => { 7 | if (result !== null && result !== undefined) { 8 | return result; 9 | } 10 | return true; 11 | }); 12 | } 13 | return Promise.resolve(true); 14 | } 15 | -------------------------------------------------------------------------------- /src/notification-controller.js: -------------------------------------------------------------------------------- 1 | import {invokeLifecycle} from './lifecycle'; 2 | 3 | export class NotificationController { 4 | constructor(renderer: NotificationRenderer, settings: any) { 5 | this.renderer = renderer; 6 | this.settings = settings; 7 | } 8 | 9 | close() { 10 | if (this.closePromise) { 11 | return this.closePromise; 12 | } 13 | clearTimeout(this.timer); 14 | return this.closePromise = invokeLifecycle(this.viewModel, 'canDeactivate') 15 | .then(canDeactivate => { 16 | if (canDeactivate) { 17 | return invokeLifecycle(this.viewModel, 'deactivate') 18 | .then(() => { 19 | return this.renderer.hideNotification(this); 20 | }) 21 | .then(() => { 22 | return this.renderer.destroyNotificationHost(this); 23 | }) 24 | .then(() => { 25 | this.controller.unbind(); 26 | }); 27 | } 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/notification-level.js: -------------------------------------------------------------------------------- 1 | export let NotificationLevel = { 2 | info: 'info', 3 | success: 'success', 4 | warning: 'warning', 5 | danger: 'danger' 6 | }; 7 | -------------------------------------------------------------------------------- /src/notification-renderer.js: -------------------------------------------------------------------------------- 1 | import {DOM} from 'aurelia-pal'; 2 | import {ViewSlot} from 'aurelia-templating'; 3 | 4 | import {BSNotification} from './bs-notification'; 5 | 6 | export let globalSettings = { 7 | append: false, 8 | containerSelector: 'body', 9 | timeout: 0, 10 | viewModel: BSNotification, 11 | limit: 5 12 | }; 13 | 14 | let transitionEvent = (function() { 15 | let transition = null; 16 | 17 | return function() { 18 | if (transition) return transition; 19 | 20 | let t; 21 | let el = DOM.createElement('fakeelement'); 22 | let transitions = { 23 | 'transition': 'transitionend', 24 | 'OTransition': 'oTransitionEnd', 25 | 'MozTransition': 'transitionend', 26 | 'WebkitTransition': 'webkitTransitionEnd' 27 | }; 28 | for (t in transitions) { 29 | if (el.style[t] !== undefined) { 30 | transition = transitions[t]; 31 | return transition; 32 | } 33 | } 34 | 35 | return undefined; 36 | }; 37 | }()); 38 | 39 | export class NotificationRenderer { 40 | defaultSettings = globalSettings; 41 | 42 | constructor() { 43 | this.notificationControllers = []; 44 | } 45 | 46 | createNotificationHost(notificationController: NotificationController) { 47 | let settings = notificationController.settings; 48 | let notificationHost = DOM.createElement('notification-host'); 49 | let notificationContainer = this.getNotificationContainer(settings.containerSelector); 50 | 51 | if (settings.append === true) { 52 | notificationContainer.appendChild(notificationHost); 53 | } else { 54 | notificationContainer.insertBefore(notificationHost, notificationContainer.firstChild); 55 | } 56 | 57 | notificationController.slot = new ViewSlot(notificationHost, true); 58 | notificationController.slot.add(notificationController.view); 59 | 60 | notificationController.showNotification = () => { 61 | this.notificationControllers.push(notificationController); 62 | 63 | if (this.notificationControllers.length >= (settings.limit + 1)) { 64 | this.notificationControllers[0].close(this.notificationControllers[0]); 65 | } 66 | 67 | notificationController.slot.attached(); 68 | 69 | if (settings.timeout > 0) { 70 | notificationController.timer = setTimeout(notificationController.close.bind(notificationController), settings.timeout); 71 | } 72 | 73 | return new Promise((resolve) => { 74 | function onTransitionEnd(e) { 75 | if (e.target !== notificationHost) { 76 | return; 77 | } 78 | notificationHost.removeEventListener(transitionEvent(), onTransitionEnd); 79 | resolve(); 80 | } 81 | 82 | notificationHost.addEventListener(transitionEvent(), onTransitionEnd); 83 | setTimeout(() => { 84 | notificationHost.classList.add('notification-host-active'); 85 | }, 0); 86 | }); 87 | }; 88 | 89 | notificationController.hideNotification = () => { 90 | let i = this.notificationControllers.indexOf(notificationController); 91 | if (i !== -1) { 92 | this.notificationControllers.splice(i, 1); 93 | } 94 | 95 | return new Promise((resolve) => { 96 | function onTransitionEnd() { 97 | notificationHost.removeEventListener(transitionEvent(), onTransitionEnd); 98 | resolve(); 99 | } 100 | 101 | notificationHost.addEventListener(transitionEvent(), onTransitionEnd); 102 | notificationHost.classList.remove('notification-host-active'); 103 | }); 104 | }; 105 | 106 | notificationController.destroyNotificationHost = () => { 107 | notificationContainer.removeChild(notificationHost); 108 | notificationController.slot.detached(); 109 | 110 | return Promise.resolve(); 111 | }; 112 | 113 | return Promise.resolve(); 114 | } 115 | 116 | showNotification(notificationController: NotificationController) { 117 | return notificationController.showNotification(); 118 | } 119 | 120 | hideNotification(notificationController: NotificationController) { 121 | return notificationController.hideNotification(); 122 | } 123 | 124 | destroyNotificationHost(notificationController: NotificationController) { 125 | return notificationController.destroyNotificationHost(); 126 | } 127 | 128 | getNotificationContainer(containerSelector: string) { 129 | let notificationContainer = DOM.querySelectorAll(containerSelector); 130 | if (notificationContainer === null) { 131 | notificationContainer = DOM.querySelectorAll('body'); 132 | } 133 | 134 | return notificationContainer[0]; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/notification-service.js: -------------------------------------------------------------------------------- 1 | import {Container} from 'aurelia-dependency-injection'; 2 | import {Origin} from 'aurelia-metadata'; 3 | import {CompositionEngine} from 'aurelia-templating'; 4 | 5 | import {invokeLifecycle} from './lifecycle'; 6 | import {NotificationController} from './notification-controller'; 7 | import {NotificationLevel} from './notification-level'; 8 | import {NotificationRenderer} from './notification-renderer'; 9 | 10 | export class NotificationService { 11 | static inject = [CompositionEngine, Container, NotificationRenderer]; 12 | 13 | compositionEngine: CompositionEngine; 14 | container: Container; 15 | notificationRenderer: NotificationRenderer; 16 | 17 | constructor(compositionEngine: CompositionEngine, container: Container, notificationRenderer: NotificationRenderer) { 18 | this.compositionEngine = compositionEngine; 19 | this.container = container; 20 | this.notificationRenderer = notificationRenderer; 21 | } 22 | 23 | notify(model: any, settings?: any, level?: string) { 24 | let _settings = Object.assign({}, this.notificationRenderer.defaultSettings, settings); 25 | let notificationController = new NotificationController(this.notificationRenderer, _createSettings(model, _settings, level)); 26 | let childContainer = this.container.createChild(); 27 | childContainer.registerInstance(NotificationController, notificationController); 28 | 29 | return _getViewModel(this.container, childContainer, this.compositionEngine, notificationController) 30 | .then(returnedCompositionContext => { 31 | notificationController.viewModel = returnedCompositionContext.viewModel; 32 | 33 | return invokeLifecycle(returnedCompositionContext.viewModel, 'canActivate', _settings.model) 34 | .then(canActivate => { 35 | if (canActivate) { 36 | this.compositionEngine.createController(returnedCompositionContext) 37 | .then(controller => { 38 | notificationController.controller = controller; 39 | notificationController.view = controller.view; 40 | controller.automate(); 41 | 42 | return this.notificationRenderer.createNotificationHost(notificationController); 43 | }) 44 | .then(() => { 45 | return this.notificationRenderer.showNotification(notificationController); 46 | }); 47 | } 48 | }); 49 | }); 50 | } 51 | 52 | info(message: string, settings?: any) { 53 | this.notify(message, settings, NotificationLevel.info); 54 | } 55 | 56 | success(message: string, settings?: any) { 57 | this.notify(message, settings, NotificationLevel.success); 58 | } 59 | 60 | warning(message: string, settings?: any) { 61 | this.notify(message, settings, NotificationLevel.warning); 62 | } 63 | 64 | danger(message: string, settings?: any) { 65 | this.notify(message, settings, NotificationLevel.danger); 66 | } 67 | } 68 | 69 | function _createSettings(model, settings, level) { 70 | let notification; 71 | if (typeof model === 'string') { 72 | notification = model; 73 | } else if (typeof model === 'object') { 74 | if (model.notification === undefined) { 75 | throw new Error('model must implement `notification` property.'); 76 | } 77 | notification = model.notification; 78 | } else { 79 | throw new Error('type is not supported by `notify()`.'); 80 | } 81 | 82 | settings.model = { 83 | notification: notification, 84 | data: model, 85 | level: level || NotificationLevel.info 86 | }; 87 | return settings; 88 | } 89 | 90 | function _getViewModel(container, childContainer, compositionEngine, notificationController) { 91 | let compositionContext = { 92 | container: container, 93 | childContainer: childContainer, 94 | model: notificationController.settings.model, 95 | viewModel: notificationController.settings.viewModel 96 | }; 97 | 98 | if (typeof compositionContext.viewModel === 'function') { 99 | compositionContext.viewModel = Origin.get(compositionContext.viewModel).moduleId; 100 | } 101 | 102 | if (typeof compositionContext.viewModel === 'string') { 103 | return compositionEngine.ensureViewModel(compositionContext); 104 | } 105 | 106 | return Promise.resolve(compositionContext); 107 | } 108 | -------------------------------------------------------------------------------- /src/style.css: -------------------------------------------------------------------------------- 1 | notification-host { 2 | display: block; 3 | transition: opacity .2s linear; 4 | opacity: 0; 5 | } 6 | 7 | .notification-host-active { 8 | opacity: 1; 9 | } 10 | -------------------------------------------------------------------------------- /test/unit/aurelia-notify.spec.js: -------------------------------------------------------------------------------- 1 | import {Container} from 'aurelia-dependency-injection'; 2 | import {configure} from '../../src/aurelia-notify'; 3 | 4 | describe('testing aurelia configure routine', () => { 5 | const frameworkConfig = { 6 | container: new Container(), 7 | globalResources() { 8 | }, 9 | transient() { 10 | } 11 | }; 12 | 13 | it('should export configure function', () => { 14 | expect(typeof configure).toBe('function'); 15 | }); 16 | 17 | it('should accept a setup callback passing back the callback', (done) => { 18 | let callback = (callback) => { 19 | expect(typeof callback).toBe('object'); 20 | done(); 21 | }; 22 | configure(frameworkConfig, callback); 23 | }); 24 | 25 | it('should accept no callback and not fail', () => { 26 | configure(frameworkConfig); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /test/unit/bs-notification.spec.js: -------------------------------------------------------------------------------- 1 | import {BSNotification} from '../../src/bs-notification'; 2 | import {NotificationController} from '../../src/notification-controller'; 3 | import {NotificationRenderer} from '../../src/notification-renderer'; 4 | 5 | describe('the BSNotification View Model', () => { 6 | let renderer; 7 | let controller; 8 | let sut; 9 | 10 | beforeEach(() => { 11 | renderer = new NotificationRenderer(); 12 | controller = new NotificationController(renderer, {}); 13 | sut = new BSNotification(controller); 14 | }); 15 | 16 | it('should hold the controller', () => { 17 | expect(sut.controller).toEqual(controller); 18 | }); 19 | 20 | it('should save the message and info on activation', () => { 21 | let model = { 22 | level: 'info', 23 | notification: 'message' 24 | }; 25 | sut.activate(model); 26 | expect(sut.level).toEqual(model.level); 27 | expect(sut.notification).toEqual(model.notification); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /test/unit/lifecycle.spec.js: -------------------------------------------------------------------------------- 1 | import {invokeLifecycle} from '../../src/lifecycle'; 2 | 3 | describe('invokeLifecycle', () => { 4 | const DEFAULT_LIFECYCLE_RESULT = true; 5 | const DEFAULT_INVOCATION_METHOD_NAME = 'canActivate'; 6 | const VM = { 7 | [DEFAULT_INVOCATION_METHOD_NAME]() { 8 | return this.output 9 | } 10 | }; 11 | 12 | function testResult(done, output, expected = DEFAULT_LIFECYCLE_RESULT, methodName = DEFAULT_INVOCATION_METHOD_NAME) { 13 | VM.output = output; 14 | invokeLifecycle(VM, methodName) 15 | .then(result => { 16 | expect(result).toBe(expected); 17 | done(); 18 | }); 19 | } 20 | 21 | function testRejection(done, expected) { 22 | invokeLifecycle(VM, DEFAULT_INVOCATION_METHOD_NAME) 23 | .then(() => { 24 | done.fail('Rejection expected'); 25 | }) 26 | .catch(error => { 27 | expect(error).toBe(expected); 28 | done(); 29 | }); 30 | } 31 | 32 | beforeEach(() => { 33 | delete VM.output; 34 | }); 35 | 36 | describe('should resolve with default value if the invoked method', () => { 37 | it('is not implemented', done => { 38 | testResult(done, undefined, DEFAULT_LIFECYCLE_RESULT, 'deactivate'); 39 | }); 40 | 41 | it('returns "undefined"', done => { 42 | testResult(done, undefined); 43 | }); 44 | 45 | it('returns "null"', done => { 46 | testResult(done, null); 47 | }); 48 | 49 | it('resolves to "undefined"', done => { 50 | testResult(done, Promise.resolve(undefined)); 51 | }); 52 | 53 | it('resolves to "null"', done => { 54 | testResult(done, Promise.resolve(null)); 55 | }); 56 | }); 57 | 58 | it('resolves with the returned value', done => { 59 | let expected = 'returned_value'; 60 | testResult(done, expected, expected); 61 | }); 62 | 63 | it('resolves with the resolved value', done => { 64 | let expected = 'resolved_value'; 65 | testResult(done, Promise.resolve(expected), expected); 66 | }); 67 | 68 | it('propagates errors when the invoked method throws', done => { 69 | let expectedError = new Error('sync_error'); 70 | spyOn(VM, DEFAULT_INVOCATION_METHOD_NAME).and.callFake(() => { throw expectedError; }); 71 | testRejection(done, expectedError); 72 | }); 73 | 74 | it('propagates errors when the invoked method is rejected', done => { 75 | let expectedError = new Error(); 76 | spyOn(VM, DEFAULT_INVOCATION_METHOD_NAME).and.returnValue(Promise.reject(expectedError)); 77 | testRejection(done, expectedError); 78 | }); 79 | 80 | it('invokes the method with the provided model', done => { 81 | let expectedModel = { test: 'test model' }; 82 | spyOn(VM, DEFAULT_INVOCATION_METHOD_NAME); 83 | invokeLifecycle(VM, DEFAULT_INVOCATION_METHOD_NAME, expectedModel) 84 | .then(result => { 85 | expect(result).toEqual(DEFAULT_LIFECYCLE_RESULT); 86 | done(); 87 | }) 88 | .catch(error => { 89 | done.fail(error); 90 | }); 91 | 92 | expect(VM[DEFAULT_INVOCATION_METHOD_NAME]).toHaveBeenCalledWith(expectedModel); 93 | }); 94 | }); 95 | -------------------------------------------------------------------------------- /test/unit/notification-controller.spec.js: -------------------------------------------------------------------------------- 1 | import {NotificationController} from '../../src/notification-controller'; 2 | 3 | describe('the Notification Controller', () => { 4 | let renderer; 5 | let settings; 6 | let sut; 7 | 8 | beforeEach(() => { 9 | settings = { name: 'Notification' }; 10 | sut = new NotificationController(renderer, settings); 11 | }); 12 | 13 | it('should be created with a settings property', () => { 14 | expect(sut.settings).toEqual(settings); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /test/unit/notification-level.spec.js: -------------------------------------------------------------------------------- 1 | import {NotificationLevel} from '../../src/notification-level'; 2 | 3 | describe('the notification levels', () => { 4 | it('should define info, success, warning, and danger levels', () => { 5 | expect(NotificationLevel.info).toEqual('info'); 6 | expect(NotificationLevel.success).toEqual('success'); 7 | expect(NotificationLevel.warning).toEqual('warning'); 8 | expect(NotificationLevel.danger).toEqual('danger'); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /test/unit/notification-renderer.spec.js: -------------------------------------------------------------------------------- 1 | import {NotificationController} from '../../src/notification-controller'; 2 | import {NotificationRenderer} from '../../src/notification-renderer'; 3 | import {BSNotification} from '../../src/bs-notification'; 4 | 5 | export let defaultSettings = { 6 | append: false, 7 | containerSelector: 'body', 8 | timeout: 0, 9 | viewModel: BSNotification, 10 | limit: 5 11 | }; 12 | 13 | describe('the Notification Renderer', () => { 14 | let sut; 15 | let controller; 16 | 17 | it('uses the default settings', done => { 18 | sut = new NotificationRenderer(); 19 | expect(sut.defaultSettings).toEqual(defaultSettings); 20 | done(); 21 | }); 22 | 23 | xit('calls the corresponding controller methods', done => { 24 | sut = new NotificationRenderer(); 25 | controller = new NotificationController(sut, defaultSettings); 26 | 27 | sut.createNotificationHost(controller); 28 | spyOn(controller, 'showNotification'); 29 | spyOn(controller, 'hideNotification'); 30 | spyOn(controller, 'destroyNotificationHost'); 31 | sut.showNotification(controller); 32 | expect(controller.showNotification).toHaveBeenCalled(); 33 | expect(controller.hideNotification).toHaveBeenCalled(); 34 | expect(controller.destroyNotificationHost).toHaveBeenCalled(); 35 | done(); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /test/unit/notification-service.spec.js: -------------------------------------------------------------------------------- 1 | import {NotificationService} from '../../src/notification-service'; 2 | import {NotificationRenderer} from '../../src/notification-renderer'; 3 | 4 | import {Container} from 'aurelia-dependency-injection'; 5 | import {CompositionEngine} from 'aurelia-templating'; 6 | 7 | describe('the Notification Service', () => { 8 | let compositionEngine; 9 | let container; 10 | let renderer; 11 | let sut; 12 | 13 | beforeEach(() => { 14 | compositionEngine = new CompositionEngine(); 15 | container = new Container(); 16 | renderer = new NotificationRenderer(); 17 | sut = new NotificationService(compositionEngine, container, renderer); 18 | }); 19 | 20 | it('should show a notification', () => { 21 | let result = sut.notify('Message'); 22 | result.then(result => { 23 | spyOn(result.renderer, 'createNotificationHost'); 24 | spyOn(result.renderer, 'showNotification'); 25 | expect(result.renderer.createNotificationHost).toHaveBeenCalled(); 26 | expect(result.renderer.showNotification).toHaveBeenCalled(); 27 | }); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /test/unit/setup.js: -------------------------------------------------------------------------------- 1 | import {initialize} from 'aurelia-pal-browser'; 2 | import 'aurelia-polyfills'; 3 | 4 | initialize(); 5 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2015", 4 | "module": "es2015", 5 | "experimentalDecorators": true, 6 | "emitDecoratorMetadata": false, 7 | "moduleResolution": "node", 8 | "stripInternal": true, 9 | "preserveConstEnums": true, 10 | "listFiles": true, 11 | "declaration": true, 12 | "removeComments": true, 13 | "lib": [ 14 | "es2015", 15 | "dom" 16 | ] 17 | }, 18 | "exclude": [ 19 | "node_modules", 20 | "dist", 21 | "build", 22 | "doc", 23 | "test", 24 | "config.js", 25 | "gulpfile.js", 26 | "karma.conf.js" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aurelia-notify", 3 | "main": "dist/aurelia-notify.d.ts", 4 | "dependencies": { 5 | "aurelia-dependency-injection": "github:aurelia/dependency-injection", 6 | "aurelia-metadata": "github:aurelia/metadata", 7 | "aurelia-pal": "github:aurelia/pal", 8 | "aurelia-templating": "github:aurelia/templating" 9 | } 10 | } 11 | --------------------------------------------------------------------------------