Markdown parsing, and code highlighting!
This commit is contained in:
parent
3e4e634ea3
commit
6027b82336
13
gulpfile.js
13
gulpfile.js
@ -32,6 +32,7 @@ let gulp = require('gulp'),
|
|||||||
scss_base: 'node_modules/scss-base/src',
|
scss_base: 'node_modules/scss-base/src',
|
||||||
chartist: 'node_modules/chartist/dist/scss',
|
chartist: 'node_modules/chartist/dist/scss',
|
||||||
normalize: require('node-normalize-scss').includePaths,
|
normalize: require('node-normalize-scss').includePaths,
|
||||||
|
hljs: 'node_modules/highlight.js/styles',
|
||||||
|
|
||||||
tests_app: 'test/app/**/*.spec.js',
|
tests_app: 'test/app/**/*.spec.js',
|
||||||
tests_api: 'test/api/**/*.php',
|
tests_api: 'test/api/**/*.php',
|
||||||
@ -151,18 +152,20 @@ gulp.task('system-build', ['tsc'], () => {
|
|||||||
.then(() => del('build'));
|
.then(() => del('build'));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('minify', () => {
|
gulp.task('minify-js', () => {
|
||||||
let js = gulp.src('dist/js/**/*.js')
|
return gulp.src('dist/js/**/*.js')
|
||||||
.pipe(jsMinify())
|
.pipe(jsMinify())
|
||||||
.pipe(gulp.dest('dist/js/'));
|
.pipe(gulp.dest('dist/js/'));
|
||||||
|
});
|
||||||
|
|
||||||
let css = gulp.src('dist/css/styles.css')
|
gulp.task('minify-css', () => {
|
||||||
|
return gulp.src('dist/css/styles.css')
|
||||||
.pipe(cssMinify())
|
.pipe(cssMinify())
|
||||||
.pipe(gulp.dest('dist/css/'));
|
.pipe(gulp.dest('dist/css/'));
|
||||||
|
|
||||||
return merge(js, css);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
gulp.task('minify', ['minify-js', 'minify-css']);
|
||||||
|
|
||||||
gulp.task('composer', () => {
|
gulp.task('composer', () => {
|
||||||
return composer({
|
return composer({
|
||||||
'working-dir': 'src/api'
|
'working-dir': 'src/api'
|
||||||
|
@ -37,6 +37,8 @@
|
|||||||
"@angular/router": "4.1.0",
|
"@angular/router": "4.1.0",
|
||||||
"@types/chartist": "^0.9.34",
|
"@types/chartist": "^0.9.34",
|
||||||
"@types/core-js": "^0.9.41",
|
"@types/core-js": "^0.9.41",
|
||||||
|
"@types/highlight.js": "^9.1.9",
|
||||||
|
"@types/marked": "0.0.28",
|
||||||
"bourbon": "^4.3.4",
|
"bourbon": "^4.3.4",
|
||||||
"bourbon-neat": "^1.8.0",
|
"bourbon-neat": "^1.8.0",
|
||||||
"chai": "^3.5.0",
|
"chai": "^3.5.0",
|
||||||
@ -63,6 +65,8 @@
|
|||||||
"gulp-typescript": "^3.1.6",
|
"gulp-typescript": "^3.1.6",
|
||||||
"gulp-uglify": "^2.1.2",
|
"gulp-uglify": "^2.1.2",
|
||||||
"gulp-util": "^3.0.8",
|
"gulp-util": "^3.0.8",
|
||||||
|
"highlight.js": "^9.11.0",
|
||||||
|
"marked": "^0.3.6",
|
||||||
"merge-stream": "^1.0.1",
|
"merge-stream": "^1.0.1",
|
||||||
"mock-browser": "^0.92.14",
|
"mock-browser": "^0.92.14",
|
||||||
"ng2-dragula": "^1.3.1",
|
"ng2-dragula": "^1.3.1",
|
||||||
|
@ -121,6 +121,7 @@ export class BoardDisplay implements OnInit {
|
|||||||
|
|
||||||
private updateActiveBoard(): void {
|
private updateActiveBoard(): void {
|
||||||
if (!this.boardNavId || !this.boards) {
|
if (!this.boardNavId || !this.boards) {
|
||||||
|
this.activeBoard = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,9 +11,7 @@
|
|||||||
<span *ngIf="taskData.points > 0" class="badge right" title="Points">
|
<span *ngIf="taskData.points > 0" class="badge right" title="Points">
|
||||||
{{ taskData.points }}</span>
|
{{ taskData.points }}</span>
|
||||||
</h4>
|
</h4>
|
||||||
<div class="description">
|
<div class="description" [innerHTML]="getTaskDescription()"></div>
|
||||||
{{ taskData.description }}
|
|
||||||
</div>
|
|
||||||
<div class="hidden">
|
<div class="hidden">
|
||||||
<pre>{{ taskData | json }}</pre>
|
<pre>{{ taskData | json }}</pre>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
import { Component, Input } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
|
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
||||||
|
|
||||||
|
import * as Marked from 'marked';
|
||||||
|
import * as hljs from 'highlight.js';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Task,
|
Task,
|
||||||
@ -15,10 +19,18 @@ export class TaskDisplay {
|
|||||||
|
|
||||||
@Input('task') taskData: Task;
|
@Input('task') taskData: Task;
|
||||||
|
|
||||||
constructor(auth: AuthService) {
|
constructor(private auth: AuthService,
|
||||||
|
private sanitizer: DomSanitizer) {
|
||||||
auth.userChanged.subscribe(() => {
|
auth.userChanged.subscribe(() => {
|
||||||
this.userOptions = auth.userOptions;
|
this.userOptions = auth.userOptions;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.initMarked();
|
||||||
|
}
|
||||||
|
|
||||||
|
getTaskDescription(): SafeHtml {
|
||||||
|
return this.sanitizer.bypassSecurityTrustHtml(
|
||||||
|
Marked(this.taskData.description));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expects a color in full HEX with leading #, e.g. #ffffe0
|
// Expects a color in full HEX with leading #, e.g. #ffffe0
|
||||||
@ -28,7 +40,44 @@ export class TaskDisplay {
|
|||||||
b = parseInt(color.substr(5, 2), 16),
|
b = parseInt(color.substr(5, 2), 16),
|
||||||
yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
|
yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
|
||||||
|
|
||||||
return yiq >= 130 ? '#333333' : '#efefef';
|
return yiq >= 140 ? '#333333' : '#efefef';
|
||||||
|
}
|
||||||
|
|
||||||
|
private initMarked() {
|
||||||
|
let renderer = new Marked.Renderer();
|
||||||
|
|
||||||
|
renderer.listitem = text => {
|
||||||
|
if (/^\s*\[[x ]\]\s*/.test(text)) {
|
||||||
|
text = text
|
||||||
|
.replace(/^\s*\[ \]\s*/,
|
||||||
|
'<i class="icon icon-check-empty" style="margin-right:-4px"></i> ')
|
||||||
|
.replace(/^\s*\[x\]\s*/,
|
||||||
|
'<i class="icon icon-check" style="margin-right:-4px"></i> ');
|
||||||
|
return '<li style="list-style: none; margin-left: -27px;">' + text + '</li>';
|
||||||
|
} else {
|
||||||
|
return '<li>' + text + '</li>';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
renderer.link = (href, title, text) => {
|
||||||
|
let out = '<a href="' + href + '"';
|
||||||
|
|
||||||
|
if (title) {
|
||||||
|
out += ' title="' + title + '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
out += ' target="tb_external">' + text + '</a>';
|
||||||
|
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
|
Marked.setOptions({
|
||||||
|
renderer,
|
||||||
|
smartypants: true,
|
||||||
|
highlight: code => {
|
||||||
|
return hljs.highlightAuto(code).value;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,6 +131,18 @@
|
|||||||
"css": "resize-vertical",
|
"css": "resize-vertical",
|
||||||
"code": 59409,
|
"code": 59409,
|
||||||
"src": "fontawesome"
|
"src": "fontawesome"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": "dd6c6b221a1088ff8a9b9cd32d0b3dd5",
|
||||||
|
"css": "check",
|
||||||
|
"code": 59410,
|
||||||
|
"src": "fontawesome"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": "4b900d04e8ab8c82f080c1cfbac5772c",
|
||||||
|
"css": "check-empty",
|
||||||
|
"code": 61590,
|
||||||
|
"src": "fontawesome"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
Binary file not shown.
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" standalone="no"?>
|
<?xml version="1.0" standalone="no"?>
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg">
|
<svg xmlns="http://www.w3.org/2000/svg">
|
||||||
<metadata>Copyright (C) 2016 by original authors @ fontello.com</metadata>
|
<metadata>Copyright (C) 2017 by original authors @ fontello.com</metadata>
|
||||||
<defs>
|
<defs>
|
||||||
<font id="fontello" horiz-adv-x="1000" >
|
<font id="fontello" horiz-adv-x="1000" >
|
||||||
<font-face font-family="fontello" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
|
<font-face font-family="fontello" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
|
||||||
@ -42,6 +42,10 @@
|
|||||||
|
|
||||||
<glyph glyph-name="resize-vertical" unicode="" d="M393 671q0-14-11-25t-25-10h-71v-572h71q15 0 25-10t11-25-11-25l-143-143q-10-11-25-11t-25 11l-143 143q-10 10-10 25t10 25 25 10h72v572h-72q-14 0-25 10t-10 25 10 26l143 142q11 11 25 11t25-11l143-142q11-11 11-26z" horiz-adv-x="428.6" />
|
<glyph glyph-name="resize-vertical" unicode="" d="M393 671q0-14-11-25t-25-10h-71v-572h71q15 0 25-10t11-25-11-25l-143-143q-10-11-25-11t-25 11l-143 143q-10 10-10 25t10 25 25 10h72v572h-72q-14 0-25 10t-10 25 10 26l143 142q11 11 25 11t25-11l143-142q11-11 11-26z" horiz-adv-x="428.6" />
|
||||||
|
|
||||||
|
<glyph glyph-name="check" unicode="" d="M786 331v-177q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h464q35 0 65-14 9-4 10-13 2-10-5-16l-27-28q-6-5-13-5-1 0-5 1-13 3-25 3h-464q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63v141q0 8 5 13l36 35q6 6 13 6 3 0 7-2 11-4 11-16z m129 273l-455-454q-13-14-31-14t-32 14l-240 240q-14 13-14 31t14 32l61 62q14 13 32 13t32-13l147-147 361 361q13 13 31 13t32-13l62-61q13-14 13-32t-13-32z" horiz-adv-x="928.6" />
|
||||||
|
|
||||||
|
<glyph glyph-name="check-empty" unicode="" d="M625 707h-464q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63v464q0 37-26 63t-63 26z m161-89v-464q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h464q66 0 114-48t47-113z" horiz-adv-x="785.7" />
|
||||||
|
|
||||||
<glyph glyph-name="minus-squared-alt" unicode="" d="M643 404v-36q0-8-5-13t-13-5h-464q-8 0-13 5t-5 13v36q0 7 5 12t13 5h464q8 0 13-5t5-12z m71-250v464q0 37-26 63t-63 26h-464q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63z m72 464v-464q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h464q66 0 114-48t47-113z" horiz-adv-x="785.7" />
|
<glyph glyph-name="minus-squared-alt" unicode="" d="M643 404v-36q0-8-5-13t-13-5h-464q-8 0-13 5t-5 13v36q0 7 5 12t13 5h464q8 0 13-5t5-12z m71-250v464q0 37-26 63t-63 26h-464q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63z m72 464v-464q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h464q66 0 114-48t47-113z" horiz-adv-x="785.7" />
|
||||||
|
|
||||||
<glyph glyph-name="plus-squared-alt" unicode="" d="M643 404v-36q0-8-5-13t-13-5h-196v-196q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v196h-196q-8 0-13 5t-5 13v36q0 7 5 12t13 5h196v197q0 8 5 13t13 5h36q8 0 13-5t5-13v-197h196q8 0 13-5t5-12z m71-250v464q0 37-26 63t-63 26h-464q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63z m72 464v-464q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h464q66 0 114-48t47-113z" horiz-adv-x="785.7" />
|
<glyph glyph-name="plus-squared-alt" unicode="" d="M643 404v-36q0-8-5-13t-13-5h-196v-196q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v196h-196q-8 0-13 5t-5 13v36q0 7 5 12t13 5h196v197q0 8 5 13t13 5h36q8 0 13-5t5-13v-197h196q8 0 13-5t5-12z m71-250v464q0 37-26 63t-63 26h-464q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63z m72 464v-464q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h464q66 0 114-48t47-113z" horiz-adv-x="785.7" />
|
||||||
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 10 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -151,12 +151,18 @@
|
|||||||
padding: 0 5px 2px;
|
padding: 0 5px 2px;
|
||||||
|
|
||||||
.badge {
|
.badge {
|
||||||
font-size: .5em;
|
font-size: .6em;
|
||||||
margin-right: -2px;
|
margin-right: -2px;
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
background-color: #1d1f21;
|
||||||
|
border: 0;
|
||||||
|
color: #c5c8c6;
|
||||||
|
}
|
||||||
|
|
||||||
.description {
|
.description {
|
||||||
max-height: 12em;
|
max-height: 12em;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
@ -44,6 +44,16 @@
|
|||||||
.icon-plus-squared-alt::before { content: '\f196'; }
|
.icon-plus-squared-alt::before { content: '\f196'; }
|
||||||
.icon-eyedropper::before { content: '\f1fb'; }
|
.icon-eyedropper::before { content: '\f1fb'; }
|
||||||
|
|
||||||
|
.icon-check:before {
|
||||||
|
content: '\e812';
|
||||||
|
margin-left: -6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-check-empty:before {
|
||||||
|
content: '\f096';
|
||||||
|
margin-left: -8px;
|
||||||
|
}
|
||||||
|
|
||||||
.icon-help-circled {
|
.icon-help-circled {
|
||||||
cursor: help;
|
cursor: help;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,9 @@
|
|||||||
// dragula
|
// dragula
|
||||||
@import '../../node_modules/dragula/dist/dragula.css';
|
@import '../../node_modules/dragula/dist/dragula.css';
|
||||||
|
|
||||||
|
// highlight.js
|
||||||
|
@import '../../node_modules/highlight.js/styles/tomorrow-night-eighties.css';
|
||||||
|
|
||||||
// Local styles
|
// Local styles
|
||||||
@import 'core';
|
@import 'core';
|
||||||
@import 'login';
|
@import 'login';
|
||||||
|
@ -8,13 +8,16 @@
|
|||||||
'rxjs': 'node_modules/rxjs',
|
'rxjs': 'node_modules/rxjs',
|
||||||
'@angular': 'node_modules/@angular',
|
'@angular': 'node_modules/@angular',
|
||||||
|
|
||||||
'chartist': 'node_modules/chartist/dist/chartist.js'
|
'chartist': 'node_modules/chartist/dist/chartist.js',
|
||||||
|
'marked': 'node_modules/marked/lib/marked.js',
|
||||||
|
'highlight.js': 'node_modules/highlight.js/lib'
|
||||||
};
|
};
|
||||||
|
|
||||||
var packages = {
|
var packages = {
|
||||||
'app': { main: 'main.js', defaultExtension: 'js' },
|
'app': { main: 'main.js', defaultExtension: 'js' },
|
||||||
'rxjs': { defaultExtension: 'js' },
|
'rxjs': { defaultExtension: 'js' },
|
||||||
'ng2-dragula': { defaultExtension: 'js' }
|
'ng2-dragula': { defaultExtension: 'js' },
|
||||||
|
'highlight.js': { main: 'index.js', defaultExtension: 'js' }
|
||||||
};
|
};
|
||||||
|
|
||||||
var angularPackages = [
|
var angularPackages = [
|
||||||
|
@ -11,7 +11,12 @@
|
|||||||
"suppressImplicitAnyIndexErrors": true,
|
"suppressImplicitAnyIndexErrors": true,
|
||||||
"lib": [ "es2015", "dom" ],
|
"lib": [ "es2015", "dom" ],
|
||||||
"typeRoots": [ "node_modules/@types" ],
|
"typeRoots": [ "node_modules/@types" ],
|
||||||
"types": [ "chartist", "core-js" ]
|
"types": [
|
||||||
|
"chartist",
|
||||||
|
"core-js",
|
||||||
|
"marked",
|
||||||
|
"highlight.js"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user