├── .editorconfig
├── .github
└── ISSUE_TEMPLATE.md
├── .gitignore
├── .travis.yml
├── .yo-rc.json
├── CHANGELOG.md
├── LICENSE
├── README.md
├── config
├── helpers.js
├── jestGlobalMocks.ts
└── setupJest.ts
├── demo
├── .editorconfig
├── .firebase
│ └── hosting.ZGlzdC9icm93c2Vy.cache
├── .firebaserc
├── .gitignore
├── README.md
├── angular.json
├── e2e
│ ├── protractor.conf.js
│ ├── src
│ │ ├── app.e2e-spec.ts
│ │ └── app.po.ts
│ └── tsconfig.e2e.json
├── firebase.json
├── package-lock.json
├── package.json
├── prerender.ts
├── proxy.conf.json
├── server.ts
├── src
│ ├── _variables.scss
│ ├── app
│ │ ├── app-routing.module.ts
│ │ ├── app.component.html
│ │ ├── app.component.scss
│ │ ├── app.component.spec.ts
│ │ ├── app.component.ts
│ │ ├── app.module.ts
│ │ ├── app.server.module.ts
│ │ ├── getting-started
│ │ │ ├── getting-started-routing.module.ts
│ │ │ ├── getting-started.component.html
│ │ │ ├── getting-started.component.scss
│ │ │ ├── getting-started.component.spec.ts
│ │ │ ├── getting-started.component.ts
│ │ │ └── getting-started.module.ts
│ │ ├── home
│ │ │ ├── home-routing.module.ts
│ │ │ ├── home.component.html
│ │ │ ├── home.component.scss
│ │ │ ├── home.component.spec.ts
│ │ │ ├── home.component.ts
│ │ │ └── home.module.ts
│ │ ├── material.module.ts
│ │ └── shared
│ │ │ ├── content-wrapper
│ │ │ ├── content-wrapper.component.html
│ │ │ ├── content-wrapper.component.scss
│ │ │ ├── content-wrapper.component.spec.ts
│ │ │ └── content-wrapper.component.ts
│ │ │ ├── footer
│ │ │ ├── footer.component.html
│ │ │ ├── footer.component.scss
│ │ │ ├── footer.component.spec.ts
│ │ │ └── footer.component.ts
│ │ │ ├── header
│ │ │ ├── header.component.html
│ │ │ ├── header.component.scss
│ │ │ ├── header.component.spec.ts
│ │ │ └── header.component.ts
│ │ │ ├── index.ts
│ │ │ └── shared.module.ts
│ ├── assets
│ │ ├── .gitkeep
│ │ ├── .npmignore
│ │ ├── forms.png
│ │ ├── forms.svg
│ │ └── logo.svg
│ ├── browserslist
│ ├── environments
│ │ ├── environment.hmr.ts
│ │ ├── environment.prod.ts
│ │ └── environment.ts
│ ├── favicon.ico
│ ├── highlight.js.scss
│ ├── hmr.ts
│ ├── index.html
│ ├── jestGlobalMocks.ts
│ ├── karma.conf.js
│ ├── main.server.ts
│ ├── main.ts
│ ├── polyfills.ts
│ ├── setupJest.ts
│ ├── styles.scss
│ ├── test.ts
│ ├── testing
│ │ ├── index.ts
│ │ └── router-stubs.ts
│ ├── tsconfig.app.json
│ ├── tsconfig.server.json
│ ├── tsconfig.spec.json
│ └── typings.d.ts
├── static.paths.ts
├── tsconfig.json
├── tslint.json
└── webpack.server.config.js
├── greenkeeper.json
├── gulpfile.js
├── karma.conf.js
├── package-lock.json
├── package.json
├── src
├── index.ts
├── module
│ ├── editor
│ │ ├── editor.component.html
│ │ ├── editor.component.scss
│ │ ├── editor.component.ts
│ │ └── toolbar
│ │ │ ├── toolbar.component.html
│ │ │ ├── toolbar.component.scss
│ │ │ └── toolbar.component.ts
│ ├── lib.interface.ts
│ ├── lib.module.ts
│ ├── material.module.ts
│ ├── service
│ │ ├── lib.service.spec.ts
│ │ └── lib.service.ts
│ └── utils
│ │ └── index.ts
├── tsconfig.lib.es5.json
├── tsconfig.lib.json
└── tsconfig.spec.json
├── tsconfig.json
├── tslint.json
└── webpack.config.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | max_line_length = 0
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
4 | ### Bug Report or Feature Request (mark with an `x`)
5 | ```
6 | - [ ] bug report -> please search issues before submitting
7 | - [ ] feature request
8 | ```
9 |
10 | ### OS and Version?
11 |
14 |
15 | ### Versions
16 |
20 |
21 |
22 | ### Repro steps
23 |
28 |
29 |
30 | ### The log given by the failure
31 |
32 |
33 |
34 | ### Desired functionality
35 |
39 |
40 |
41 | ### Mention any other details that might be useful
42 |
43 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 |
7 | # dependencies
8 | /node_modules
9 |
10 | # IDEs and editors
11 | /.idea
12 | .project
13 | .classpath
14 | .c9/
15 | *.launch
16 | .settings/
17 | *.sublime-workspace
18 |
19 | # IDE - VSCode
20 | .vscode/*
21 | !.vscode/settings.json
22 | !.vscode/tasks.json
23 | !.vscode/launch.json
24 | !.vscode/extensions.json
25 |
26 | # misc
27 | /.sass-cache
28 | /connect.lock
29 | /coverage
30 | /libpeerconnection.log
31 | npm-debug.log
32 | yarn-error.log
33 | testem.log
34 | /typings
35 | /config/gulp-tasks/README.md
36 |
37 | # e2e
38 | /e2e/*.js
39 | /e2e/*.map
40 |
41 | # System Files
42 | .DS_Store
43 | Thumbs.db
44 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: required
2 | dist: trusty
3 |
4 | #install google chrome, using addons
5 | addons:
6 | apt:
7 | sources:
8 | - google-chrome
9 | packages:
10 | - google-chrome-stable
11 |
12 | language: node_js
13 | node_js:
14 | - "8"
15 |
16 | before_script:
17 | - export DISPLAY=:99.0
18 | - sh -e /etc/init.d/xvfb start
19 | - npm install --quiet -g gulp-cli
20 |
21 | script: gulp test:ci
22 |
23 | after_success: gulp coveralls
24 |
25 | cache:
26 | yarn: true
27 |
--------------------------------------------------------------------------------
/.yo-rc.json:
--------------------------------------------------------------------------------
1 | {
2 | "generator-ngx-library": {
3 | "version": "6.2.1",
4 | "authorName": "Michael Doye",
5 | "authorEmail": "michaeldoye@gmail.com",
6 | "githubUsername": "michaeldoye",
7 | "githubRepoName": "mat-markdown-editor",
8 | "projectName": "mat-markdown-editor",
9 | "projectVersion": "0.0.1",
10 | "projectDescription": "Material design markdown editor",
11 | "projectKeywords": [
12 | "markdown",
13 | "text editor",
14 | "angular",
15 | "material design"
16 | ],
17 | "ngVersion": "6.0.0",\
18 | "ngModules": [
19 | "core",
20 | "common"
21 | ],
22 | "otherDependencies": [],
23 | "additionalPackageFiles": [],
24 | "dependenciesRange": "^",
25 | "ngPrefix": "ngx-mde",
26 | "testingFramework": "jest",
27 | "useGreenkeeper": true,
28 | "useCompodoc": true,
29 | "enforceNgGitCommitMsg": true,
30 | "exclusions": [
31 | "config/karma.conf.js",
32 | "config/webpack.test.js",
33 | "config/karma-test-shim.js"
34 | ],
35 | "deleteExclusions": []
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 | ## [0.0.8](https://github.com/michaeldoye/mat-markdown-editor/compare/v0.0.7...v0.0.8) (2019-03-27)
3 |
4 |
5 | ### Bug Fixes
6 |
7 | * **demo:** readme update ([b3a1c77](https://github.com/michaeldoye/mat-markdown-editor/commit/b3a1c77))
8 | * **demo:** readme update ([39b399e](https://github.com/michaeldoye/mat-markdown-editor/commit/39b399e))
9 | * **lib:** update travis ([8dfda7d](https://github.com/michaeldoye/mat-markdown-editor/commit/8dfda7d))
10 |
11 |
12 |
13 |
14 | ## [0.0.7](https://github.com/michaeldoye/mat-markdown-editor/compare/v0.0.6...v0.0.7) (2019-03-20)
15 |
16 |
17 |
18 |
19 | ## [0.0.6](https://github.com/michaeldoye/mat-markdown-editor/compare/v0.0.5...v0.0.6) (2019-03-20)
20 |
21 |
22 |
23 |
24 | ## [0.0.5](https://github.com/michaeldoye/mat-markdown-editor/compare/v0.0.4...v0.0.5) (2019-03-20)
25 |
26 |
27 |
28 |
29 | ## [0.0.4](https://github.com/michaeldoye/mat-markdown-editor/compare/v0.0.3...v0.0.4) (2019-03-20)
30 |
31 |
32 |
33 |
34 | ## [0.0.3](https://github.com/michaeldoye/mat-markdown-editor/compare/v0.0.2...v0.0.3) (2019-03-19)
35 |
36 |
37 |
38 |
39 | ## [0.0.2](https://github.com/michaeldoye/mat-markdown-editor/compare/aa4765c...v0.0.2) (2019-03-19)
40 |
41 |
42 | ### Bug Fixes
43 |
44 | * **demo:** add usage to readme ([f717d4e](https://github.com/michaeldoye/mat-markdown-editor/commit/f717d4e))
45 | * **demo:** fixed logo in readme ([5035304](https://github.com/michaeldoye/mat-markdown-editor/commit/5035304))
46 | * **demo:** readme update ([3ab2067](https://github.com/michaeldoye/mat-markdown-editor/commit/3ab2067))
47 | * **lib:** added svg logo ([7c7bb07](https://github.com/michaeldoye/mat-markdown-editor/commit/7c7bb07))
48 | * **lib:** greenkeeper ignore ([2eae841](https://github.com/michaeldoye/mat-markdown-editor/commit/2eae841))
49 | * **lib:** ts version ([09ae721](https://github.com/michaeldoye/mat-markdown-editor/commit/09ae721))
50 | * **lib:** updated logo ([cfbe38d](https://github.com/michaeldoye/mat-markdown-editor/commit/cfbe38d))
51 |
52 |
53 | ### Features
54 |
55 | * **lib:** initial commit ([aa4765c](https://github.com/michaeldoye/mat-markdown-editor/commit/aa4765c))
56 | * **lib:** pass all options via one object ([122d493](https://github.com/michaeldoye/mat-markdown-editor/commit/122d493))
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019 Michael Doye
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | "Software"), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be
14 | included in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | # Material Design Markdown Editor
6 |
7 | [](https://badge.fury.io/js/mat-markdown-editor)
8 | [](https://travis-ci.org/michaeldoye/mat-markdown-editor)
9 | [](https://coveralls.io/github/michaeldoye/mat-markdown-editor?branch=master)
10 | [](https://david-dm.org/michaeldoye/mat-markdown-editor)
11 | [](https://david-dm.org/michaeldoye/mat-markdown-editor#info=devDependencies)
12 | [](https://greenkeeper.io/)
13 |
14 | ## Demo
15 |
16 | View it in action at https://mat-markdown-editor.firebaseapp.com
17 |
18 | Edit on StackBlitz: https://stackblitz.com/edit/angular-w4tejv
19 |
20 | ## Dependencies
21 | * [Angular](https://angular.io) (*requires* Angular 2 or higher, tested with 2.0.0)
22 | * [Angular Material](https://material.angular.io/)
23 |
24 | ## Installation
25 | Install above dependencies via *npm*.
26 |
27 | Now install `mat-markdown-editor` via:
28 | ```shell
29 | npm install --save mat-markdown-editor
30 | ```
31 |
32 | Add the following to your `index.html` (or [configure](https://nitayneeman.com/posts/how-to-add-third-party-library-in-angular-cli/) via `angular-cli.json`)
33 | * [Marked JS](https://marked.js.org/#/README.md#README.md)
34 | * [Hightlight JS](https://highlightjs.org/)
35 | * [Ace Editor](https://ace.c9.io/)
36 |
37 | ```html
38 |
39 |
40 |
41 | ```
42 |
43 | ---
44 | ##### SystemJS
45 | >**Note**:If you are using `SystemJS`, you should adjust your configuration to point to the UMD bundle.
46 | In your systemjs config file, `map` needs to tell the System loader where to look for `mat-markdown-editor`:
47 | ```js
48 | map: {
49 | 'mat-markdown-editor': 'node_modules/mat-markdown-editor/bundles/mat-markdown-editor.umd.js',
50 | }
51 | ```
52 | ---
53 |
54 | Once installed you need to import the main module:
55 | ```js
56 | import { MatMarkdownEditorModule } from 'mat-markdown-editor';
57 | ```
58 | The only remaining part is to list the imported module in your application module. The exact method will be slightly
59 | different for the root (top-level) module for which you should end up with the code similar to (notice ` MatMarkdownEditorModule.forRoot()`):
60 | ```js
61 | import { MatMarkdownEditorModule } from 'mat-markdown-editor';
62 |
63 | @NgModule({
64 | declarations: [AppComponent, ...],
65 | imports: [MatMarkdownEditorModule.forRoot(), ...],
66 | bootstrap: [AppComponent]
67 | })
68 | export class AppModule {
69 | }
70 | ```
71 |
72 | Other modules in your application can simply import ` MatMarkdownEditorModule `:
73 |
74 | ```js
75 | import { MatMarkdownEditorModule } from 'mat-markdown-editor';
76 |
77 | @NgModule({
78 | declarations: [OtherComponent, ...],
79 | imports: [MatMarkdownEditorModule, ...],
80 | })
81 | export class OtherModule {
82 | }
83 | ```
84 |
85 | ## Usage
86 |
87 | ```js
88 | import { Component } from '@angular/core';
89 | import { MatMarkdownEditorOptions } from 'mat-markdown-editor';
90 |
91 | @Component({
92 | selector: 'app-home',
93 | template: `
94 |
103 | `,
104 | })
105 | export class HomeComponent {
106 | public options: MatMarkdownEditorOptions = {
107 | enablePreviewContentClick: false,
108 | resizable: true,
109 | showBorder: true,
110 | hideIcons: {},
111 | hideToolbar: false,
112 | height: '500px',
113 | mode: 'editor',
114 | toolbarColor: 'primary',
115 | preRender: this.preRender,
116 | };
117 |
118 | preRender(markDown: any) {
119 | // Here you have access to the markdown binding
120 | // before it is rendered
121 | return markDown;
122 | }
123 | }
124 | ```
125 | All options can be found [here](https://github.com/michaeldoye/mat-markdown-editor/blob/master/src/module/lib.interface.ts)
126 |
127 |
128 |
129 | ## Run Demo App Locally
130 |
131 | - [clone this repo](https://github.com/michaeldoye/mat-markdown-editor.git) by running
132 | ```bash
133 | $ git clone https://github.com/michaeldoye/mat-markdown-editor.git
134 | ```
135 |
136 | - link the **mat-markdown-editor** package
137 |
138 | ```bash
139 | $ gulp link
140 | ```
141 |
142 | - navigate to the demo app directory
143 | ```bash
144 | $ cd demo
145 | ```
146 |
147 | - install the dependencies
148 | ```bash
149 | $ npm i
150 | ```
151 |
152 | - run/start/serve the app
153 | ```bash
154 | $ npm run start
155 | ```
156 | or
157 | ```bash
158 | $ ng serve --open
159 | ```
160 | - the app is now hosted by `http://localhost:4200/`
161 |
162 |
163 |
164 |
165 | ## Development
166 |
167 | 1. clone this [repo](https://github.com/michaeldoye/mat-markdown-editor.git)
168 | 2. Install the dependencies by running `npm i`
169 | 3. build the library `npm run build` or `gulp build`
170 | 4. Link the library `gulp link`
171 | 5. Navigate to the demo app's directory
172 | - `cd demo`
173 | _ `npm i`
174 | _ `npm start`
175 |
176 | ## License
177 |
178 | Copyright (c) 2019 Michael Doye. Licensed under the MIT License (MIT)
179 |
180 |
--------------------------------------------------------------------------------
/config/helpers.js:
--------------------------------------------------------------------------------
1 | const os = require('os');
2 | const path = require('path');
3 | const exec = require('child_process').exec;
4 |
5 | const _root = path.resolve(__dirname, '..');
6 |
7 |
8 | /**
9 | * Plaform independant path to an executable cmd
10 | * @param {string} path
11 | */
12 | platformPath = (path) => {
13 | return /^win/.test(os.platform()) ? `${path}.cmd` : path;
14 | };
15 |
16 | /**
17 | *
18 | * @param {string[]} args
19 | */
20 | rootDir = (...args) => {
21 | return path.join.apply(path, [_root].concat(...args));
22 | };
23 |
24 | /**
25 | *
26 | * @param {string} cmd
27 | */
28 | binPath = (cmd) => {
29 | return platformPath(`/node_modules/.bin/${cmd}`);
30 | };
31 |
32 | /**
33 | * Promisified child_process.exec
34 | *
35 | * @param cmd
36 | * @param opts See child_process.exec node docs
37 | * @returns {Promise}
38 | */
39 | execp = (cmd, opts) => {
40 | opts = Object.assign(opts || {}, {
41 | stdout: process.stdout,
42 | stderr: process.stderr
43 | });
44 | return new Promise((resolve, reject) => {
45 | const child = exec(cmd, opts,
46 | (err, stdout, stderr) => err ? reject(err.code) : resolve(0));
47 |
48 | if (opts.stdout) {
49 | child.stdout.pipe(opts.stdout);
50 | }
51 | if (opts.stderr) {
52 | child.stderr.pipe(opts.stderr);
53 | }
54 | });
55 | };
56 |
57 | /**
58 | * Install dependencies using yarn, if present, or npm otherwise.
59 | * @param opts See child_process.exec node docs
60 | * @returns {Promise}
61 | */
62 | installDependencies = (opts) => {
63 | return execp('yarn -v') // first try to install deps using yarn
64 | .then(exitCode => exitCode === 0 ? execp('yarn install', opts) : execp('npm install', opts));
65 | };
66 |
67 | var exports = module.exports = {
68 | root: rootDir,
69 | execp: execp,
70 | binPath: binPath,
71 | platformPath: platformPath,
72 | installDependencies: installDependencies
73 | };
74 |
--------------------------------------------------------------------------------
/config/jestGlobalMocks.ts:
--------------------------------------------------------------------------------
1 | global['CSS'] = null;
2 |
3 | const mock = () => {
4 | let storage = {};
5 | return {
6 | getItem: (key: string) => key in storage ? storage[key] : null,
7 | setItem: (key: string | number, value: string) => storage[key] = value || '',
8 | removeItem: (key: string | number) => delete storage[key],
9 | clear: () => storage = {},
10 | };
11 | };
12 |
13 | Object.defineProperty(window, 'localStorage', {value: mock()});
14 | Object.defineProperty(window, 'sessionStorage', {value: mock()});
15 | Object.defineProperty(document, 'doctype', {
16 | value: ''
17 | });
18 | Object.defineProperty(window, 'getComputedStyle', {
19 | value: () => {
20 | return {
21 | display: 'none',
22 | appearance: ['-webkit-appearance']
23 | };
24 | }
25 | });
26 | /**
27 | * ISSUE: https://github.com/angular/material2/issues/7101
28 | * Workaround for JSDOM missing transform property
29 | */
30 | Object.defineProperty(document.body.style, 'transform', {
31 | value: () => {
32 | return {
33 | enumerable: true,
34 | configurable: true,
35 | };
36 | },
37 | });
38 |
--------------------------------------------------------------------------------
/config/setupJest.ts:
--------------------------------------------------------------------------------
1 | import 'jest-preset-angular';
2 | import './jestGlobalMocks';
3 |
--------------------------------------------------------------------------------
/demo/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | max_line_length = off
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/demo/.firebase/hosting.ZGlzdC9icm93c2Vy.cache:
--------------------------------------------------------------------------------
1 | 4.8c8d0bb3ab912bd7f8bf.js,1553072127206,315863f1ac769487b9b217511c532a3cec7188b436fff2bbec8309a62edd6d82
2 | favicon.ico,1553072127206,3c8f1dca744007357393e9228949f1d36e0865c21c06cb504be0fa21e397df5f
3 | index.html,1553072127207,6961b7a9d946e868f63ec6d2ea65f563f0ae864a4d34f80f2b50c144c95dfb0a
4 | 3rdpartylicenses.txt,1553072127205,031ee3198184597544d063de32568ea37ac7ea04cb9ece0b062cc31c3f3a0a60
5 | runtime.ff57a64bedad5d60e350.js,1553072127206,786cbf52c8342046f1f9a399730ddaa838fdc594c5046c5ac55f5c7d747d6d22
6 | assets/forms.png,1553072127207,361a875eecaab41bb23b427add7fa92300392acfafc20fe8e5db460c259f2632
7 | assets/forms.svg,1553072127207,80c218a9ad36f618eb0c2b10c385c79f3833d8dcd17096195da40937e9ff7066
8 | assets/logo.svg,1553072127207,04e531ef510c0566b0b3a7895158bad2bba2da4fff93a1d25899073f88cdd82f
9 | polyfills.a9824751764fbcd6131c.js,1553072127206,827452fcaf4948f7e6df0a8551e61fb7ab5d60a0a4633893ee9733d1b288882b
10 | fontawesome-webfont.af7ae505a9eed503f8b8.woff2,1553072127206,156e171dae6239bcd8304d42163d8b1e6bfd029759d46be88a4e446a51249ba2
11 | fontawesome-webfont.fee66e712a8a08eef580.woff,1553072127205,9cb84ef5f51a04cf0dd3a9aec98c43ad4d44df442b7454c6b448913e36fb0c43
12 | fontawesome-webfont.674f50d287a8c48dc19b.eot,1553072127206,9acdf34fe486fad3cfa8ef4aa925ebbe9e955c8a8d127bff4d427620b0eeb643
13 | fontawesome-webfont.b06871f281fee6b241d6.ttf,1553072127206,225dc03087123b26cb71296d418705ec2e89e826acd04bfe6fc6353a0f5220c8
14 | styles.bdaf6eb4c09997661380.css,1553072127206,79cde03b7ffea9a69654880b2774aef8724c85c42255c0dcbdd63da82e393493
15 | main.415e51ee6651ef6c11ce.js,1553072127206,b4c54f182fe9e17709b7bcbf0e751bcc081ffb4e59521bd13863d9d2937be849
16 | fontawesome-webfont.912ec66d7572ff821749.svg,1553072127206,303fc405939cc4d296906102b8047b71a4ec14a7b51aa7a2abfaad416ec8fb3c
17 |
--------------------------------------------------------------------------------
/demo/.firebaserc:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/demo/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 | /out-tsc
7 |
8 | # dependencies
9 | /node_modules
10 |
11 | # IDEs and editors
12 | /.idea
13 | .project
14 | .classpath
15 | .c9/
16 | *.launch
17 | .settings/
18 | *.sublime-workspace
19 |
20 | # IDE - VSCode
21 | .vscode/*
22 | !.vscode/settings.json
23 | !.vscode/tasks.json
24 | !.vscode/launch.json
25 | !.vscode/extensions.json
26 |
27 | # misc
28 | /.sass-cache
29 | /connect.lock
30 | /coverage
31 | /libpeerconnection.log
32 | npm-debug.log
33 | yarn-error.log
34 | testem.log
35 | /typings
36 |
37 | # System Files
38 | .DS_Store
39 | Thumbs.db
40 |
--------------------------------------------------------------------------------
/demo/README.md:
--------------------------------------------------------------------------------
1 | # mat-markdown-editor-demo
2 |
3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 6.0.0.
4 |
5 | ## Development server
6 |
7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
8 |
9 | ## Code scaffolding
10 |
11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
12 |
13 | ## Build
14 |
15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
16 |
17 | ## Running unit tests
18 |
19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
20 |
21 | ## Running end-to-end tests
22 |
23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
24 |
25 | ## Further help
26 |
27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
28 |
--------------------------------------------------------------------------------
/demo/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "version": 1,
4 | "newProjectRoot": "projects",
5 | "projects": {
6 | "mat-markdown-editor-demo": {
7 | "root": "",
8 | "sourceRoot": "src",
9 | "projectType": "application",
10 | "prefix": "app",
11 | "schematics": {},
12 | "architect": {
13 | "build": {
14 | "builder": "@angular-devkit/build-angular:browser",
15 | "options": {
16 | "outputPath": "dist/browser",
17 | "index": "src/index.html",
18 | "main": "src/main.ts",
19 | "polyfills": "src/polyfills.ts",
20 | "tsConfig": "src/tsconfig.app.json",
21 | "assets": [
22 | "src/favicon.ico",
23 | "src/assets"
24 | ],
25 | "styles": [
26 | "src/styles.scss"
27 | ],
28 | "scripts": []
29 | },
30 | "configurations": {
31 | "production": {
32 | "fileReplacements": [
33 | {
34 | "replace": "src/environments/environment.ts",
35 | "with": "src/environments/environment.prod.ts"
36 | }
37 | ],
38 | "optimization": true,
39 | "outputHashing": "all",
40 | "sourceMap": false,
41 | "extractCss": true,
42 | "namedChunks": false,
43 | "aot": true,
44 | "extractLicenses": true,
45 | "vendorChunk": false,
46 | "buildOptimizer": true
47 | },
48 | "hmr": {
49 | "fileReplacements": [
50 | {
51 | "replace": "src/environments/environment.ts",
52 | "with": "src/environments/environment.hmr.ts"
53 | }
54 | ]
55 | }
56 | }
57 | },
58 | "serve": {
59 | "builder": "@angular-devkit/build-angular:dev-server",
60 | "options": {
61 | "browserTarget": "mat-markdown-editor-demo:build",
62 | "hmrWarning": false
63 | },
64 | "configurations": {
65 | "production": {
66 | "browserTarget": "mat-markdown-editor-demo:build:production"
67 | },
68 | "hmr": {
69 | "hmr": true,
70 | "browserTarget": "mat-markdown-editor-demo:build:hmr"
71 | }
72 | }
73 | },
74 | "extract-i18n": {
75 | "builder": "@angular-devkit/build-angular:extract-i18n",
76 | "options": {
77 | "browserTarget": "mat-markdown-editor-demo:build"
78 | }
79 | },
80 | "test": {
81 | "builder": "@angular-devkit/build-angular:karma",
82 | "options": {
83 | "main": "src/test.ts",
84 | "polyfills": "src/polyfills.ts",
85 | "tsConfig": "src/tsconfig.spec.json",
86 | "karmaConfig": "src/karma.conf.js",
87 | "styles": [
88 | "styles.scss"
89 | ],
90 | "scripts": [],
91 | "assets": [
92 | "src/favicon.ico",
93 | "src/assets"
94 | ]
95 | }
96 | },
97 | "lint": {
98 | "builder": "@angular-devkit/build-angular:tslint",
99 | "options": {
100 | "tsConfig": [
101 | "src/tsconfig.app.json",
102 | "src/tsconfig.spec.json"
103 | ],
104 | "exclude": [
105 | "**/node_modules/**"
106 | ]
107 | }
108 | },
109 | "server": {
110 | "builder": "@angular-devkit/build-angular:server",
111 | "options": {
112 | "outputPath": "dist/server",
113 | "main": "src/main.server.ts",
114 | "tsConfig": "src/tsconfig.server.json"
115 | }
116 | }
117 | }
118 | },
119 | "mat-markdown-editor-demo-e2e": {
120 | "root": "e2e/",
121 | "projectType": "application",
122 | "architect": {
123 | "e2e": {
124 | "builder": "@angular-devkit/build-angular:protractor",
125 | "options": {
126 | "protractorConfig": "e2e/protractor.conf.js",
127 | "devServerTarget": "mat-markdown-editor-demo:serve"
128 | }
129 | },
130 | "lint": {
131 | "builder": "@angular-devkit/build-angular:tslint",
132 | "options": {
133 | "tsConfig": "e2e/tsconfig.e2e.json",
134 | "exclude": [
135 | "**/node_modules/**"
136 | ]
137 | }
138 | }
139 | }
140 | }
141 | },
142 | "defaultProject": "mat-markdown-editor-demo"
143 | }
--------------------------------------------------------------------------------
/demo/e2e/protractor.conf.js:
--------------------------------------------------------------------------------
1 | // Protractor configuration file, see link for more information
2 | // https://github.com/angular/protractor/blob/master/lib/config.ts
3 |
4 | const { SpecReporter } = require('jasmine-spec-reporter');
5 |
6 | exports.config = {
7 | allScriptsTimeout: 11000,
8 | specs: [
9 | './src/**/*.e2e-spec.ts'
10 | ],
11 | capabilities: {
12 | 'browserName': 'chrome'
13 | },
14 | directConnect: true,
15 | baseUrl: 'http://localhost:4200/',
16 | framework: 'jasmine',
17 | jasmineNodeOpts: {
18 | showColors: true,
19 | defaultTimeoutInterval: 30000,
20 | print: function() {}
21 | },
22 | onPrepare() {
23 | require('ts-node').register({
24 | project: require('path').join(__dirname, './tsconfig.e2e.json')
25 | });
26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
27 | }
28 | };
--------------------------------------------------------------------------------
/demo/e2e/src/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { NgxMarkdownEditorDemoPage } from './app.po';
2 |
3 | describe('mat-markdown-editor-demo App', () => {
4 | let page: NgxMarkdownEditorDemoPage;
5 |
6 | beforeEach(() => {
7 | page = new NgxMarkdownEditorDemoPage ();
8 | });
9 |
10 | it('should display message saying app works', () => {
11 | page.navigateTo();
12 | expect(page.getParagraphText()).toEqual('app works!');
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/demo/e2e/src/app.po.ts:
--------------------------------------------------------------------------------
1 | import { browser, element, by } from 'protractor';
2 |
3 | export class NgxMarkdownEditorDemoPage {
4 | navigateTo() {
5 | return browser.get('/');
6 | }
7 |
8 | getParagraphText() {
9 | return element(by.css('app-root h1')).getText();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/demo/e2e/tsconfig.e2e.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/app",
5 | "module": "commonjs",
6 | "target": "es5",
7 | "types": [
8 | "jasmine",
9 | "jasminewd2",
10 | "node"
11 | ]
12 | }
13 | }
--------------------------------------------------------------------------------
/demo/firebase.json:
--------------------------------------------------------------------------------
1 | {
2 | "hosting": {
3 | "public": "dist/browser",
4 | "ignore": [
5 | "firebase.json",
6 | "**/.*",
7 | "**/node_modules/**"
8 | ]
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/demo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mat-markdown-editor-demo",
3 | "version": "0.0.0",
4 | "license": "MIT",
5 | "description": "Demo app for mat-markdown-editor",
6 | "scripts": {
7 | "ng": "ng",
8 | "start": "ng serve",
9 | "build": "ng build",
10 | "test": "jest",
11 | "lint": "ng lint",
12 | "e2e": "ng e2e",
13 | "postinstall": "npm link mat-markdown-editor",
14 | "builddemo": "gulp build && sudo gulp link && npm i && npm start"
15 | },
16 | "private": true,
17 | "dependencies": {
18 | "@angular/animations": "^7.2.8",
19 | "@angular/cdk": "^7.3.3",
20 | "@angular/common": "^7.2.8",
21 | "@angular/compiler": "^7.2.8",
22 | "@angular/core": "^7.2.8",
23 | "@angular/flex-layout": "^7.0.0-beta.23",
24 | "@angular/forms": "^7.2.8",
25 | "@angular/http": "^7.2.8",
26 | "@angular/material": "^7.3.3",
27 | "@angular/platform-browser": "^7.2.8",
28 | "@angular/platform-browser-dynamic": "^7.2.8",
29 | "@angular/platform-server": "^7.2.8",
30 | "@angular/router": "^7.2.8",
31 | "@ng-bootstrap/ng-bootstrap": "4.1.0",
32 | "@stackblitz/sdk": "^1.2.0",
33 | "bootstrap": "4.3.1",
34 | "core-js": "^2.5.4",
35 | "font-awesome": "^4.7.0",
36 | "hammerjs": "^2.0.8",
37 | "rxjs": "^6.4.0",
38 | "zone.js": "^0.8.26"
39 | },
40 | "devDependencies": {
41 | "@angular-devkit/build-angular": "~0.13.5",
42 | "@angular/cli": "~7.3.5",
43 | "@angular/compiler-cli": "^7.2.8",
44 | "@angular/language-service": "^7.2.8",
45 | "@angularclass/hmr": "~2.1.3",
46 | "@compodoc/gulp-compodoc": "0.0.10",
47 | "@nguniversal/common": "^7.1.1",
48 | "@nguniversal/express-engine": "^7.1.1",
49 | "@nguniversal/module-map-ngfactory-loader": "^7.1.1",
50 | "@types/jest": "24.0.11",
51 | "@types/node": "~11.11.0",
52 | "angular-cli-ghpages": "0.5.3",
53 | "ansi-colors": "3.2.4",
54 | "codelyzer": "^4.0.1",
55 | "commitplease": "3.2.0",
56 | "conventional-github-releaser": "3.1.2",
57 | "del": "4.0.0",
58 | "express": "^4.16.2",
59 | "fancy-log": "1.3.3",
60 | "gulp": "^3.9.1",
61 | "gulp-bump": "3.1.3",
62 | "gulp-conventional-changelog": "2.0.10",
63 | "gulp-coveralls": "0.1.4",
64 | "gulp-file": "0.4.0",
65 | "gulp-git": "2.9.0",
66 | "gulp-hub": "4.2.0",
67 | "jest": "24.3.1",
68 | "jest-preset-angular": "7.0.1",
69 | "lodash": "4.17.11",
70 | "prettier": "1.16.4",
71 | "protractor": "~5.4.2",
72 | "reflect-metadata": "~0.1.10",
73 | "run-sequence": "2.2.1",
74 | "travis-status": "3.0.1",
75 | "ts-loader": "~5.3.3",
76 | "ts-node": "~8.0.3",
77 | "tslint": "~5.13.1",
78 | "typescript": "3.1.1",
79 | "webpack-cli": "^3.2.3",
80 | "yargs": "13.2.2"
81 | },
82 | "jest": {
83 | "preset": "jest-preset-angular",
84 | "coverageReporters": [
85 | "lcov",
86 | "text"
87 | ],
88 | "setupTestFrameworkScriptFile": "/src/setupJest.ts"
89 | },
90 | "prettier": {
91 | "trailingComma": "es5",
92 | "tabWidth": 2,
93 | "semi": true,
94 | "singleQuote": true
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/demo/prerender.ts:
--------------------------------------------------------------------------------
1 | // Load zone.js for the server.
2 | import 'zone.js/dist/zone-node';
3 | import 'reflect-metadata';
4 | import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
5 | import { join } from 'path';
6 |
7 | import { enableProdMode } from '@angular/core';
8 | // Faster server renders w/ Prod mode (dev mode never needed)
9 | enableProdMode();
10 |
11 | // Import module map for lazy loading
12 | import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';
13 | import { renderModuleFactory } from '@angular/platform-server';
14 | import { ROUTES } from './static.paths';
15 |
16 | // * NOTE :: leave this as require() since this file is built Dynamically from webpack
17 | const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main');
18 |
19 | const BROWSER_FOLDER = join(process.cwd(), 'dist', 'browser');
20 |
21 | // Load the index.html file containing referances to your application bundle.
22 | const index = readFileSync(join(BROWSER_FOLDER, 'index.html'), 'utf8');
23 |
24 | let previousRender = Promise.resolve();
25 |
26 | // Iterate each route path
27 | ROUTES.forEach(route => {
28 | var fullPath = join(BROWSER_FOLDER, route);
29 |
30 | // Make sure the directory structure is there
31 | if (!existsSync(fullPath)) {
32 | mkdirSync(fullPath);
33 | }
34 |
35 | // Writes rendered HTML to index.html, replacing the file if it already exists.
36 | previousRender = previousRender.then(_ => renderModuleFactory(AppServerModuleNgFactory, {
37 | document: index,
38 | url: route,
39 | extraProviders: [
40 | provideModuleMap(LAZY_MODULE_MAP)
41 | ]
42 | })).then(html => writeFileSync(join(fullPath, 'index.html'), html));
43 | });
44 |
--------------------------------------------------------------------------------
/demo/proxy.conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "/doc/*": {
3 | "target": "http://localhost:8080",
4 | "secure": false,
5 | "pathRewrite": {"^/doc" : ""},
6 | "logLevel": "info"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/demo/server.ts:
--------------------------------------------------------------------------------
1 | import 'zone.js/dist/zone-node';
2 | import 'reflect-metadata';
3 | import { enableProdMode } from '@angular/core';
4 | // Express Engine
5 | import { ngExpressEngine } from '@nguniversal/express-engine';
6 | // Import module map for lazy loading
7 | import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';
8 |
9 | import * as express from 'express';
10 | import { join } from 'path';
11 |
12 | // Faster server renders w/ Prod mode (dev mode never needed)
13 | enableProdMode();
14 |
15 | // Express server
16 | const app = express();
17 |
18 | const PORT = process.env.PORT || 4000;
19 | const DIST_FOLDER = join(process.cwd(), 'dist');
20 |
21 | // * NOTE :: leave this as require() since this file is built Dynamically from webpack
22 | const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main');
23 |
24 | // Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
25 | app.engine('html', ngExpressEngine({
26 | bootstrap: AppServerModuleNgFactory,
27 | providers: [
28 | provideModuleMap(LAZY_MODULE_MAP)
29 | ]
30 | }));
31 |
32 | app.set('view engine', 'html');
33 | app.set('views', join(DIST_FOLDER, 'browser'));
34 |
35 | // Example Express Rest API endpoints
36 | // app.get('/api/**', (req, res) => { });
37 | // Server static files from /browser
38 | app.get('*.*', express.static(join(DIST_FOLDER, 'browser'), {
39 | maxAge: '1y'
40 | }));
41 |
42 | // All regular routes use the Universal engine
43 | app.get('*', (req, res) => {
44 | res.render('index', { req });
45 | });
46 |
47 | // Start up the Node server
48 | app.listen(PORT, () => {
49 | console.log(`Node Express server listening on http://localhost:${PORT}`);
50 | });
51 |
--------------------------------------------------------------------------------
/demo/src/_variables.scss:
--------------------------------------------------------------------------------
1 | $icon-font-path: '../node_modules/bootstrap-sass/assets/fonts/bootstrap/';
2 | $fa-font-path: '../node_modules/font-awesome/fonts/';
3 |
--------------------------------------------------------------------------------
/demo/src/app/app-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 |
4 | const routes: Routes = [
5 | {
6 | path: '',
7 | redirectTo: 'home',
8 | pathMatch: 'full'
9 | },
10 | {
11 | path: 'getting-started',
12 | loadChildren: 'app/getting-started/getting-started.module#GettingStartedModule'
13 | }
14 | ];
15 |
16 | @NgModule({
17 | imports: [RouterModule.forRoot(routes)],
18 | exports: [RouterModule]
19 | })
20 | export class AppRoutingModule { }
21 |
--------------------------------------------------------------------------------
/demo/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/demo/src/app/app.component.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaeldoye/mat-markdown-editor/229a4b1c6d6876987d421b98e737688210c95a6c/demo/src/app/app.component.scss
--------------------------------------------------------------------------------
/demo/src/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | /* tslint:disable:no-unused-variable */
2 | import { Router } from '@angular/router'
3 | import { Component } from '@angular/core'
4 | import { TestBed, async } from '@angular/core/testing'
5 | import { AppComponent } from './app.component'
6 | import { FooterComponent } from './shared/footer/footer.component'
7 |
8 | import {
9 | RouterOutletStubComponent,
10 | RouterLinkStubDirective,
11 | } from '../testing/router-stubs'
12 | import { Observable, of } from 'rxjs'
13 |
14 | @Component({ selector: 'app-header', template: '' })
15 | class HeaderStubComponent {}
16 |
17 | class RouterStub {
18 | events: Observable = of()
19 | }
20 |
21 | // @ts-ignore
22 | describe('AppComponent', () => {
23 | // @ts-ignore
24 | beforeEach(async(() => {
25 | TestBed.configureTestingModule({
26 | declarations: [
27 | AppComponent,
28 | HeaderStubComponent,
29 | FooterComponent,
30 | RouterOutletStubComponent,
31 | ],
32 | providers: [{ provide: Router, useClass: RouterStub }],
33 | })
34 | }))
35 | // @ts-ignore
36 | it('should create', async(() => {
37 | const fixture = TestBed.createComponent(AppComponent)
38 | const app = fixture.debugElement.componentInstance
39 | // @ts-ignore
40 | expect(app).toBeTruthy()
41 | }))
42 | })
43 |
--------------------------------------------------------------------------------
/demo/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Inject, PLATFORM_ID } from '@angular/core';
2 | import { Router, NavigationEnd, RouterEvent } from '@angular/router';
3 | import { isPlatformBrowser } from '@angular/common';
4 | import { filter } from 'rxjs/operators';
5 |
6 | @Component({
7 | selector: 'app-root',
8 | templateUrl: './app.component.html',
9 | styleUrls: ['./app.component.scss']
10 | })
11 | export class AppComponent {
12 |
13 | constructor(private router: Router, @Inject(PLATFORM_ID) private platformId: Object) {
14 |
15 | this.router.events.pipe(
16 | filter((event:RouterEvent) => event instanceof NavigationEnd)
17 | ).subscribe(event => {
18 | if (isPlatformBrowser(this.platformId)) {
19 | window.scroll(0, 0);
20 | }
21 | });
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/demo/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { FormsModule } from '@angular/forms';
3 | import { BrowserModule } from '@angular/platform-browser';
4 | import { TransferHttpCacheModule } from '@nguniversal/common';
5 |
6 | import { AppRoutingModule } from './app-routing.module';
7 | import { AppSharedModule } from './shared';
8 | import { HomeModule } from './home/home.module';
9 | import { AppComponent } from './app.component';
10 | import { MaterialModule } from './material.module';
11 |
12 | @NgModule({
13 | declarations: [AppComponent],
14 | imports: [
15 | // Add .withServerTransition() to support Universal rendering.
16 | // The application ID can be any identifier which is unique on
17 | // the page.
18 | BrowserModule.withServerTransition({
19 | appId: 'mat-markdown-editor-demo-id',
20 | }),
21 | TransferHttpCacheModule,
22 | FormsModule,
23 | MaterialModule,
24 | AppRoutingModule,
25 | AppSharedModule,
26 | HomeModule,
27 | ],
28 | providers: [],
29 | bootstrap: [AppComponent],
30 | })
31 | export class AppModule {}
32 |
--------------------------------------------------------------------------------
/demo/src/app/app.server.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { ServerModule, ServerTransferStateModule } from '@angular/platform-server';
3 | import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader';
4 |
5 | import { AppModule } from './app.module';
6 | import { AppComponent } from './app.component';
7 |
8 | @NgModule({
9 | imports: [
10 | // The AppServerModule should import your AppModule followed
11 | // by the ServerModule from @angular/platform-server.
12 | AppModule,
13 | ServerModule,
14 | ModuleMapLoaderModule,
15 | ServerTransferStateModule,
16 | ],
17 | // Since the bootstrapped component is not inherited from your
18 | // imported AppModule, it needs to be repeated here.
19 | bootstrap: [AppComponent],
20 | })
21 | export class AppServerModule { }
22 |
--------------------------------------------------------------------------------
/demo/src/app/getting-started/getting-started-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { RouterModule } from '@angular/router';
2 | import { NgModule } from '@angular/core';
3 | import { GettingStartedComponent } from './getting-started.component';
4 |
5 | @NgModule({
6 | imports: [RouterModule.forChild([
7 | { path: '', component: GettingStartedComponent }
8 | ])],
9 | exports: [RouterModule]
10 | })
11 | export class GettingStartedRoutingModule {}
--------------------------------------------------------------------------------
/demo/src/app/getting-started/getting-started.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Getting Started
4 |
5 |
6 |
7 |
8 |
9 |
10 | Put your content here. Typically instructions about how to install/use your library.
11 |
12 |
--------------------------------------------------------------------------------
/demo/src/app/getting-started/getting-started.component.scss:
--------------------------------------------------------------------------------
1 | .getting-started{
2 | margin-top: 1.0rem;
3 | }
4 |
--------------------------------------------------------------------------------
/demo/src/app/getting-started/getting-started.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 | import { DebugElement } from '@angular/core';
3 |
4 | import { GettingStartedComponent } from './getting-started.component';
5 |
6 | describe('GettingStartedComponent', () => {
7 | let component: GettingStartedComponent;
8 | let fixture: ComponentFixture;
9 |
10 | beforeEach(async(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [GettingStartedComponent]
13 | })
14 | .compileComponents()
15 | .then(() => {
16 | fixture = TestBed.createComponent(GettingStartedComponent);
17 | component = fixture.componentInstance;
18 | fixture.detectChanges();
19 | });
20 | }));
21 |
22 | it('should create', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/demo/src/app/getting-started/getting-started.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { Title } from '@angular/platform-browser';
3 |
4 |
5 | @Component({
6 | selector: 'app-getting-started',
7 | templateUrl: './getting-started.component.html',
8 | styleUrls: ['./getting-started.component.scss']
9 | })
10 | export class GettingStartedComponent implements OnInit {
11 |
12 | constructor(private titleService:Title) { }
13 |
14 | ngOnInit() {
15 | this.titleService.setTitle('Getting Started | mat-markdown-editor');
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/demo/src/app/getting-started/getting-started.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { GettingStartedComponent } from './getting-started.component';
4 | import { GettingStartedRoutingModule } from './getting-started-routing.module';
5 |
6 | @NgModule({
7 | imports: [
8 | CommonModule,
9 | GettingStartedRoutingModule
10 | ],
11 | declarations: [GettingStartedComponent],
12 | })
13 | export class GettingStartedModule { }
14 |
--------------------------------------------------------------------------------
/demo/src/app/home/home-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { RouterModule } from '@angular/router';
2 | import { NgModule } from '@angular/core';
3 | import { HomeComponent } from './home.component';
4 |
5 | @NgModule({
6 | imports: [RouterModule.forChild([
7 | { path: 'home', component: HomeComponent }
8 | ])],
9 | exports: [RouterModule]
10 | })
11 | export class HomeRoutingModule {}
--------------------------------------------------------------------------------
/demo/src/app/home/home.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |

12 |
13 |
14 |
Mat Markdown Editor
15 |
Material design markdown editor
16 |
Scroll down to see it in action!
17 |
18 | Code on Github
25 | Documentation
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
59 |
{{ form.status | json }}
60 |
61 |
62 |
--------------------------------------------------------------------------------
/demo/src/app/home/home.component.scss:
--------------------------------------------------------------------------------
1 | .logo {
2 | width: 256px;
3 | height: 256px;
4 | margin-top: 1.4rem;
5 | }
6 |
7 | .home {
8 | margin-top: 1.0rem;
9 | }
10 |
11 | button.mat-button {
12 | margin-right: 10px;
13 | }
14 |
--------------------------------------------------------------------------------
/demo/src/app/home/home.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 | import { DebugElement } from '@angular/core';
3 |
4 | import { HomeComponent } from './home.component';
5 | import { LibModule } from 'mat-markdown-editor';
6 |
7 | describe('HomeComponent', () => {
8 | let component: HomeComponent;
9 | let fixture: ComponentFixture;
10 |
11 | beforeEach(async(() => {
12 | TestBed.configureTestingModule({
13 | imports: [
14 | LibModule.forRoot(),],
15 | declarations: [HomeComponent]
16 | })
17 | .compileComponents()
18 | .then(() => {
19 | fixture = TestBed.createComponent(HomeComponent);
20 | component = fixture.componentInstance;
21 | });
22 | }));
23 |
24 | it('should create', () => {
25 | expect(component).toBeTruthy();
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/demo/src/app/home/home.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { Title } from '@angular/platform-browser';
3 | import sdk from '@stackblitz/sdk';
4 | import { MatMarkdownEditorOptions } from 'mat-markdown-editor';
5 |
6 | @Component({
7 | selector: 'app-home',
8 | templateUrl: './home.component.html',
9 | styleUrls: ['./home.component.scss'],
10 | })
11 | export class HomeComponent implements OnInit {
12 | public options: MatMarkdownEditorOptions = {
13 | enablePreviewContentClick: false,
14 | resizable: true,
15 | showBorder: true,
16 | hideIcons: {},
17 | hideToolbar: false,
18 | height: '500px',
19 | mode: 'editor',
20 | toolbarColor: 'primary',
21 | preRender: this.preRender,
22 | };
23 | public content = '### Example Markdown';
24 |
25 | constructor(private titleService: Title) {}
26 |
27 | ngOnInit() {
28 | this.titleService.setTitle('Home | mat-markdown-editor');
29 | }
30 |
31 | editOnStackBlitz() {
32 | sdk.openGithubProject('michaeldoye/mat-markdown-editor/tree/master/demo');
33 | }
34 | preRender(markDown: any) {
35 | return markDown;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/demo/src/app/home/home.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { MatMarkdownEditorModule } from 'mat-markdown-editor';
4 | import { FormsModule } from '@angular/forms';
5 |
6 | import { HomeRoutingModule } from './home-routing.module';
7 | import { HomeComponent } from './home.component';
8 | import { MaterialModule } from '../material.module';
9 |
10 | @NgModule({
11 | imports: [
12 | CommonModule,
13 | MatMarkdownEditorModule.forRoot(),
14 | HomeRoutingModule,
15 | FormsModule,
16 | MaterialModule,
17 | ],
18 | declarations: [HomeComponent],
19 | })
20 | export class HomeModule {}
21 |
--------------------------------------------------------------------------------
/demo/src/app/material.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import {
3 | MatAutocompleteModule,
4 | MatButtonModule,
5 | MatButtonToggleModule,
6 | MatCardModule,
7 | MatCheckboxModule,
8 | MatChipsModule,
9 | MatDatepickerModule,
10 | MatDialogModule,
11 | MatExpansionModule,
12 | MatGridListModule,
13 | MatIconModule,
14 | MatInputModule,
15 | MatListModule,
16 | MatMenuModule,
17 | MatNativeDateModule,
18 | MatPaginatorModule,
19 | MatProgressBarModule,
20 | MatProgressSpinnerModule,
21 | MatRadioModule,
22 | MatRippleModule,
23 | MatSelectModule,
24 | MatSidenavModule,
25 | MatSliderModule,
26 | MatSlideToggleModule,
27 | MatSnackBarModule,
28 | MatSortModule,
29 | MatTableModule,
30 | MatTabsModule,
31 | MatToolbarModule,
32 | MatTooltipModule,
33 | MatStepperModule,
34 | MatFormFieldModule,
35 | } from '@angular/material';
36 |
37 | @NgModule({
38 | imports: [
39 | MatAutocompleteModule,
40 | MatButtonModule,
41 | MatButtonToggleModule,
42 | MatCardModule,
43 | MatCheckboxModule,
44 | MatChipsModule,
45 | MatStepperModule,
46 | MatDatepickerModule,
47 | MatDialogModule,
48 | MatExpansionModule,
49 | MatGridListModule,
50 | MatIconModule,
51 | MatInputModule,
52 | MatListModule,
53 | MatMenuModule,
54 | MatNativeDateModule,
55 | MatPaginatorModule,
56 | MatProgressBarModule,
57 | MatProgressSpinnerModule,
58 | MatRadioModule,
59 | MatRippleModule,
60 | MatSelectModule,
61 | MatSidenavModule,
62 | MatSliderModule,
63 | MatSlideToggleModule,
64 | MatSnackBarModule,
65 | MatSortModule,
66 | MatTableModule,
67 | MatTabsModule,
68 | MatToolbarModule,
69 | MatTooltipModule,
70 | MatFormFieldModule,
71 | ],
72 | exports: [
73 | MatAutocompleteModule,
74 | MatButtonModule,
75 | MatButtonToggleModule,
76 | MatCardModule,
77 | MatCheckboxModule,
78 | MatChipsModule,
79 | MatStepperModule,
80 | MatDatepickerModule,
81 | MatDialogModule,
82 | MatExpansionModule,
83 | MatGridListModule,
84 | MatIconModule,
85 | MatInputModule,
86 | MatListModule,
87 | MatMenuModule,
88 | MatNativeDateModule,
89 | MatPaginatorModule,
90 | MatProgressBarModule,
91 | MatProgressSpinnerModule,
92 | MatRadioModule,
93 | MatRippleModule,
94 | MatSelectModule,
95 | MatSidenavModule,
96 | MatSliderModule,
97 | MatSlideToggleModule,
98 | MatSnackBarModule,
99 | MatSortModule,
100 | MatTableModule,
101 | MatTabsModule,
102 | MatToolbarModule,
103 | MatTooltipModule,
104 | MatFormFieldModule,
105 | ],
106 | })
107 | export class MaterialModule {}
108 |
--------------------------------------------------------------------------------
/demo/src/app/shared/content-wrapper/content-wrapper.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ component }}
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/demo/src/app/shared/content-wrapper/content-wrapper.component.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaeldoye/mat-markdown-editor/229a4b1c6d6876987d421b98e737688210c95a6c/demo/src/app/shared/content-wrapper/content-wrapper.component.scss
--------------------------------------------------------------------------------
/demo/src/app/shared/content-wrapper/content-wrapper.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 | import { DebugElement } from '@angular/core';
3 |
4 | import { ContentWrapperComponent } from './content-wrapper.component';
5 |
6 | describe('ContentWrapperComponent', () => {
7 | let component: ContentWrapperComponent;
8 | let fixture: ComponentFixture;
9 |
10 | beforeEach(async(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [ContentWrapperComponent]
13 | })
14 | .compileComponents()
15 | .then(() => {
16 | fixture = TestBed.createComponent(ContentWrapperComponent);
17 | component = fixture.componentInstance;
18 | fixture.detectChanges();
19 | });
20 | }));
21 |
22 | it('should create', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/demo/src/app/shared/content-wrapper/content-wrapper.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit, Input } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-content-wrapper',
5 | templateUrl: './content-wrapper.component.html',
6 | styleUrls: ['./content-wrapper.component.scss']
7 | })
8 | export class ContentWrapperComponent implements OnInit {
9 |
10 | @Input()
11 | public component: string;
12 |
13 | constructor() { }
14 |
15 | ngOnInit() {
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/demo/src/app/shared/footer/footer.component.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/demo/src/app/shared/footer/footer.component.scss:
--------------------------------------------------------------------------------
1 | footer {
2 | padding: 3rem 0;
3 | font-size: 85%;
4 | background-color: #f7f7f7;
5 | text-align: left;
6 |
7 | .heart{
8 | color: #ff005d;
9 | }
10 |
11 | p {
12 | margin-bottom: 0;
13 | }
14 |
15 | a {
16 | font-weight: 500;
17 | color: #55595c;
18 | }
19 |
20 | }
--------------------------------------------------------------------------------
/demo/src/app/shared/footer/footer.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 | import { DebugElement } from '@angular/core';
3 |
4 | import { FooterComponent } from './footer.component';
5 |
6 | describe('FooterComponent', () => {
7 | let component: FooterComponent;
8 | let fixture: ComponentFixture;
9 |
10 | beforeEach(async(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [FooterComponent]
13 | })
14 | .compileComponents()
15 | .then(() => {
16 | fixture = TestBed.createComponent(FooterComponent);
17 | component = fixture.componentInstance;
18 | fixture.detectChanges();
19 | });
20 | }));
21 |
22 | it('should create', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/demo/src/app/shared/footer/footer.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-footer',
5 | templateUrl: './footer.component.html',
6 | styleUrls: ['./footer.component.scss']
7 | })
8 | export class FooterComponent implements OnInit {
9 |
10 | constructor() { }
11 |
12 | ngOnInit() {
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/demo/src/app/shared/header/header.component.html:
--------------------------------------------------------------------------------
1 |
37 |
--------------------------------------------------------------------------------
/demo/src/app/shared/header/header.component.scss:
--------------------------------------------------------------------------------
1 | .navbar {
2 | background: hsla(0,0%,100%,.95)
3 | }
4 |
--------------------------------------------------------------------------------
/demo/src/app/shared/header/header.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 | import { By } from '@angular/platform-browser';
3 | import { DebugElement } from '@angular/core';
4 |
5 | import { NgbCollapseModule } from '@ng-bootstrap/ng-bootstrap';
6 |
7 | import { HeaderComponent } from './header.component';
8 | import { RouterLinkStubDirective, RouterLinkActiveStubDirective } from './../../../testing/router-stubs';
9 |
10 | describe('HeaderComponent', () => {
11 | let component: HeaderComponent;
12 | let fixture: ComponentFixture;
13 |
14 | let linkDes: DebugElement[];
15 | let links: RouterLinkStubDirective[];
16 |
17 | beforeEach(async(() => {
18 | TestBed.configureTestingModule({
19 | imports: [
20 | NgbCollapseModule.forRoot()
21 | ],
22 | declarations: [
23 | HeaderComponent,
24 | RouterLinkStubDirective,
25 | RouterLinkActiveStubDirective
26 | ]
27 | })
28 | .compileComponents()
29 | .then(() => {
30 | fixture = TestBed.createComponent(HeaderComponent);
31 | component = fixture.componentInstance;
32 | });
33 | }));
34 |
35 | beforeEach(() => {
36 | // trigger initial data binding
37 | fixture.detectChanges();
38 |
39 | // find DebugElements with an attached RouterLinkStubDirective
40 | linkDes = fixture.debugElement.queryAll(By.directive(RouterLinkStubDirective));
41 |
42 | // get the attached link directive instances using the DebugElement injectors
43 | links = linkDes.map(de => de.injector.get(RouterLinkStubDirective) as RouterLinkStubDirective);
44 | });
45 |
46 | it('should create', () => {
47 | expect(component).toBeTruthy();
48 | });
49 |
50 | it('can get RouterLinks from template', () => {
51 | expect(links.length).toBe(2); // should have 2 links
52 | expect(links[0].linkParams).toBe('/home'); // 1st link should go to Home
53 | expect(links[1].linkParams).toBe('/getting-started'); // 2nd link should go to GettingStarted
54 | });
55 |
56 | it('can click Home link in template', () => {
57 | const homeLinkDe = linkDes[0];
58 | const homeLink = links[0];
59 |
60 | expect(homeLink.navigatedTo).toBeNull(); // link should not have navigated yet
61 |
62 | homeLinkDe.triggerEventHandler('click', null);
63 | fixture.detectChanges();
64 |
65 | expect(homeLink.navigatedTo).toBe('/home');
66 | });
67 |
68 | it('can click GettingStarted link in template', () => {
69 | const gettingStartedLinkDe = linkDes[1];
70 | const gettingStartedLink = links[1];
71 |
72 | expect(gettingStartedLink.navigatedTo).toBeNull(); // link should not have navigated yet
73 |
74 | gettingStartedLinkDe.triggerEventHandler('click', null);
75 | fixture.detectChanges();
76 |
77 | expect(gettingStartedLink.navigatedTo).toBe('/getting-started');
78 | });
79 | });
80 |
--------------------------------------------------------------------------------
/demo/src/app/shared/header/header.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-header',
5 | templateUrl: './header.component.html',
6 | styleUrls: ['./header.component.scss']
7 | })
8 | export class HeaderComponent implements OnInit {
9 |
10 | navbarCollapsed = true;
11 |
12 | constructor() { }
13 |
14 | ngOnInit() {
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/demo/src/app/shared/index.ts:
--------------------------------------------------------------------------------
1 | export * from './shared.module';
--------------------------------------------------------------------------------
/demo/src/app/shared/shared.module.ts:
--------------------------------------------------------------------------------
1 | import { RouterModule } from '@angular/router';
2 | import { NgModule } from '@angular/core';
3 | import { NgbCollapseModule } from '@ng-bootstrap/ng-bootstrap';
4 |
5 | import { HeaderComponent } from './header/header.component';
6 | import { FooterComponent } from './footer/footer.component';
7 | import { ContentWrapperComponent } from './content-wrapper/content-wrapper.component';
8 |
9 | @NgModule({
10 | imports: [RouterModule, NgbCollapseModule.forRoot() ],
11 | exports: [HeaderComponent, FooterComponent, ContentWrapperComponent],
12 | declarations: [HeaderComponent, FooterComponent, ContentWrapperComponent],
13 | providers: [],
14 | })
15 | export class AppSharedModule { }
16 |
--------------------------------------------------------------------------------
/demo/src/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaeldoye/mat-markdown-editor/229a4b1c6d6876987d421b98e737688210c95a6c/demo/src/assets/.gitkeep
--------------------------------------------------------------------------------
/demo/src/assets/.npmignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaeldoye/mat-markdown-editor/229a4b1c6d6876987d421b98e737688210c95a6c/demo/src/assets/.npmignore
--------------------------------------------------------------------------------
/demo/src/assets/forms.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaeldoye/mat-markdown-editor/229a4b1c6d6876987d421b98e737688210c95a6c/demo/src/assets/forms.png
--------------------------------------------------------------------------------
/demo/src/assets/forms.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/demo/src/assets/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
17 |
--------------------------------------------------------------------------------
/demo/src/browserslist:
--------------------------------------------------------------------------------
1 | # This file is currently used by autoprefixer to adjust CSS to support the below specified browsers
2 | # For additional information regarding the format and rule options, please see:
3 | # https://github.com/browserslist/browserslist#queries
4 | # For IE 9-11 support, please uncomment the last line of the file and adjust as needed
5 | > 0.5%
6 | last 2 versions
7 | Firefox ESR
8 | not dead
9 | # IE 9-11
--------------------------------------------------------------------------------
/demo/src/environments/environment.hmr.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: false,
3 | hmr: true
4 | };
5 |
--------------------------------------------------------------------------------
/demo/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true,
3 | hmr: false
4 | };
5 |
--------------------------------------------------------------------------------
/demo/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // The file contents for the current environment will overwrite these during build.
2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do
3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead.
4 | // The list of which env maps to which file can be found in `.angular-cli.json`.
5 |
6 | export const environment = {
7 | production: false,
8 | hmr: false
9 | };
10 |
--------------------------------------------------------------------------------
/demo/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaeldoye/mat-markdown-editor/229a4b1c6d6876987d421b98e737688210c95a6c/demo/src/favicon.ico
--------------------------------------------------------------------------------
/demo/src/highlight.js.scss:
--------------------------------------------------------------------------------
1 | /* Dracula Theme v1.2.5
2 | *
3 | * https://github.com/dracula/highlightjs
4 | *
5 | * Copyright 2016-present, All rights reserved
6 | *
7 | * Code licensed under the MIT license
8 | *
9 | * @author Denis Ciccale
10 | * @author Zeno Rocha
11 | */
12 |
13 | .hljs {
14 | display: block;
15 | overflow-x: auto;
16 | padding: 0.5em;
17 | background: #282a36;
18 | }
19 |
20 | .hljs-built_in,
21 | .hljs-selector-tag,
22 | .hljs-section,
23 | .hljs-link {
24 | color: #8be9fd;
25 | }
26 |
27 | .hljs-keyword {
28 | color: #ff79c6;
29 | }
30 |
31 | .hljs,
32 | .hljs-subst {
33 | color: #f8f8f2;
34 | }
35 |
36 | .hljs-title {
37 | color: #50fa7b;
38 | }
39 |
40 | .hljs-string,
41 | .hljs-meta,
42 | .hljs-name,
43 | .hljs-type,
44 | .hljs-attribute,
45 | .hljs-symbol,
46 | .hljs-bullet,
47 | .hljs-addition,
48 | .hljs-variable,
49 | .hljs-template-tag,
50 | .hljs-template-variable {
51 | color: #f1fa8c;
52 | }
53 |
54 | .hljs-comment,
55 | .hljs-quote,
56 | .hljs-deletion {
57 | color: #6272a4;
58 | }
59 |
60 | .hljs-keyword,
61 | .hljs-selector-tag,
62 | .hljs-literal,
63 | .hljs-title,
64 | .hljs-section,
65 | .hljs-doctag,
66 | .hljs-type,
67 | .hljs-name,
68 | .hljs-strong {
69 | font-weight: bold;
70 | }
71 |
72 | .hljs-literal,
73 | .hljs-number {
74 | color: #bd93f9;
75 | }
76 |
77 | .hljs-emphasis {
78 | font-style: italic;
79 | }
--------------------------------------------------------------------------------
/demo/src/hmr.ts:
--------------------------------------------------------------------------------
1 | import { NgModuleRef, ApplicationRef } from '@angular/core';
2 | import { createNewHosts } from '@angularclass/hmr';
3 |
4 | export const hmrBootstrap = (module: any, bootstrap: () => Promise>) => {
5 | let ngModule: NgModuleRef;
6 | module.hot.accept();
7 | bootstrap().then(mod => ngModule = mod);
8 | module.hot.dispose(() => {
9 | const appRef: ApplicationRef = ngModule.injector.get(ApplicationRef);
10 | const elements = appRef.components.map(c => c.location.nativeElement);
11 | const makeVisible = createNewHosts(elements);
12 | ngModule.destroy();
13 | makeVisible();
14 | });
15 | };
16 |
--------------------------------------------------------------------------------
/demo/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | mat-markdown-editor
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
20 |
21 |
22 |
26 |
27 |
28 |
29 |
30 |
34 |
38 |
39 |
40 |
41 |
42 |
46 |
47 |
48 |
49 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | Loading...
61 |
62 |
63 |
--------------------------------------------------------------------------------
/demo/src/jestGlobalMocks.ts:
--------------------------------------------------------------------------------
1 | global['CSS'] = null;
2 |
3 | const mock = () => {
4 | let storage = {};
5 | return {
6 | getItem: key => key in storage ? storage[key] : null,
7 | setItem: (key, value) => storage[key] = value || '',
8 | removeItem: key => delete storage[key],
9 | clear: () => storage = {},
10 | };
11 | };
12 |
13 | Object.defineProperty(window, 'localStorage', {value: mock()});
14 | Object.defineProperty(window, 'sessionStorage', {value: mock()});
15 | Object.defineProperty(document, 'doctype', {
16 | value: ''
17 | });
18 | Object.defineProperty(window, 'getComputedStyle', {
19 | value: () => {
20 | return {
21 | display: 'none',
22 | appearance: ['-webkit-appearance']
23 | };
24 | }
25 | });
26 | /**
27 | * ISSUE: https://github.com/angular/material2/issues/7101
28 | * Workaround for JSDOM missing transform property
29 | */
30 | Object.defineProperty(document.body.style, 'transform', {
31 | value: () => {
32 | return {
33 | enumerable: true,
34 | configurable: true,
35 | };
36 | },
37 | });
38 |
--------------------------------------------------------------------------------
/demo/src/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration file, see link for more information
2 | // https://karma-runner.github.io/1.0/config/configuration-file.html
3 |
4 | module.exports = function (config) {
5 | config.set({
6 | basePath: '',
7 | frameworks: ['jasmine', '@angular-devkit/build-angular'],
8 | plugins: [
9 | require('karma-jasmine'),
10 | require('karma-chrome-launcher'),
11 | require('karma-jasmine-html-reporter'),
12 | require('karma-coverage-istanbul-reporter'),
13 | require('@angular-devkit/build-angular/plugins/karma')
14 | ],
15 | client: {
16 | clearContext: false // leave Jasmine Spec Runner output visible in browser
17 | },
18 | coverageIstanbulReporter: {
19 | dir: require('path').join(__dirname, '../coverage'),
20 | reports: ['html', 'lcovonly'],
21 | fixWebpackSourcePaths: true
22 | },
23 | reporters: ['progress', 'kjhtml'],
24 | port: 9876,
25 | colors: true,
26 | logLevel: config.LOG_INFO,
27 | autoWatch: true,
28 | browsers: ['Chrome'],
29 | singleRun: false
30 | });
31 | };
--------------------------------------------------------------------------------
/demo/src/main.server.ts:
--------------------------------------------------------------------------------
1 | export { AppServerModule } from './app/app.server.module';
2 |
--------------------------------------------------------------------------------
/demo/src/main.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 |
4 | import { AppModule } from './app/app.module';
5 | import { environment } from './environments/environment';
6 |
7 | import { hmrBootstrap } from './hmr';
8 |
9 | import 'hammerjs';
10 |
11 | if (environment.production) {
12 | enableProdMode();
13 | }
14 |
15 | const bootstrap = () => platformBrowserDynamic().bootstrapModule(AppModule);
16 |
17 | if (environment.hmr) {
18 | if (module[ 'hot' ]) {
19 | hmrBootstrap(module, bootstrap);
20 | } else {
21 | console.error('HMR is not enabled for webpack-dev-server!');
22 | console.log('Are you using the --hmr flag for ng serve?');
23 | }
24 | } else {
25 | bootstrap().catch(err => console.log(err));
26 | }
27 |
--------------------------------------------------------------------------------
/demo/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file includes polyfills needed by Angular and is loaded before the app.
3 | * You can add your own extra polyfills to this file.
4 | *
5 | * This file is divided into 2 sections:
6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
8 | * file.
9 | *
10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
13 | *
14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
15 | */
16 |
17 | /***************************************************************************************************
18 | * BROWSER POLYFILLS
19 | */
20 |
21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/
22 | // import 'core-js/es6/symbol';
23 | // import 'core-js/es6/object';
24 | // import 'core-js/es6/function';
25 | // import 'core-js/es6/parse-int';
26 | // import 'core-js/es6/parse-float';
27 | // import 'core-js/es6/number';
28 | // import 'core-js/es6/math';
29 | // import 'core-js/es6/string';
30 | // import 'core-js/es6/date';
31 | // import 'core-js/es6/array';
32 | // import 'core-js/es6/regexp';
33 | // import 'core-js/es6/map';
34 | // import 'core-js/es6/weak-map';
35 | // import 'core-js/es6/set';
36 |
37 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */
38 | // import 'classlist.js'; // Run `npm install --save classlist.js`.
39 |
40 | /** IE10 and IE11 requires the following for the Reflect API. */
41 | // import 'core-js/es6/reflect';
42 |
43 |
44 | /** Evergreen browsers require these. **/
45 | // Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
46 | import 'core-js/es7/reflect';
47 |
48 |
49 | /**
50 | * Web Animations `@angular/platform-browser/animations`
51 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
52 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
53 | **/
54 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
55 |
56 | /**
57 | * By default, zone.js will patch all possible macroTask and DomEvents
58 | * user can disable parts of macroTask/DomEvents patch by setting following flags
59 | */
60 |
61 | // (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
62 | // (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
63 | // (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
64 |
65 | /*
66 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
67 | * with the following flag, it will bypass `zone.js` patch for IE/Edge
68 | */
69 | // (window as any).__Zone_enable_cross_context_check = true;
70 |
71 | /***************************************************************************************************
72 | * Zone JS is required by default for Angular itself.
73 | */
74 | import 'zone.js/dist/zone'; // Included with Angular CLI.
75 |
76 |
77 |
78 | /***************************************************************************************************
79 | * APPLICATION IMPORTS
80 | */
81 |
--------------------------------------------------------------------------------
/demo/src/setupJest.ts:
--------------------------------------------------------------------------------
1 | import 'jest-preset-angular';
2 | import './jestGlobalMocks';
3 |
--------------------------------------------------------------------------------
/demo/src/styles.scss:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 |
3 | @import '_variables';
4 | @import '~bootstrap/scss/bootstrap';
5 | @import '~font-awesome/scss/font-awesome';
6 | @import 'highlight.js';
7 | @import "~@angular/material/prebuilt-themes/indigo-pink.css";
8 |
9 | .jumbotron {
10 | //margin-top: 3.4rem;
11 | margin-bottom: 0rem;
12 | h1 {
13 | font-size: 2.5rem;
14 | margin-bottom: 1.4rem;
15 | }
16 | p {
17 | font-size: 1.2rem;
18 | }
19 |
20 | .btn{
21 | margin: .5rem;
22 | }
23 |
24 | .buttons a{
25 | margin: 0.2rem;
26 | }
27 |
28 | }
29 |
30 | @include media-breakpoint-up(sm) {
31 | .jumbotron {
32 | // margin-top: 3.4rem;
33 | margin-bottom: 0rem;
34 | h1 {
35 | font-size: 3.6rem;
36 | margin-bottom: 1.8rem;
37 | }
38 | p {
39 | font-size: 1.4rem;
40 | }
41 | .buttons a{
42 | margin: 0.3rem;
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/demo/src/test.ts:
--------------------------------------------------------------------------------
1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2 |
3 | import 'zone.js/dist/zone-testing';
4 | import { getTestBed } from '@angular/core/testing';
5 | import {
6 | BrowserDynamicTestingModule,
7 | platformBrowserDynamicTesting
8 | } from '@angular/platform-browser-dynamic/testing';
9 |
10 | declare const require: any;
11 |
12 | // First, initialize the Angular testing environment.
13 | getTestBed().initTestEnvironment(
14 | BrowserDynamicTestingModule,
15 | platformBrowserDynamicTesting()
16 | );
17 | // Then we find all the tests.
18 | const context = require.context('./', true, /\.spec\.ts$/);
19 | // And load the modules.
20 | context.keys().map(context);
21 |
--------------------------------------------------------------------------------
/demo/src/testing/index.ts:
--------------------------------------------------------------------------------
1 | export * from './router-stubs';
--------------------------------------------------------------------------------
/demo/src/testing/router-stubs.ts:
--------------------------------------------------------------------------------
1 |
2 | import { Component, Directive, Injectable, Input } from '@angular/core';
3 | import { NavigationExtras } from '@angular/router';
4 | // Only implements params and part of snapshot.params
5 | import { BehaviorSubject } from 'rxjs';
6 |
7 | // export for convenience.
8 | export { ActivatedRoute, Router, RouterLink, RouterOutlet } from '@angular/router';
9 |
10 |
11 | @Directive({
12 | selector: '[routerLink]',
13 | host: {
14 | '(click)': 'onClick()'
15 | }
16 | })
17 | export class RouterLinkStubDirective {
18 | @Input('routerLink') linkParams: any;
19 | navigatedTo: any = null;
20 |
21 | onClick() {
22 | this.navigatedTo = this.linkParams;
23 | }
24 | }
25 |
26 | @Directive({
27 | selector: '[routerLinkActive]'
28 | })
29 | export class RouterLinkActiveStubDirective {
30 | @Input('routerLinkActive') linkParams: any;
31 | }
32 |
33 | @Component({ selector: 'router-outlet', template: '' })
34 | export class RouterOutletStubComponent { }
35 |
36 | @Injectable()
37 | export class RouterStub {
38 | navigate(commands: any[], extras?: NavigationExtras) { }
39 | }
40 |
41 |
42 | @Injectable()
43 | export class ActivatedRouteStub {
44 |
45 | // ActivatedRoute.params is Observable
46 | private subject = new BehaviorSubject(this.testParams);
47 | params = this.subject.asObservable();
48 |
49 | // Test parameters
50 | private _testParams: {};
51 | get testParams() { return this._testParams; }
52 | set testParams(params: {}) {
53 | this._testParams = params;
54 | this.subject.next(params);
55 | }
56 |
57 | // ActivatedRoute.snapshot.params
58 | get snapshot() {
59 | return { params: this.testParams };
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/demo/src/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/app",
5 | "baseUrl": "./",
6 | "module": "es2015",
7 | "types": [],
8 | "paths": {
9 | "@angular/*": ["../node_modules/@angular/*"]
10 | }
11 | },
12 | "exclude": [
13 | "testing/*",
14 | "test.ts",
15 | "setupJest.ts",
16 | "jestGlobalMocks.ts",
17 | "**/*.spec.ts"
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/demo/src/tsconfig.server.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/app",
5 | "baseUrl": "./",
6 | "module": "commonjs",
7 | "types": []
8 | },
9 | "exclude": [
10 | "testing/*",
11 | "test.ts",
12 | "setupJest.ts",
13 | "jestGlobalMocks.ts",
14 | "**/*.spec.ts"
15 | ],
16 | "angularCompilerOptions": {
17 | "entryModule": "app/app.server.module#AppServerModule"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/demo/src/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/spec",
5 | "baseUrl": "./",
6 | "module": "commonjs",
7 | "target": "es5",
8 | "types": [
9 | "jasmine",
10 | "node"
11 | ]
12 | },
13 | "files": [
14 | "test.ts",
15 | "polyfills.ts"
16 | ],
17 | "include": [
18 | "**/*.spec.ts",
19 | "**/*.d.ts"
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/demo/src/typings.d.ts:
--------------------------------------------------------------------------------
1 | /* SystemJS module definition */
2 | declare var module: NodeModule;
3 | interface NodeModule {
4 | id: string;
5 | }
6 |
--------------------------------------------------------------------------------
/demo/static.paths.ts:
--------------------------------------------------------------------------------
1 | export const ROUTES = [
2 | '/',
3 | '/getting-started/',
4 | ];
5 |
--------------------------------------------------------------------------------
/demo/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "outDir": "./dist/out-tsc",
5 | "sourceMap": true,
6 | "declaration": false,
7 | "moduleResolution": "node",
8 | "emitDecoratorMetadata": true,
9 | "experimentalDecorators": true,
10 | "target": "es5",
11 | "typeRoots": [
12 | "node_modules/@types"
13 | ],
14 | "lib": [
15 | "es2017",
16 | "dom"
17 | ]
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/demo/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rulesDirectory": [
3 | "node_modules/codelyzer"
4 | ],
5 | "rules": {
6 | "arrow-return-shorthand": true,
7 | "callable-types": true,
8 | "class-name": true,
9 | "comment-format": [
10 | true,
11 | "check-space"
12 | ],
13 | "curly": true,
14 | "deprecation": {
15 | "severity": "warn"
16 | },
17 | "eofline": true,
18 | "forin": true,
19 | "import-blacklist": [
20 | true,
21 | "rxjs/Rx"
22 | ],
23 | "import-spacing": true,
24 | "indent": [
25 | true,
26 | "spaces"
27 | ],
28 | "interface-over-type-literal": true,
29 | "label-position": true,
30 | "max-line-length": [
31 | true,
32 | 140
33 | ],
34 | "member-access": false,
35 | "member-ordering": [
36 | true,
37 | {
38 | "order": [
39 | "static-field",
40 | "instance-field",
41 | "static-method",
42 | "instance-method"
43 | ]
44 | }
45 | ],
46 | "no-arg": true,
47 | "no-bitwise": true,
48 | "no-console": [
49 | true,
50 | "debug",
51 | "info",
52 | "time",
53 | "timeEnd",
54 | "trace"
55 | ],
56 | "no-construct": true,
57 | "no-debugger": true,
58 | "no-duplicate-super": true,
59 | "no-empty": false,
60 | "no-empty-interface": true,
61 | "no-eval": true,
62 | "no-inferrable-types": [
63 | true,
64 | "ignore-params"
65 | ],
66 | "no-misused-new": true,
67 | "no-non-null-assertion": true,
68 | "no-shadowed-variable": true,
69 | "no-string-literal": false,
70 | "no-string-throw": true,
71 | "no-switch-case-fall-through": true,
72 | "no-trailing-whitespace": true,
73 | "no-unnecessary-initializer": true,
74 | "no-unused-expression": true,
75 | "no-use-before-declare": true,
76 | "no-var-keyword": true,
77 | "object-literal-sort-keys": false,
78 | "one-line": [
79 | true,
80 | "check-open-brace",
81 | "check-catch",
82 | "check-else",
83 | "check-whitespace"
84 | ],
85 | "prefer-const": true,
86 | "quotemark": [
87 | true,
88 | "single"
89 | ],
90 | "radix": true,
91 | "semicolon": [
92 | true,
93 | "always"
94 | ],
95 | "triple-equals": [
96 | true,
97 | "allow-null-check"
98 | ],
99 | "typedef-whitespace": [
100 | true,
101 | {
102 | "call-signature": "nospace",
103 | "index-signature": "nospace",
104 | "parameter": "nospace",
105 | "property-declaration": "nospace",
106 | "variable-declaration": "nospace"
107 | }
108 | ],
109 | "unified-signatures": true,
110 | "variable-name": false,
111 | "whitespace": [
112 | true,
113 | "check-branch",
114 | "check-decl",
115 | "check-operator",
116 | "check-separator",
117 | "check-type"
118 | ],
119 | "no-output-on-prefix": true,
120 | "use-input-property-decorator": true,
121 | "use-output-property-decorator": true,
122 | "use-host-property-decorator": true,
123 | "no-input-rename": true,
124 | "no-output-rename": true,
125 | "use-life-cycle-interface": true,
126 | "use-pipe-transform-interface": true,
127 | "component-class-suffix": true,
128 | "directive-class-suffix": true
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/demo/webpack.server.config.js:
--------------------------------------------------------------------------------
1 | // Work around for https://github.com/angular/angular-cli/issues/7200
2 |
3 | const path = require('path');
4 | const webpack = require('webpack');
5 |
6 | module.exports = {
7 | mode: 'none',
8 | entry: {
9 | // This is our Express server for Dynamic universal
10 | server: './server.ts',
11 | // This is an example of Static prerendering (generative)
12 | prerender: './prerender.ts'
13 | },
14 | target: 'node',
15 | resolve: { extensions: ['.ts', '.js'] },
16 | // Make sure we include all node_modules etc
17 | externals: [/node_modules/],
18 | output: {
19 | // Puts the output at the root of the dist folder
20 | path: path.join(__dirname, 'dist'),
21 | filename: '[name].js'
22 | },
23 | module: {
24 | rules: [
25 | { test: /\.ts$/, loader: 'ts-loader' }
26 | ]
27 | },
28 | plugins: [
29 | new webpack.ContextReplacementPlugin(
30 | // fixes WARNING Critical dependency: the request of a dependency is an expression
31 | /(.+)?angular(\\|\/)core(.+)?/,
32 | path.join(__dirname, 'src'), // location of your src
33 | {} // a map of your routes
34 | ),
35 | new webpack.ContextReplacementPlugin(
36 | // fixes WARNING Critical dependency: the request of a dependency is an expression
37 | /(.+)?express(\\|\/)(.+)?/,
38 | path.join(__dirname, 'src'),
39 | {}
40 | )
41 | ]
42 | }
43 |
--------------------------------------------------------------------------------
/greenkeeper.json:
--------------------------------------------------------------------------------
1 | {
2 | "groups": {
3 | "default": {
4 | "packages": [
5 | "demo/package.json",
6 | "package.json"
7 | ]
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | const _ = require('lodash');
2 | const del = require('del');
3 | const gulp = require('gulp');
4 | const acolors = require('ansi-colors');
5 | const fancyLog = require('fancy-log');
6 | const helpers = require('./config/helpers');
7 |
8 | /** TSLint checker */
9 | const tslint = require('tslint');
10 | const gulpTslint = require('gulp-tslint');
11 |
12 | /** External command runner */
13 | const process = require('process');
14 | const execSync = require('child_process').execSync;
15 |
16 | /** File Access */
17 | const fs = require('fs');
18 | const path = require('path');
19 | const gulpFile = require('gulp-file');
20 |
21 | /** To properly handle pipes on error */
22 | const pump = require('pump');
23 |
24 | /** Testing/Code Coverage */
25 | const gulpCoveralls = require('gulp-coveralls');
26 | const jestCli = require('jest-cli');
27 |
28 | /** To order tasks */
29 | const runSequence = require('run-sequence');
30 |
31 | /** To compile & bundle the library with Angular & Rollup */
32 | const ngc = (args) => new Promise((resolve, reject)=>{// Promisify version of the ngc compiler
33 | let exitCode = require('@angular/compiler-cli/src/main').main(args);
34 | resolve(exitCode);
35 | });
36 | const rollup = require('rollup');
37 | const rollupUglify = require('rollup-plugin-uglify');
38 | const rollupSourcemaps = require('rollup-plugin-sourcemaps');
39 | const rollupNodeResolve = require('rollup-plugin-node-resolve');
40 | const rollupCommonjs = require('rollup-plugin-commonjs');
41 |
42 | /** To load templates and styles in Angular components */
43 | const gulpInlineNgTemplate = require('gulp-inline-ng2-template');
44 |
45 | /** Sass style */
46 | const sass = require('node-sass');
47 | const cssnano = require('cssnano');
48 | const postcss = require('postcss');
49 | const autoprefixer = require('autoprefixer');
50 | const stripInlineComments = require('postcss-strip-inline-comments');
51 |
52 | //Bumping, Releasing tools
53 | const gulpGit = require('gulp-git');
54 | const gulpBump = require('gulp-bump');
55 | const gulpConventionalChangelog = require('gulp-conventional-changelog');
56 | const conventionalGithubReleaser = require('conventional-github-releaser');
57 |
58 | /** To load gulp tasks from multiple files */
59 | const gulpHub = require('gulp-hub');
60 |
61 | /** Documentation generation tools **/
62 | const gulpCompodoc = require('@compodoc/gulp-compodoc');
63 |
64 | const yargs = require('yargs');
65 | const argv = yargs
66 | .option('version', {
67 | alias: 'v',
68 | describe: 'Enter Version to bump to',
69 | choices: ['patch', 'minor', 'major'],
70 | type: "string"
71 | })
72 | .option('ghToken', {
73 | alias: 'gh',
74 | describe: 'Enter Github Token for releasing',
75 | type: "string"
76 | })
77 | .version(false) // disable default --version from yargs( since v9.0.0)
78 | .argv;
79 |
80 | const config = {
81 | libraryName: 'mat-markdown-editor',
82 | unscopedLibraryName: 'mat-markdown-editor',
83 | allSrc: 'src/**/*',
84 | allTs: 'src/**/!(*.spec).ts',
85 | allSass: 'src/**/*.+(scss|sass)',
86 | allHtml: 'src/**/*.html',
87 | demoDir: 'demo/',
88 | buildDir: 'tmp/',
89 | outputDir: 'dist/',
90 | outputDemoDir: 'demo/dist/browser/',
91 | coverageDir: 'coverage/'
92 | };
93 |
94 | const rootFolder = path.join(__dirname);
95 | const buildFolder = path.join(rootFolder, `${config.buildDir}`);
96 | const distFolder = path.join(rootFolder, `${config.outputDir}`);
97 | const es5OutputFolder = path.join(buildFolder, 'lib-es5');
98 | const es2015OutputFolder = path.join(buildFolder, 'lib-es2015');
99 |
100 | //Helper functions
101 |
102 | const getPackageJsonVersion = () => {
103 | // We parse the json file instead of using require because require caches
104 | // multiple calls so the version number won't be updated
105 | return JSON.parse(fs.readFileSync('./package.json', 'utf8')).version;
106 | };
107 |
108 | const isOK = condition => {
109 | if(condition === undefined){
110 | return acolors.yellow('[SKIPPED]');
111 | }
112 | return condition ? acolors.green('[OK]') : acolors.red('[KO]');
113 | };
114 |
115 | const readyToRelease = () => {
116 | let isTravisPassing = /build #\d+ passed/.test(execSync('npm run check-travis').toString().trim());
117 | let onMasterBranch = execSync('git symbolic-ref --short -q HEAD').toString().trim() === 'master';
118 | let canBump = !!argv.version;
119 | let canGhRelease = argv.ghToken || process.env.CONVENTIONAL_GITHUB_RELEASER_TOKEN;
120 | let canNpmPublish = !!execSync('npm whoami').toString().trim() && execSync('npm config get registry').toString().trim() === 'https://registry.npmjs.org/';
121 |
122 | fancyLog(`[travis-ci] Travis build on 'master' branch is passing............................................${isOK(isTravisPassing)}`);
123 | fancyLog(`[git-branch] User is currently on 'master' branch..................................................${isOK(onMasterBranch)}`);
124 | fancyLog(`[npm-publish] User is currently logged in to NPM Registry...........................................${isOK(canNpmPublish)}`);
125 | fancyLog(`[bump-version] Option '--version' provided, with value : 'major', 'minor' or 'patch'.................${isOK(canBump)}`);
126 | fancyLog(`[github-release] Option '--ghToken' provided or 'CONVENTIONAL_GITHUB_RELEASER_TOKEN' variable set......${isOK(canGhRelease)}`);
127 |
128 | return isTravisPassing && onMasterBranch && canBump && canGhRelease && canNpmPublish;
129 | };
130 |
131 | const execCmd = (name, args, opts, ...subFolders) => {
132 | const cmd = helpers.root(subFolders, helpers.binPath(`${name}`));
133 | return helpers.execp(`${cmd} ${args}`, opts)
134 | .catch(e => {
135 | fancyLog(acolors.red(`${name} command failed. See below for errors.\n`));
136 | fancyLog(acolors.red(e));
137 | process.exit(1);
138 | });
139 | };
140 |
141 | const execExternalCmd = (name, args, opts) => {
142 | return helpers.execp(`${name} ${args}`, opts)
143 | .catch(e => {
144 | fancyLog(acolors.red(`${name} command failed. See below for errors.\n`));
145 | fancyLog(acolors.red(e));
146 | process.exit(1);
147 | });
148 | };
149 |
150 |
151 | // Compile Sass to css
152 | const styleProcessor = (stylePath, ext, styleFile, callback) => {
153 | /**
154 | * Remove comments, autoprefixer, Minifier
155 | */
156 | const processors = [
157 | stripInlineComments,
158 | autoprefixer,
159 | cssnano
160 | ];
161 |
162 | const postProcessCss = css => {
163 | postcss(processors).process(css, {from: undefined}).then(result => {
164 | result.warnings().forEach(function (warn) {
165 | fancyLog.warn(warn.toString());
166 | });
167 | styleFile = result.css;
168 | callback(null, styleFile);
169 | });
170 | };
171 |
172 | if (/\.(scss|sass)$/.test(ext[0])) {
173 | let sassObj = sass.renderSync({ file: stylePath });
174 | if (sassObj && sassObj['css']) {
175 | let css = sassObj.css.toString('utf8');
176 | postProcessCss(css);
177 | }
178 | } else if (/\.css$/.test(ext[0])) {
179 | postProcessCss(styleFile);
180 | }
181 | };
182 |
183 | /////////////////////////////////////////////////////////////////////////////
184 | // Cleaning Tasks
185 | /////////////////////////////////////////////////////////////////////////////
186 | gulp.task('clean:dist', () => {
187 | return del(config.outputDir);
188 | });
189 |
190 | gulp.task('clean:build', () => {
191 | return del(config.buildDir);
192 | });
193 |
194 | gulp.task('clean:coverage', () => {
195 | return del(config.coverageDir);
196 | });
197 |
198 | gulp.task('clean:doc', () => {
199 | return del(`${config.outputDir}/doc`);
200 | });
201 |
202 | gulp.task('clean', ['clean:dist', 'clean:coverage', 'clean:build']);
203 |
204 | /////////////////////////////////////////////////////////////////////////////
205 | // Compilation Tasks
206 | /////////////////////////////////////////////////////////////////////////////
207 |
208 | gulp.task('lint', (cb) => {
209 | pump([
210 | gulp.src(config.allTs),
211 | gulpTslint(
212 | {
213 | program: tslint.Linter.createProgram('./tsconfig.json'),
214 | formatter: 'verbose',
215 | configuration: 'tslint.json'
216 | }),
217 | gulpTslint.report()
218 | ], cb);
219 | });
220 |
221 | // Inline Styles and Templates into components
222 | gulp.task('inline-templates', (cb) => {
223 | const options = {
224 | base: `${config.buildDir}`,
225 | styleProcessor: styleProcessor,
226 | useRelativePaths: true
227 | };
228 | pump(
229 | [
230 | gulp.src(config.allTs),
231 | gulpInlineNgTemplate(options),
232 | gulp.dest(`${config.buildDir}`)
233 | ],
234 | cb);
235 | });
236 |
237 | // Prepare files for compilation
238 | gulp.task('pre-compile', (cb) => {
239 | pump([
240 | gulp.src([config.allSrc]),
241 | gulp.dest(config.buildDir)
242 | ], cb);
243 | });
244 |
245 | gulp.task('ng-compile',() => {
246 | return Promise.resolve()
247 | // Compile to ES5.
248 | .then(() => ngc(['--project',`${buildFolder}/tsconfig.lib.es5.json`])
249 | .then(exitCode => exitCode === 0 ? Promise.resolve() : Promise.reject())
250 | .then(() => fancyLog('ES5 compilation succeeded.'))
251 | )
252 | // Compile to ES2015.
253 | .then(() => ngc(['--project',`${buildFolder}/tsconfig.lib.json`])
254 | .then(exitCode => exitCode === 0 ? Promise.resolve() : Promise.reject())
255 | .then(() => fancyLog('ES2015 compilation succeeded.'))
256 | )
257 | .catch(e => {
258 | fancyLog(acolors.red('ng-compilation failed. See below for errors.\n'));
259 | fancyLog(acolors.red(e));
260 | process.exit(1);
261 | });
262 | });
263 |
264 | // Lint, Prepare Build, , Sass to css, Inline templates & Styles and Ng-Compile
265 | gulp.task('compile', (cb) => {
266 | runSequence('lint', 'pre-compile', 'inline-templates', 'ng-compile', cb);
267 | });
268 |
269 | // Build the 'dist' folder (without publishing it to NPM)
270 | gulp.task('build', ['clean'], (cb) => {
271 | runSequence('compile', 'test', 'npm-package', 'rollup-bundle', cb);
272 | });
273 |
274 | // Same as 'build' but without cleaning temp folders (to avoid breaking demo app, if currently being served)
275 | gulp.task('build-watch', (cb) => {
276 | runSequence('compile', 'test', 'npm-package', 'rollup-bundle', cb);
277 | });
278 |
279 | // Same as 'build-watch' but without running tests
280 | gulp.task('build-watch-no-tests', (cb) => {
281 | runSequence('compile', 'npm-package', 'rollup-bundle', cb);
282 | });
283 |
284 | // Watch changes on (*.ts, *.html, *.sass) and Re-build library
285 | gulp.task('build:watch', ['build-watch'], () => {
286 | gulp.watch([config.allTs, config.allHtml, config.allSass], ['build-watch']);
287 | });
288 |
289 | // Watch changes on (*.ts, *.html, *.sass) and Re-build library (without running tests)
290 | gulp.task('build:watch-fast', ['build-watch-no-tests'], () => {
291 | gulp.watch([config.allTs, config.allHtml, config.allSass], ['build-watch-no-tests']);
292 | });
293 |
294 |
295 | /////////////////////////////////////////////////////////////////////////////
296 | // Packaging Tasks
297 | /////////////////////////////////////////////////////////////////////////////
298 |
299 | // Prepare 'dist' folder for publication to NPM
300 | gulp.task('npm-package', (cb) => {
301 | let pkgJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
302 | let targetPkgJson = {};
303 | let fieldsToCopy = ['version', 'description', 'keywords', 'author', 'repository', 'license', 'bugs', 'homepage'];
304 |
305 | targetPkgJson['name'] = config.libraryName;
306 |
307 | //only copy needed properties from project's package json
308 | fieldsToCopy.forEach((field) => { targetPkgJson[field] = pkgJson[field]; });
309 |
310 | targetPkgJson['main'] = `./bundles/${config.unscopedLibraryName}.umd.js`;
311 | targetPkgJson['module'] = `./esm5/${config.unscopedLibraryName}.es5.js`;
312 | targetPkgJson['es2015'] = `./esm2015/${config.unscopedLibraryName}.js`;
313 | targetPkgJson['typings'] = `./${config.unscopedLibraryName}.d.ts`;
314 |
315 | // defines project's dependencies as 'peerDependencies' for final users
316 | targetPkgJson.peerDependencies = {};
317 | Object.keys(pkgJson.dependencies).forEach((dependency) => {
318 | // versions are defined as '^' by default, but you can customize it by editing "dependenciesRange" in '.yo-rc.json' file
319 | targetPkgJson.peerDependencies[dependency] = `^${pkgJson.dependencies[dependency].replace(/[\^~><=]/,'')}`;
320 | });
321 |
322 | // copy the needed additional files in the 'dist' folder
323 | pump(
324 | [
325 | gulp.src(['README.md', 'LICENSE', 'CHANGELOG.md',
326 | `${config.buildDir}/lib-es5/**/*.d.ts`,
327 | `${config.buildDir}/lib-es5/**/*.metadata.json`]),
328 | gulpFile('package.json', JSON.stringify(targetPkgJson, null, 2)),
329 | gulp.dest(config.outputDir)
330 | ], cb);
331 | });
332 |
333 | // Bundles the library as UMD/FESM bundles using RollupJS
334 | gulp.task('rollup-bundle', (cb) => {
335 | return Promise.resolve()
336 | // Bundle lib.
337 | .then(() => {
338 | // Base configuration.
339 | const es5Input = path.join(es5OutputFolder, `${config.unscopedLibraryName}.js`);
340 | const es2015Input = path.join(es2015OutputFolder, `${config.unscopedLibraryName}.js`);
341 | const globals = {
342 | // The key here is library name, and the value is the name of the global variable name
343 | // the window object.
344 | // See https://github.com/rollup/rollup/wiki/JavaScript-API#globals for more.
345 |
346 | // Angular dependencies
347 | '@angular/core': 'ng.core',
348 | '@angular/common': 'ng.common',
349 |
350 | // Rxjs dependencies
351 | 'rxjs/Subject': 'Rx',
352 | 'rxjs/Observable': 'Rx',
353 | 'rxjs/add/observable/fromEvent': 'Rx.Observable',
354 | 'rxjs/add/observable/forkJoin': 'Rx.Observable',
355 | 'rxjs/add/observable/of': 'Rx.Observable',
356 | 'rxjs/add/observable/merge': 'Rx.Observable',
357 | 'rxjs/add/observable/throw': 'Rx.Observable',
358 | 'rxjs/add/operator/auditTime': 'Rx.Observable.prototype',
359 | 'rxjs/add/operator/toPromise': 'Rx.Observable.prototype',
360 | 'rxjs/add/operator/map': 'Rx.Observable.prototype',
361 | 'rxjs/add/operator/filter': 'Rx.Observable.prototype',
362 | 'rxjs/add/operator/do': 'Rx.Observable.prototype',
363 | 'rxjs/add/operator/share': 'Rx.Observable.prototype',
364 | 'rxjs/add/operator/finally': 'Rx.Observable.prototype',
365 | 'rxjs/add/operator/catch': 'Rx.Observable.prototype',
366 | 'rxjs/add/observable/empty': 'Rx.Observable.prototype',
367 | 'rxjs/add/operator/first': 'Rx.Observable.prototype',
368 | 'rxjs/add/operator/startWith': 'Rx.Observable.prototype',
369 | 'rxjs/add/operator/switchMap': 'Rx.Observable.prototype',
370 |
371 | // ATTENTION:
372 | // Add any other dependency or peer dependency of your library here
373 | // This is required for UMD bundle users.
374 | // See https://github.com/tinesoft/generator-ngx-library/TROUBLESHOUTING.md if trouble
375 |
376 |
377 | };
378 | const rollupBaseConfig = {
379 | output:{
380 | name: _.camelCase(config.libraryName),
381 | sourcemap: true,
382 | globals: globals
383 | },
384 | // List of dependencies
385 | // See https://github.com/rollup/rollup/wiki/JavaScript-API#external for more.
386 | external: Object.keys(globals),
387 | plugins: [
388 | rollupCommonjs({
389 | include: ['node_modules/rxjs/**']
390 | }),
391 | rollupSourcemaps(),
392 | rollupNodeResolve({
393 | jsnext: true,
394 | module: true,
395 | jail: distFolder, // to use final 'package.json' from 'dist/'
396 | })
397 | ]
398 | };
399 |
400 | // UMD bundle.
401 | const umdConfig = _.merge({}, rollupBaseConfig, {
402 | input: es5Input,
403 | output: {
404 | format: 'umd',
405 | file: path.join(distFolder, `bundles`, `${config.unscopedLibraryName}.umd.js`)
406 | }
407 | });
408 |
409 | // Minified UMD bundle.
410 | const minifiedUmdConfig = _.merge({}, rollupBaseConfig, {
411 | input: es5Input,
412 | output: {
413 | format: 'umd',
414 | file: path.join(distFolder, `bundles`, `${config.unscopedLibraryName}.umd.min.js`),
415 | },
416 | plugins: rollupBaseConfig.plugins.concat([rollupUglify({})])
417 | });
418 |
419 | // ESM+ES5 flat module bundle.
420 | const fesm5config = _.merge({}, rollupBaseConfig, {
421 | input: es5Input,
422 | output: {
423 | format: 'es',
424 | file: path.join(distFolder, 'esm5', `${config.unscopedLibraryName}.es5.js`),
425 | }
426 | });
427 |
428 | // ESM+ES2015 flat module bundle.
429 | const fesm2015config = _.merge({}, rollupBaseConfig, {
430 | input: es2015Input,
431 | output: {
432 | format: 'es',
433 | file: path.join(distFolder, 'esm2015', `${config.unscopedLibraryName}.js`),
434 | }
435 | });
436 |
437 | const allBundles = [
438 | umdConfig,
439 | minifiedUmdConfig,
440 | fesm5config,
441 | fesm2015config
442 | ].map(cfg => rollup.rollup(cfg).then(bundle => bundle.write(cfg.output)));
443 |
444 | return Promise.all(allBundles)
445 | .then(() => fancyLog('All bundles generated successfully.'))
446 | })
447 | .catch(e => {
448 | fancyLog(acolors.red('rollup-bundling failed. See below for errors.\n'));
449 | fancyLog(acolors.red(e));
450 | process.exit(1);
451 | });
452 | });
453 |
454 |
455 | /////////////////////////////////////////////////////////////////////////////
456 | // Documentation Tasks
457 | /////////////////////////////////////////////////////////////////////////////
458 | gulp.task('build:doc', (cb) => {
459 | pump([
460 | gulp.src('src/**/*.ts'),
461 | gulpCompodoc({
462 | tsconfig: 'src/tsconfig.lib.json',
463 | hideGenerator:true,
464 | disableCoverage: true,
465 | output: `${config.outputDemoDir}/doc/`
466 | })
467 | ], cb);
468 | });
469 |
470 | gulp.task('serve:doc', ['clean:doc'], (cb) => {
471 | pump([
472 | gulp.src('src/**/*.ts'),
473 | gulpCompodoc({
474 | tsconfig: 'src/tsconfig.lib.json',
475 | serve: true,
476 | output: `${config.outputDir}/doc/`
477 | })
478 | ], cb);
479 | });
480 |
481 |
482 |
483 | /////////////////////////////////////////////////////////////////////////////
484 | // Demo Tasks
485 | /////////////////////////////////////////////////////////////////////////////
486 | const execDemoCmd = (args,opts) => {
487 | if(fs.existsSync(`${config.demoDir}/node_modules`)){
488 | return execCmd('ng', args, opts, `/${config.demoDir}`);
489 | }
490 | else{
491 | fancyLog(acolors.yellow(`No 'node_modules' found in '${config.demoDir}'. Installing dependencies for you...`));
492 | return helpers.installDependencies({ cwd: `${config.demoDir}` })
493 | .then(exitCode => exitCode === 0 ? execCmd('ng', args, opts, `/${config.demoDir}`) : Promise.reject())
494 | .catch(e => {
495 | fancyLog(acolors.red(`ng command failed. See below for errors.\n`));
496 | fancyLog(acolors.red(e));
497 | process.exit(1);
498 | });
499 | }
500 | };
501 |
502 | gulp.task('test:demo', () => {
503 | return execExternalCmd('npm', 'run test', { cwd: `${config.demoDir}`});
504 | });
505 |
506 | gulp.task('serve:demo', () => {
507 | return execDemoCmd('serve --aot --proxy-config proxy.conf.json', { cwd: `${config.demoDir}` });
508 | });
509 |
510 | gulp.task('serve:demo-hmr', () => {
511 | return execDemoCmd('serve --configuration hmr --aot --proxy-config proxy.conf.json', { cwd: `${config.demoDir}` });
512 | });
513 |
514 | gulp.task('build:demo', () => {
515 | return execDemoCmd(`build --preserve-symlinks --prod --base-href /mat-markdown-editor/ --deploy-url /mat-markdown-editor/`, { cwd: `${config.demoDir}`});
516 | });
517 |
518 | gulp.task('serve:demo-ssr',['build:demo-ssr'], () => {
519 | return execExternalCmd('node', 'dist/server.js', { cwd: `${config.demoDir}` });
520 | });
521 |
522 | gulp.task('build:demo-ssr', () => {
523 | return execDemoCmd(`build --preserve-symlinks --prod`, { cwd: `${config.demoDir}`})
524 | .then(() => execDemoCmd(`run mat-markdown-editor-demo:server`, { cwd: `${config.demoDir}` }))
525 | .then(() => execCmd('webpack', '--config webpack.server.config.js --progress --colors', { cwd: `${config.demoDir}` }, `/${config.demoDir}`))
526 | .catch(e => {
527 | fancyLog(acolors.red(`build:demo-ssr command failed. See below for errors.\n`));
528 | fancyLog(acolors.red(e));
529 | process.exit(1);
530 | });
531 | });
532 |
533 | gulp.task('push:demo', () => {
534 | return execCmd('ngh',`--dir ${config.outputDemoDir} --message="chore(demo): :rocket: deploy new version"`);
535 | });
536 |
537 | gulp.task('deploy:demo', (cb) => {
538 | runSequence('build:demo', 'build:doc', 'push:demo', cb);
539 | });
540 |
541 |
542 | /////////////////////////////////////////////////////////////////////////////
543 | // Test Tasks
544 | /////////////////////////////////////////////////////////////////////////////
545 | gulp.task('test', (cb) => {
546 | let isTravis = !!process.env.TRAVIS;
547 | return jestCli.runCLI({ config: require('./package.json').jest, coverage: true, runInBand: isTravis, ci: isTravis }, ".").then(({ results }) => {
548 | if (!results.success) throw new Error('There are test failures!');
549 | });
550 | });
551 |
552 | gulp.task('test:ci', ['clean'], (cb) => {
553 | runSequence('compile', 'test');
554 | });
555 |
556 | gulp.task('test:watch', (cb) => {
557 | return jestCli.runCLI({ config: require('./package.json').jest, watch: true }, ".").then(({ results }) => {
558 | if (!results.success) throw new Error('There are test failures!');
559 | });
560 | });
561 |
562 | gulp.task('test:watch-no-cc', (cb) => {//no coverage (useful for debugging failing tests in browser)
563 | return jestCli.runCLI({ config: require('./package.json').jest, watch: true, coverage:false }, ".").then(({ results }) => {
564 | if (!results.success) throw new Error('There are test failures!');
565 | });
566 | });
567 |
568 | /////////////////////////////////////////////////////////////////////////////
569 | // Release Tasks
570 | /////////////////////////////////////////////////////////////////////////////
571 | gulp.task('changelog', (cb) => {
572 | pump(
573 | [
574 | gulp.src('CHANGELOG.md', { buffer: false }),
575 | gulpConventionalChangelog({ preset: 'angular', releaseCount: 0 }),
576 | gulp.dest('./')
577 | ], cb);
578 | });
579 |
580 | gulp.task('github-release', (cb) => {
581 | if (!argv.ghToken && !process.env.CONVENTIONAL_GITHUB_RELEASER_TOKEN) {
582 | fancyLog(acolors.red(`You must specify a Github Token via '--ghToken' or set environment variable 'CONVENTIONAL_GITHUB_RELEASER_TOKEN' to allow releasing on Github`));
583 | throw new Error(`Missing '--ghToken' argument and environment variable 'CONVENTIONAL_GITHUB_RELEASER_TOKEN' not set`);
584 | }
585 |
586 | conventionalGithubReleaser(
587 | {
588 | type: 'oauth',
589 | token: argv.ghToken || process.env.CONVENTIONAL_GITHUB_RELEASER_TOKEN
590 | },
591 | { preset: 'angular' },
592 | cb);
593 | });
594 |
595 | gulp.task('bump-version', (cb) => {
596 | if (!argv.version) {
597 | fancyLog(acolors.red(`You must specify which version to bump to (Possible values: 'major', 'minor', and 'patch')`));
598 | throw new Error(`Missing '--version' argument`);
599 | }
600 |
601 | pump(
602 | [
603 | gulp.src('./package.json'),
604 | gulpBump({ type: argv.version }),
605 | gulp.dest('./'),
606 | ], cb);
607 | });
608 |
609 | gulp.task('commit-changes', (cb) => {
610 | let version = getPackageJsonVersion();
611 | pump(
612 | [
613 | gulp.src('.'),
614 | gulpGit.add(),
615 | gulpGit.commit(`chore(release): bump version number to ${version}`)
616 | ], cb);
617 | });
618 |
619 | gulp.task('push-changes', (cb) => {
620 | gulpGit.push('origin', 'master', cb);
621 | });
622 |
623 | gulp.task('create-new-tag', (cb) => {
624 | let version = `v${getPackageJsonVersion()}`;
625 | gulpGit.tag(version, `chore(release): :sparkles: :tada: create tag for version v${version}`, (error) => {
626 | if (error) {
627 | return cb(error);
628 | }
629 | gulpGit.push('origin', 'master', { args: '--tags' }, cb);
630 | });
631 |
632 | });
633 |
634 | // Build and then Publish 'dist' folder to NPM
635 | gulp.task('npm-publish', ['build'], () => {
636 | return execExternalCmd('npm',`publish ${config.outputDir} --access public`)
637 | });
638 |
639 | // Perfom pre-release checks (no actual release)
640 | gulp.task('pre-release', cb => {
641 | readyToRelease();
642 | cb();
643 | });
644 |
645 | gulp.task('release', (cb) => {
646 | fancyLog('# Performing Pre-Release Checks...');
647 | if (!readyToRelease()) {
648 | fancyLog(acolors.red('# Pre-Release Checks have failed. Please fix them and try again. Aborting...'));
649 | cb();
650 | }
651 | else {
652 | fancyLog(acolors.green('# Pre-Release Checks have succeeded. Continuing...'));
653 | runSequence(
654 | 'bump-version',
655 | 'changelog',
656 | 'commit-changes',
657 | 'push-changes',
658 | 'create-new-tag',
659 | 'github-release',
660 | 'npm-publish',
661 | 'deploy:demo',
662 | (error) => {
663 | if (error) {
664 | fancyLog(acolors.red(error.message));
665 | } else {
666 | fancyLog(acolors.green('RELEASE FINISHED SUCCESSFULLY'));
667 | }
668 | cb(error);
669 | });
670 | }
671 | });
672 |
673 |
674 | /////////////////////////////////////////////////////////////////////////////
675 | // Utility Tasks
676 | /////////////////////////////////////////////////////////////////////////////
677 |
678 | // Link 'dist' folder (create a local 'ng-scrollreveal' package that symlinks to it)
679 | // This way, we can have the demo project declare a dependency on 'ng-scrollreveal' (as it should)
680 | // and, thanks to 'npm link ng-scrollreveal' on demo project, be sure to always use the latest built
681 | // version of the library ( which is in 'dist/' folder)
682 | gulp.task('link', () => {
683 | return execExternalCmd('npm', 'link', { cwd: `${config.outputDir}` });
684 | });
685 |
686 | gulp.task('unlink', () => {
687 | return execExternalCmd('npm', 'unlink', { cwd: `${config.outputDir}` });
688 | });
689 |
690 | // Upload code coverage report to coveralls.io (will be triggered by Travis CI on successful build)
691 | gulp.task('coveralls', (cb) => {
692 | pump(
693 | [
694 | gulp.src(`${config.coverageDir}/lcov.info`),
695 | gulpCoveralls()
696 | ], cb);
697 | });
698 |
699 | gulp.task('default', ['build']);
700 |
701 | // Load additional tasks
702 | gulpHub(['./config/gulp-tasks/*.js']);
703 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | module.exports = require('./config/karma.conf.js');
2 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mat-markdown-editor",
3 | "description": "Material design markdown editor",
4 | "version": "0.0.8",
5 | "homepage": "https://github.com/michaeldoye/mat-markdown-editor",
6 | "author": {
7 | "name": "Michael Doye",
8 | "url": "https://github.com/michaeldoye"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git://github.com/michaeldoye/mat-markdown-editor.git"
13 | },
14 | "license": "MIT",
15 | "keywords": [
16 | "markdown",
17 | "text editor",
18 | "angular",
19 | "material design"
20 | ],
21 | "bugs": {
22 | "url": "https://github.com/michaeldoye/mat-markdown-editor/issues"
23 | },
24 | "private": true,
25 | "scripts": {
26 | "start": "gulp build",
27 | "test": " gulp test",
28 | "demo": " gulp build:demo",
29 | "check-travis": " travis-status --repo=michaeldoye/mat-markdown-editor --branch=master --fail-pending || echo 'Not yet passing'"
30 | },
31 | "dependencies": {
32 | "@angular/cdk": "^7.3.3",
33 | "@angular/common": "7.2.8",
34 | "@angular/core": "7.2.8",
35 | "@angular/flex-layout": "^7.0.0-beta.23",
36 | "@angular/forms": "^7.2.8",
37 | "@angular/material": "^7.3.3",
38 | "gh-got": "^8.1.0",
39 | "jest-cli": "^24.3.1",
40 | "tsickle": "^0.34.3"
41 | },
42 | "devDependencies": {
43 | "@angular/animations": "^7.2.8",
44 | "@angular/compiler": "7.2.8",
45 | "@angular/compiler-cli": "7.2.8",
46 | "@angular/platform-browser": "7.2.8",
47 | "@angular/platform-browser-dynamic": "7.2.8",
48 | "@angular/platform-server": "7.2.8",
49 | "@compodoc/gulp-compodoc": "0.0.10",
50 | "@types/jest": "24.0.11",
51 | "@types/lodash": "4.14.123",
52 | "@types/node": "11.11.0",
53 | "angular-cli-ghpages": "0.5.3",
54 | "angular2-template-loader": "0.6.2",
55 | "ansi-colors": "3.2.4",
56 | "autoprefixer": "9.5.0",
57 | "awesome-typescript-loader": "5.2.1",
58 | "codelyzer": "4.5.0",
59 | "commitplease": "3.2.0",
60 | "conventional-github-releaser": "^3.1.2",
61 | "core-js": "2.6.5",
62 | "css-loader": "2.1.1",
63 | "cssnano": "4.1.10",
64 | "del": "4.0.0",
65 | "fancy-log": "1.3.3",
66 | "gulp": "^3.9.1",
67 | "gulp-bump": "3.1.3",
68 | "gulp-conventional-changelog": "2.0.10",
69 | "gulp-coveralls": "0.1.4",
70 | "gulp-file": "0.4.0",
71 | "gulp-git": "2.9.0",
72 | "gulp-hub": "4.2.0",
73 | "gulp-inline-ng2-template": "5.0.1",
74 | "gulp-tslint": "8.1.4",
75 | "html-loader": "0.5.5",
76 | "jest": "24.3.1",
77 | "jest-preset-angular": "7.0.1",
78 | "lodash": "4.17.11",
79 | "node-sass": "4.11.0",
80 | "postcss": "7.0.14",
81 | "postcss-strip-inline-comments": "0.1.5",
82 | "prettier": "1.16.4",
83 | "pump": "3.0.0",
84 | "raw-loader": "1.0.0",
85 | "rollup": "0.58.2",
86 | "rollup-plugin-commonjs": "9.1.3",
87 | "rollup-plugin-node-resolve": "3.3.0",
88 | "rollup-plugin-sourcemaps": "0.4.2",
89 | "rollup-plugin-uglify": "3.0.0",
90 | "run-sequence": "2.2.1",
91 | "rxjs": "6.4.0",
92 | "sass-loader": "7.1.0",
93 | "source-map-loader": "0.2.4",
94 | "to-string-loader": "1.1.5",
95 | "travis-status": "3.0.1",
96 | "tslint": "5.13.1",
97 | "typescript": "3.1.1",
98 | "yargs": "13.2.2",
99 | "zone.js": "0.8.29"
100 | },
101 | "engines": {
102 | "node": ">=8.0.0"
103 | },
104 | "jest": {
105 | "preset": "jest-preset-angular",
106 | "roots": [
107 | "/src/"
108 | ],
109 | "coverageReporters": [
110 | "lcov",
111 | "text"
112 | ],
113 | "coveragePathIgnorePatterns": [
114 | "/node_modules/",
115 | "/config",
116 | "/dist/"
117 | ],
118 | "setupTestFrameworkScriptFile": "/config/setupJest.ts"
119 | },
120 | "greenkeeper": {
121 | "ignore": [
122 | "@angular/core",
123 | "@angular/common",
124 | "@angular/compiler",
125 | "@angular/platform-server",
126 | "@angular/platform-browser",
127 | "@angular/platform-browser-dynamic",
128 | "@angular/compiler-cli",
129 | "zone.js",
130 | "rxjs",
131 | "tslint",
132 | "gulp-tslint",
133 | "typescript",
134 | "awesome-typescript-loader",
135 | "codelyzer",
136 | "@angular/animations",
137 | "@types/jasmine",
138 | "gulp",
139 | "rollup",
140 | "rollup-plugin-commonjs",
141 | "rollup-plugin-node-resolve",
142 | "rollup-plugin-uglify"
143 | ]
144 | },
145 | "commitplease": {
146 | "style": "angular",
147 | "types": [
148 | "feat",
149 | "fix",
150 | "docs",
151 | "style",
152 | "refactor",
153 | "perf",
154 | "test",
155 | "chore",
156 | "revert",
157 | "demo"
158 | ],
159 | "scope": "\\S+.*"
160 | },
161 | "prettier": {
162 | "bracketSpacing": true,
163 | "trailingComma": "es5",
164 | "tabWidth": 2,
165 | "semi": true,
166 | "singleQuote": true,
167 | "htmlWhitespaceSensitivity": "css"
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './module/lib.module';
2 |
--------------------------------------------------------------------------------
/src/module/editor/editor.component.html:
--------------------------------------------------------------------------------
1 |
8 |
9 |
16 |
17 |
18 |
34 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/module/editor/editor.component.scss:
--------------------------------------------------------------------------------
1 | .md-editor-container {
2 | position: relative;
3 | height: 100%;
4 | margin-bottom: 15px;
5 | &.border {
6 | border: 1px solid rgba(0, 0, 0, 0.1);
7 | }
8 | &.fullscreen {
9 | margin: 0;
10 | position: fixed;
11 | border: 0;
12 | top: 0;
13 | left: 0;
14 | width: 100% !important;
15 | height: 100% !important;
16 | z-index: 99;
17 | }
18 | &.md-editor-resizable:not(.fullscreen) {
19 | resize: both;
20 | overflow: auto;
21 | display: inline-block;
22 | width: 100%;
23 | .md-footer {
24 | z-index: -1;
25 | }
26 | }
27 | .md-layout {
28 | height: 100%;
29 | display: flex;
30 | flex-direction: column;
31 | .tool-bar {
32 | .btn-group {
33 | }
34 | }
35 | .editor-container {
36 | flex: 1;
37 | display: flex;
38 | & > div {
39 | flex: 1;
40 | }
41 | .editor-panel-container {
42 | height: 100%;
43 | }
44 | .editor-panel {
45 | height: 100%;
46 | .ace-editor {
47 | height: 100%;
48 | min-height: 100%;
49 | }
50 | }
51 | }
52 | .preview-panel {
53 | .material-icons {
54 | vertical-align: top;
55 | margin-bottom: 0.2em;
56 | margin-left: -0.8em;
57 | }
58 | height: 100%;
59 | border-left: 1px solid rgba(0, 0, 0, 0.1);
60 | background-color: white;
61 | padding: 10px;
62 | overflow-y: auto;
63 | }
64 | .md-footer {
65 | .length-view {
66 | flex: 1;
67 | padding: 4px 2px 0 2px;
68 | font-size: 12px;
69 | line-height: 16px;
70 | }
71 | .resize-btn {
72 | width: 17px;
73 | }
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/module/editor/editor.component.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Component,
3 | ViewChild,
4 | forwardRef,
5 | Attribute,
6 | Input,
7 | AfterViewInit,
8 | OnInit,
9 | OnDestroy,
10 | ElementRef,
11 | } from '@angular/core';
12 | import {
13 | NG_VALUE_ACCESSOR,
14 | ControlValueAccessor,
15 | NG_VALIDATORS,
16 | Validator,
17 | AbstractControl,
18 | ValidationErrors,
19 | } from '@angular/forms';
20 | import { DomSanitizer } from '@angular/platform-browser';
21 | import { MatMarkdownEditorOptions } from '../lib.interface';
22 | import { markDownCode, markDownTable, markDownListItem } from '../utils';
23 |
24 | declare let ace: any;
25 | declare let marked: any;
26 | declare let hljs: any;
27 |
28 | @Component({
29 | // tslint:disable-next-line: component-selector
30 | selector: 'mat-markdown-editor',
31 | templateUrl: './editor.component.html',
32 | styleUrls: ['./editor.component.scss'],
33 | providers: [
34 | {
35 | provide: NG_VALUE_ACCESSOR,
36 | useExisting: forwardRef(() => MatMarkdownEditorComponent),
37 | multi: true,
38 | },
39 | {
40 | provide: NG_VALIDATORS,
41 | useExisting: forwardRef(() => MatMarkdownEditorComponent),
42 | multi: true,
43 | },
44 | ],
45 | })
46 | export class MatMarkdownEditorComponent
47 | implements ControlValueAccessor, Validator, OnInit, AfterViewInit, OnDestroy {
48 | @ViewChild('aceEditor') public aceEditorContainer: ElementRef;
49 | @Input() public options: MatMarkdownEditorOptions;
50 |
51 | public showPreviewPanel = true;
52 | public isFullScreen = false;
53 | public previewHtml: any;
54 | public editor: any;
55 |
56 | private _renderMarkTimeout: any;
57 | private _markdownValue: any;
58 | private _options: any = {};
59 | private _markedOpt: any;
60 |
61 | private _onChange = (_: any) => {};
62 | private _onTouched = () => {};
63 |
64 | public get markdownValue(): any {
65 | return this._markdownValue || '';
66 | }
67 | public set markdownValue(value: any) {
68 | this._markdownValue = value;
69 | this._onChange(value);
70 |
71 | if (this.options.preRender && this.options.preRender instanceof Function) {
72 | value = this.options.preRender(value);
73 | }
74 | if (value !== null && value !== undefined) {
75 | if (this._renderMarkTimeout) {
76 | clearTimeout(this._renderMarkTimeout);
77 | }
78 | this._renderMarkTimeout = setTimeout(() => {
79 | const html = marked(value || '', this._markedOpt);
80 | this.previewHtml = this._domSanitizer.bypassSecurityTrustHtml(html);
81 | }, 100);
82 | }
83 | }
84 |
85 | constructor(
86 | @Attribute('required') public required: boolean = false,
87 | @Attribute('maxlength') public maxlength: number = -1,
88 | private _domSanitizer: DomSanitizer
89 | ) {}
90 |
91 | ngOnInit() {
92 | const editorElement = this.aceEditorContainer.nativeElement;
93 | this.editor = ace.edit(editorElement);
94 |
95 | const markedRender = new marked.Renderer();
96 | markedRender.code = markDownCode;
97 | markedRender.table = markDownTable;
98 | markedRender.listitem = markDownListItem;
99 | const markedjsOpt = {
100 | renderer: markedRender,
101 | highlight: (code: any) => hljs.highlightAuto(code).value,
102 | };
103 | this._markedOpt = Object.assign({}, this.options.markedjsOpt, markedjsOpt);
104 | }
105 |
106 | ngAfterViewInit() {
107 | this.editor.$blockScrolling = Infinity;
108 | this.editor.getSession().setUseWrapMode(true);
109 | this.editor.getSession().setMode('ace/mode/markdown');
110 | this.editor.setValue(this.markdownValue || '', 1);
111 | this.editor.setOption('scrollPastEnd', this._options.scrollPastEnd || 0);
112 |
113 | this.editor.on('change', () => {
114 | this.markdownValue = this.editor.getValue();
115 | });
116 | }
117 |
118 | writeValue(value: any | Array): void {
119 | setTimeout(() => {
120 | this.markdownValue = value;
121 | if (typeof value !== 'undefined' && this.editor) {
122 | this.editor.setValue(value || '', 1);
123 | }
124 | }, 1);
125 | }
126 |
127 | registerOnChange(fn: (_: any) => {}): void {
128 | this._onChange = fn;
129 | }
130 |
131 | registerOnTouched(fn: () => {}): void {
132 | this._onTouched = fn;
133 | }
134 |
135 | validate(c: AbstractControl): ValidationErrors {
136 | let result: any = null;
137 | if (this.required && this.markdownValue.length === 0) {
138 | result = { required: true };
139 | }
140 | if (this.maxlength > 0 && this.markdownValue.length > this.maxlength) {
141 | result = { maxlength: true };
142 | }
143 | return result;
144 | }
145 |
146 | onTogglePreview(isOpen: boolean) {
147 | this.showPreviewPanel = isOpen;
148 | }
149 |
150 | onFullScreen(isFullScreen: boolean) {
151 | this.isFullScreen = isFullScreen;
152 | this.editor.resize();
153 | }
154 |
155 | previewPanelClick(event: Event) {
156 | if (this.options.enablePreviewContentClick !== true) {
157 | event.preventDefault();
158 | event.stopImmediatePropagation();
159 | }
160 | }
161 |
162 | ngOnDestroy() {
163 | return this.editor && this.editor.destroy();
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/src/module/editor/toolbar/toolbar.component.html:
--------------------------------------------------------------------------------
1 |
8 |
9 |
18 |
27 |
36 |
45 |
46 |
47 |
48 |
49 |
58 |
67 |
68 |
69 |
70 |
71 |
82 |
93 |
102 |
103 |
104 |
105 |
106 |
117 |
118 |
119 |
120 |
121 |
122 |
132 |
142 |
143 |
144 |
--------------------------------------------------------------------------------
/src/module/editor/toolbar/toolbar.component.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaeldoye/mat-markdown-editor/229a4b1c6d6876987d421b98e737688210c95a6c/src/module/editor/toolbar/toolbar.component.scss
--------------------------------------------------------------------------------
/src/module/editor/toolbar/toolbar.component.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Component,
3 | Input,
4 | Output,
5 | EventEmitter,
6 | Renderer2,
7 | } from '@angular/core';
8 |
9 | @Component({
10 | // tslint:disable-next-line: component-selector
11 | selector: 'mat-markdown-editor-toolbar',
12 | templateUrl: './toolbar.component.html',
13 | styleUrls: ['./toolbar.component.scss'],
14 | })
15 | export class EditorToolbarComponent {
16 | @Input() public options: any;
17 | @Input() public isFullScreen: boolean;
18 | @Input() private editor: any;
19 | @Output() public onTogglePreview = new EventEmitter();
20 | @Output() public onFullScreen = new EventEmitter();
21 |
22 | public previewIsOpen = true;
23 | private _editorResizeTimer: any;
24 |
25 | constructor(private _renderer: Renderer2) {}
26 |
27 | insertContent(type: string, customContent?: string) {
28 | if (!this.editor) {
29 | return;
30 | }
31 | let selectedText = this.editor.getSelectedText();
32 | let startSize = 2;
33 | let initText = '';
34 | const isSelected = !!selectedText;
35 | const range = this.editor.selection.getRange();
36 | switch (type) {
37 | case 'Bold':
38 | initText = 'Bold Text';
39 | selectedText = `**${selectedText || initText}**`;
40 | break;
41 | case 'Italic':
42 | initText = 'Italic Text';
43 | selectedText = `*${selectedText || initText}*`;
44 | startSize = 1;
45 | break;
46 | case 'Heading':
47 | initText = 'Heading';
48 | selectedText = `# ${selectedText || initText}`;
49 | break;
50 | case 'Reference':
51 | initText = 'Reference';
52 | selectedText = `> ${selectedText || initText}`;
53 | break;
54 | case 'Link':
55 | selectedText = `[${selectedText}](http://)`;
56 | startSize = 1;
57 | break;
58 | case 'Image':
59 | selectedText = ``;
60 | break;
61 | case 'Ul':
62 | selectedText = `- ${selectedText || initText}`;
63 | break;
64 | case 'Ol':
65 | selectedText = `1. ${selectedText || initText}`;
66 | startSize = 3;
67 | break;
68 | case 'Code':
69 | initText = 'Source Code';
70 | selectedText =
71 | '```language\r\n' + (selectedText || initText) + '\r\n```';
72 | startSize = 3;
73 | break;
74 | case 'Custom':
75 | selectedText = customContent;
76 | startSize = 0;
77 | break;
78 | }
79 | this.editor.session.replace(range, selectedText);
80 | if (!isSelected) {
81 | range.start.column += startSize;
82 | range.end.column = range.start.column + initText.length;
83 | this.editor.selection.setRange(range);
84 | }
85 | this.editor.focus();
86 | }
87 |
88 | togglePreview() {
89 | this.previewIsOpen = !this.previewIsOpen;
90 | this.onTogglePreview.emit(this.previewIsOpen);
91 | this.editorResize();
92 | }
93 |
94 | fullScreen() {
95 | this.isFullScreen = !this.isFullScreen;
96 | this._renderer.setStyle(
97 | document.body,
98 | 'overflowY',
99 | this.isFullScreen ? 'hidden' : 'auto'
100 | );
101 | this.onFullScreen.emit(this.isFullScreen);
102 | this.editorResize();
103 | }
104 |
105 | editorResize(timeOut: number = 100) {
106 | if (!this.editor) {
107 | return;
108 | }
109 | if (this._editorResizeTimer) {
110 | clearTimeout(this._editorResizeTimer);
111 | }
112 | this._editorResizeTimer = setTimeout(() => {
113 | this.editor.resize();
114 | this.editor.focus();
115 | }, timeOut);
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/src/module/lib.interface.ts:
--------------------------------------------------------------------------------
1 | export interface MatMarkdownEditorOptions {
2 | showBorder?: boolean; // Show editor component's border
3 | // tslint:disable-next-line: max-line-length
4 | hideIcons?: object; // ['Bold', 'Italic', 'Heading', 'Reference', 'Link', 'Image', 'Ul', 'Ol', 'Code', 'TogglePreview', 'FullScreen'], Default is empty
5 | scrollPastEnd?: number; // The option for ace editor
6 | enablePreviewContentClick?: boolean; // Allow user fire the click event on the preview panel, like href etc.
7 | resizable?: boolean; // Allow resize the editor
8 | markedjsOpt?: MarkedjsOption; // The markedjs option, see https://marked.js.org/#/USING_ADVANCED.md#options
9 | hideToolbar?: boolean;
10 | height?: string;
11 | mode?: string;
12 | preRender?: Function;
13 | toolbarColor?: string;
14 | }
15 |
16 | export interface MarkedjsOption {
17 | baseUrl?: string; // Default null
18 | breaks?: boolean; // Default false
19 | gfm?: boolean; // Default true
20 | headerIds?: boolean; // Default true
21 | headerPrefix?: string; // Default ''
22 | langPrefix?: string; // Default 'language-'
23 | mangle?: boolean; // Default true
24 | pedantic?: boolean; // Default false
25 | sanitize?: boolean; // Default false
26 | sanitizer?: Function; // Default null
27 | silent?: boolean; // Default false
28 | smartLists?: boolean; // Default false
29 | smartypants?: boolean; // Default false
30 | tables?: boolean; // Default true
31 | xhtml?: boolean; // Default false
32 | }
33 |
--------------------------------------------------------------------------------
/src/module/lib.module.ts:
--------------------------------------------------------------------------------
1 | import { CommonModule } from '@angular/common';
2 | import { NgModule, ModuleWithProviders } from '@angular/core';
3 | import { FormsModule, ReactiveFormsModule } from '@angular/forms';
4 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
5 |
6 | import { MatMarkdownEditorComponent } from './editor/editor.component';
7 | import { LibService } from './service/lib.service';
8 | import { MaterialModule } from './material.module';
9 | import { FlexLayoutModule } from '@angular/flex-layout';
10 | import { EditorToolbarComponent } from './editor/toolbar/toolbar.component';
11 |
12 | export { MatMarkdownEditorComponent } from './editor/editor.component';
13 | export { LibService } from './service/lib.service';
14 | export { MatMarkdownEditorOptions, MarkedjsOption } from './lib.interface';
15 |
16 | @NgModule({
17 | imports: [
18 | CommonModule,
19 | FormsModule,
20 | MaterialModule,
21 | ReactiveFormsModule,
22 | BrowserAnimationsModule,
23 | FlexLayoutModule,
24 | ],
25 | exports: [MatMarkdownEditorComponent],
26 | declarations: [MatMarkdownEditorComponent, EditorToolbarComponent],
27 | })
28 | export class MatMarkdownEditorModule {
29 | static forRoot(): ModuleWithProviders {
30 | return {
31 | ngModule: MatMarkdownEditorModule,
32 | providers: [LibService],
33 | };
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/module/material.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import {
3 | MatAutocompleteModule,
4 | MatButtonModule,
5 | MatButtonToggleModule,
6 | MatCardModule,
7 | MatCheckboxModule,
8 | MatChipsModule,
9 | MatDatepickerModule,
10 | MatDialogModule,
11 | MatExpansionModule,
12 | MatGridListModule,
13 | MatIconModule,
14 | MatInputModule,
15 | MatListModule,
16 | MatMenuModule,
17 | MatNativeDateModule,
18 | MatPaginatorModule,
19 | MatProgressBarModule,
20 | MatProgressSpinnerModule,
21 | MatRadioModule,
22 | MatRippleModule,
23 | MatSelectModule,
24 | MatSidenavModule,
25 | MatSliderModule,
26 | MatSlideToggleModule,
27 | MatSnackBarModule,
28 | MatSortModule,
29 | MatTableModule,
30 | MatTabsModule,
31 | MatToolbarModule,
32 | MatTooltipModule,
33 | MatStepperModule,
34 | } from '@angular/material';
35 |
36 | @NgModule({
37 | imports: [
38 | MatAutocompleteModule,
39 | MatButtonModule,
40 | MatButtonToggleModule,
41 | MatCardModule,
42 | MatCheckboxModule,
43 | MatChipsModule,
44 | MatStepperModule,
45 | MatDatepickerModule,
46 | MatDialogModule,
47 | MatExpansionModule,
48 | MatGridListModule,
49 | MatIconModule,
50 | MatInputModule,
51 | MatListModule,
52 | MatMenuModule,
53 | MatNativeDateModule,
54 | MatPaginatorModule,
55 | MatProgressBarModule,
56 | MatProgressSpinnerModule,
57 | MatRadioModule,
58 | MatRippleModule,
59 | MatSelectModule,
60 | MatSidenavModule,
61 | MatSliderModule,
62 | MatSlideToggleModule,
63 | MatSnackBarModule,
64 | MatSortModule,
65 | MatTableModule,
66 | MatTabsModule,
67 | MatToolbarModule,
68 | MatTooltipModule,
69 | ],
70 | exports: [
71 | MatAutocompleteModule,
72 | MatButtonModule,
73 | MatButtonToggleModule,
74 | MatCardModule,
75 | MatCheckboxModule,
76 | MatChipsModule,
77 | MatStepperModule,
78 | MatDatepickerModule,
79 | MatDialogModule,
80 | MatExpansionModule,
81 | MatGridListModule,
82 | MatIconModule,
83 | MatInputModule,
84 | MatListModule,
85 | MatMenuModule,
86 | MatNativeDateModule,
87 | MatPaginatorModule,
88 | MatProgressBarModule,
89 | MatProgressSpinnerModule,
90 | MatRadioModule,
91 | MatRippleModule,
92 | MatSelectModule,
93 | MatSidenavModule,
94 | MatSliderModule,
95 | MatSlideToggleModule,
96 | MatSnackBarModule,
97 | MatSortModule,
98 | MatTableModule,
99 | MatTabsModule,
100 | MatToolbarModule,
101 | MatTooltipModule,
102 | ],
103 | })
104 | export class MaterialModule {}
105 |
--------------------------------------------------------------------------------
/src/module/service/lib.service.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed, inject } from '@angular/core/testing';
2 |
3 | import { LibService } from './lib.service';
4 |
5 | describe('LibService', () => {
6 | beforeEach(() => {
7 | TestBed.configureTestingModule({
8 | providers: [LibService]
9 | });
10 | });
11 |
12 | it('should create service', inject([LibService], (service: LibService) => {
13 | expect(service).toBeTruthy();
14 | }));
15 |
16 | it('should say hello to stranger', inject([LibService], (service: LibService) => {
17 | expect(service.sayHello()).toBe('Hello Stanger!');
18 | }));
19 |
20 | it('should say hello to provided user', inject([LibService], (service: LibService) => {
21 | expect(service.sayHello('ng-hacker')).toBe('Hello ng-hacker!');
22 | }));
23 | });
24 |
--------------------------------------------------------------------------------
/src/module/service/lib.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 |
3 | @Injectable()
4 | export class LibService {
5 | constructor() { }
6 | sayHello(name?: string) {
7 | return `Hello ${name || 'Stanger'}!`;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/module/utils/index.ts:
--------------------------------------------------------------------------------
1 | declare let hljs: any;
2 |
3 | export function markDownListItem(text: string): string {
4 | if (!/^\s*\[[x ]]\s*/.test(text)) {
5 | return `${text}`;
6 | } else {
7 | text = text
8 | .replace(
9 | /^\s*\[ ]\s*/,
10 | 'check_box_outline_blank '
11 | )
12 | .replace(
13 | /^\s*\[x]\s*/,
14 | 'check_box '
15 | );
16 | return `${text}`;
17 | }
18 | }
19 |
20 | export function markDownTable(header: string, body: string): string {
21 | return `\n\n${header}\n\n${body}\n
\n`;
22 | }
23 |
24 | export function markDownCode(code: any, language: any): string {
25 | const validLang = !!(language && hljs.getLanguage(language));
26 | const highlighted = validLang ? hljs.highlight(language, code).value : code;
27 | return `${highlighted}
`;
28 | }
29 |
--------------------------------------------------------------------------------
/src/tsconfig.lib.es5.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.lib.json",
3 | "compilerOptions": {
4 | "target": "es5",
5 | "outDir": "../tmp/lib-es5/",
6 | "baseUrl": "",
7 | "types": []
8 | },
9 | "files": [
10 | "./index.ts"
11 | ],
12 | "angularCompilerOptions": {
13 | "strictMetadataEmit": true,
14 | "skipTemplateCodegen": true,
15 | "genDir": "../tmp/lib-gen-dir/",
16 | "flatModuleOutFile": "mat-markdown-editor.js",
17 | "flatModuleId": "mat-markdown-editor",
18 | "annotateForClosureCompiler": true
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../tmp/lib-es2015/",
5 | "target": "es2015",
6 | "rootDir": "./",
7 | "baseUrl": "",
8 | "types": [ "node"]
9 | },
10 | "files": [
11 | "./index.ts"
12 | ],
13 | "angularCompilerOptions": {
14 | "strictMetadataEmit": true,
15 | "skipTemplateCodegen": true,
16 | "genDir": "../tmp/lib-gen-dir/",
17 | "flatModuleOutFile": "mat-markdown-editor.js",
18 | "flatModuleId": "mat-markdown-editor",
19 | "annotateForClosureCompiler": true
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "baseUrl": "",
5 | "module": "commonjs",
6 | "declaration": false,
7 | "emitDecoratorMetadata": true,
8 | "typeRoots": [
9 | "../node_modules/@types"
10 | ]
11 | },
12 | "awesomeTypescriptLoaderOptions": {
13 | "useWebpackText": true
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "es2015",
5 | "moduleResolution": "node",
6 | "sourceMap": true,
7 | "inlineSources": true,
8 | "declaration": true,
9 | "experimentalDecorators": true,
10 | "noImplicitAny": true,
11 | "suppressImplicitAnyIndexErrors": true,
12 | "skipLibCheck": true,
13 | "stripInternal": true,
14 | "lib": [
15 | "es2015",
16 | "dom"
17 | ]
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rulesDirectory": [
3 | "node_modules/codelyzer"
4 | ],
5 | "rules": {
6 | "arrow-return-shorthand": true,
7 | "callable-types": true,
8 | "class-name": true,
9 | "comment-format": [
10 | true,
11 | "check-space"
12 | ],
13 | "curly": true,
14 | "eofline": true,
15 | "forin": true,
16 | "import-blacklist": [
17 | true,
18 | "rxjs"
19 | ],
20 | "import-spacing": true,
21 | "indent": [
22 | true,
23 | "spaces"
24 | ],
25 | "interface-over-type-literal": true,
26 | "label-position": true,
27 | "max-line-length": [
28 | true,
29 | 140
30 | ],
31 | "member-access": false,
32 | "member-ordering": [
33 | true,
34 | "static-before-instance",
35 | "variables-before-functions"
36 | ],
37 | "no-arg": true,
38 | "no-bitwise": true,
39 | "no-console": [
40 | true,
41 | "debug",
42 | "info",
43 | "time",
44 | "timeEnd",
45 | "trace"
46 | ],
47 | "no-construct": true,
48 | "no-debugger": true,
49 | "no-duplicate-super": true,
50 | "no-empty": false,
51 | "no-empty-interface": true,
52 | "no-eval": true,
53 | "no-inferrable-types": [
54 | true,
55 | "ignore-params"
56 | ],
57 | "no-misused-new": true,
58 | "no-non-null-assertion": true,
59 | "no-shadowed-variable": true,
60 | "no-string-literal": false,
61 | "no-string-throw": true,
62 | "no-switch-case-fall-through": true,
63 | "no-trailing-whitespace": true,
64 | "no-unnecessary-initializer": true,
65 | "no-unused-expression": true,
66 | "no-use-before-declare": true,
67 | "no-var-keyword": true,
68 | "object-literal-sort-keys": false,
69 | "one-line": [
70 | true,
71 | "check-open-brace",
72 | "check-catch",
73 | "check-else",
74 | "check-whitespace"
75 | ],
76 | "prefer-const": true,
77 | "quotemark": [
78 | true,
79 | "single"
80 | ],
81 | "radix": true,
82 | "semicolon": [
83 | "always"
84 | ],
85 | "triple-equals": [
86 | true,
87 | "allow-null-check"
88 | ],
89 | "typedef-whitespace": [
90 | true,
91 | {
92 | "call-signature": "nospace",
93 | "index-signature": "nospace",
94 | "parameter": "nospace",
95 | "property-declaration": "nospace",
96 | "variable-declaration": "nospace"
97 | }
98 | ],
99 | "unified-signatures": true,
100 | "variable-name": false,
101 | "whitespace": [
102 | true,
103 | "check-branch",
104 | "check-decl",
105 | "check-operator",
106 | "check-separator",
107 | "check-type"
108 | ],
109 | "directive-selector": [
110 | true,
111 | "attribute",
112 | "ngx-mde",
113 | "camelCase"
114 | ],
115 | "component-selector": [
116 | true,
117 | "element",
118 | "ngx-mde",
119 | "kebab-case"
120 | ],
121 | "use-input-property-decorator": true,
122 | "use-output-property-decorator": true,
123 | "use-host-property-decorator": true,
124 | "no-input-rename": true,
125 | "no-output-rename": true,
126 | "use-life-cycle-interface": true,
127 | "use-pipe-transform-interface": true,
128 | "component-class-suffix": true,
129 | "directive-class-suffix": true
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | module.exports = require('./config/webpack.test.js');
2 |
--------------------------------------------------------------------------------