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',
|
||||
chartist: 'node_modules/chartist/dist/scss',
|
||||
normalize: require('node-normalize-scss').includePaths,
|
||||
hljs: 'node_modules/highlight.js/styles',
|
||||
|
||||
tests_app: 'test/app/**/*.spec.js',
|
||||
tests_api: 'test/api/**/*.php',
|
||||
@ -151,18 +152,20 @@ gulp.task('system-build', ['tsc'], () => {
|
||||
.then(() => del('build'));
|
||||
});
|
||||
|
||||
gulp.task('minify', () => {
|
||||
let js = gulp.src('dist/js/**/*.js')
|
||||
gulp.task('minify-js', () => {
|
||||
return gulp.src('dist/js/**/*.js')
|
||||
.pipe(jsMinify())
|
||||
.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(gulp.dest('dist/css/'));
|
||||
|
||||
return merge(js, css);
|
||||
});
|
||||
|
||||
gulp.task('minify', ['minify-js', 'minify-css']);
|
||||
|
||||
gulp.task('composer', () => {
|
||||
return composer({
|
||||
'working-dir': 'src/api'
|
||||
|
@ -37,6 +37,8 @@
|
||||
"@angular/router": "4.1.0",
|
||||
"@types/chartist": "^0.9.34",
|
||||
"@types/core-js": "^0.9.41",
|
||||
"@types/highlight.js": "^9.1.9",
|
||||
"@types/marked": "0.0.28",
|
||||
"bourbon": "^4.3.4",
|
||||
"bourbon-neat": "^1.8.0",
|
||||
"chai": "^3.5.0",
|
||||
@ -63,6 +65,8 @@
|
||||
"gulp-typescript": "^3.1.6",
|
||||
"gulp-uglify": "^2.1.2",
|
||||
"gulp-util": "^3.0.8",
|
||||
"highlight.js": "^9.11.0",
|
||||
"marked": "^0.3.6",
|
||||
"merge-stream": "^1.0.1",
|
||||
"mock-browser": "^0.92.14",
|
||||
"ng2-dragula": "^1.3.1",
|
||||
|
@ -121,6 +121,7 @@ export class BoardDisplay implements OnInit {
|
||||
|
||||
private updateActiveBoard(): void {
|
||||
if (!this.boardNavId || !this.boards) {
|
||||
this.activeBoard = null;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -11,9 +11,7 @@
|
||||
<span *ngIf="taskData.points > 0" class="badge right" title="Points">
|
||||
{{ taskData.points }}</span>
|
||||
</h4>
|
||||
<div class="description">
|
||||
{{ taskData.description }}
|
||||
</div>
|
||||
<div class="description" [innerHTML]="getTaskDescription()"></div>
|
||||
<div class="hidden">
|
||||
<pre>{{ taskData | json }}</pre>
|
||||
</div>
|
||||
|
@ -1,4 +1,8 @@
|
||||
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 {
|
||||
Task,
|
||||
@ -15,10 +19,18 @@ export class TaskDisplay {
|
||||
|
||||
@Input('task') taskData: Task;
|
||||
|
||||
constructor(auth: AuthService) {
|
||||
constructor(private auth: AuthService,
|
||||
private sanitizer: DomSanitizer) {
|
||||
auth.userChanged.subscribe(() => {
|
||||
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
|
||||
@ -28,7 +40,44 @@ export class TaskDisplay {
|
||||
b = parseInt(color.substr(5, 2), 16),
|
||||
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",
|
||||
"code": 59409,
|
||||
"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"?>
|
||||
<!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">
|
||||
<metadata>Copyright (C) 2016 by original authors @ fontello.com</metadata>
|
||||
<metadata>Copyright (C) 2017 by original authors @ fontello.com</metadata>
|
||||
<defs>
|
||||
<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" />
|
||||
@ -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="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="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;
|
||||
|
||||
.badge {
|
||||
font-size: .5em;
|
||||
font-size: .6em;
|
||||
margin-right: -2px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: #1d1f21;
|
||||
border: 0;
|
||||
color: #c5c8c6;
|
||||
}
|
||||
|
||||
.description {
|
||||
max-height: 12em;
|
||||
overflow: auto;
|
||||
|
@ -44,6 +44,16 @@
|
||||
.icon-plus-squared-alt::before { content: '\f196'; }
|
||||
.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 {
|
||||
cursor: help;
|
||||
}
|
||||
|
@ -14,6 +14,9 @@
|
||||
// dragula
|
||||
@import '../../node_modules/dragula/dist/dragula.css';
|
||||
|
||||
// highlight.js
|
||||
@import '../../node_modules/highlight.js/styles/tomorrow-night-eighties.css';
|
||||
|
||||
// Local styles
|
||||
@import 'core';
|
||||
@import 'login';
|
||||
|
@ -8,13 +8,16 @@
|
||||
'rxjs': 'node_modules/rxjs',
|
||||
'@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 = {
|
||||
'app': { main: 'main.js', defaultExtension: 'js' },
|
||||
'rxjs': { defaultExtension: 'js' },
|
||||
'ng2-dragula': { defaultExtension: 'js' }
|
||||
'ng2-dragula': { defaultExtension: 'js' },
|
||||
'highlight.js': { main: 'index.js', defaultExtension: 'js' }
|
||||
};
|
||||
|
||||
var angularPackages = [
|
||||
|
@ -11,7 +11,12 @@
|
||||
"suppressImplicitAnyIndexErrors": true,
|
||||
"lib": [ "es2015", "dom" ],
|
||||
"typeRoots": [ "node_modules/@types" ],
|
||||
"types": [ "chartist", "core-js" ]
|
||||
"types": [
|
||||
"chartist",
|
||||
"core-js",
|
||||
"marked",
|
||||
"highlight.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user