From f4e631d8414d74b69790c03296733b5b305217e1 Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sat, 21 Jan 2017 12:36:12 -0800 Subject: [PATCH 01/25] bugfix(highlight:) Remove only empty lines at the beggining and end of the content so content new lines arent removed --- .../highlight/highlight.component.scss | 67 ++++++++++--------- src/platform/highlight/highlight.component.ts | 41 ++++++++++-- 2 files changed, 71 insertions(+), 37 deletions(-) diff --git a/src/platform/highlight/highlight.component.scss b/src/platform/highlight/highlight.component.scss index 3a977c77a2..2b4aa660c1 100644 --- a/src/platform/highlight/highlight.component.scss +++ b/src/platform/highlight/highlight.component.scss @@ -1,39 +1,40 @@ $code-font: Menlo, Monaco, "Andale Mono", "lucida console", "Courier New", monospace; +:host /deep/ { + pre, + code, + .highlight { + font-family: $code-font; + } + pre { + display: block; + overflow-x: auto; + padding: 0; + margin: 0; + background: transparent; + color: white; + font-family: $code-font; + line-height: 1.45; + tab-size: 2; + -webkit-font-smoothing: auto; + -webkit-text-size-adjust: none; + position: relative; + border-radius: 2px; + font-size: 0.8rem; + } -pre, -code, -.highlight { - font-family: $code-font; -} -pre { - display: block; - overflow-x: auto; - padding: 0; - margin: 0; - background: transparent; - color: white; - font-family: $code-font; - line-height: 1.45; - tab-size: 2; - -webkit-font-smoothing: auto; - -webkit-text-size-adjust: none; - position: relative; - border-radius: 2px; - font-size: 0.8rem; -} - -code { - margin: 0; - padding: 0; - overflow-wrap: break-word; - white-space: pre-wrap; -} + code { + margin: 0; + padding: 0; + overflow-wrap: break-word; + white-space: pre-wrap; + } -.highlight { - display: block; - overflow-wrap: break-word; - line-height: 1.5; - margin: 0; + .highlight { + display: block; + overflow-wrap: break-word; + line-height: 1.5; + margin: 0; + } } /* Use host as a parent here since hljs renders after dom & doesn't get Angular shadowdom */ diff --git a/src/platform/highlight/highlight.component.ts b/src/platform/highlight/highlight.component.ts index ec6f7448e1..b8214662e5 100644 --- a/src/platform/highlight/highlight.component.ts +++ b/src/platform/highlight/highlight.component.ts @@ -30,10 +30,11 @@ export class TdHighlightComponent implements AfterViewInit { render(contents: string, codeElement: HTMLElement): void { let lines: string[] = contents.split('\n'); - // Remove empty lines - lines = lines.filter(function(line: string): boolean { - return line.trim().length > 0; - }); + // Remove empty start lines only + this._removeEmptyElementAtStart(lines); + // Remove empty ending lines only + this._removeEmptyElementAtEnd(lines); + // Make it so each line starts at 0 whitespace let firstLineWhitespace: string = lines[0].match(/^\s*/)[0]; let startingWhitespaceRegex: RegExp = new RegExp('^' + firstLineWhitespace); @@ -61,4 +62,36 @@ export class TdHighlightComponent implements AfterViewInit { codeElement.innerHTML = highlightedCode.value; } } + + /** + * Method to remove empty lines at the beggining of the array + */ + private _removeEmptyElementAtStart(elements: string[]): void { + let emptyLines: number = 0; + for (; emptyLines < elements.length; emptyLines++) { + if (elements[emptyLines].trim().length > 0) { + break; + } + } + while (emptyLines--) { + elements.shift(); + } + } + + + /** + * Method to remove empty lines at the end of the array + */ + private _removeEmptyElementAtEnd(elements: string[]): void { + let emptyLines: number = elements.length - 1; + for (; emptyLines >= 0; emptyLines--) { + if (elements[emptyLines].trim().length > 0) { + break; + } + } + emptyLines = (elements.length - 1) - emptyLines; + while (emptyLines--) { + elements.pop(); + } + } } From 3c899875cc49ce5c1aa6af5cb32aba0f01606b1d Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sat, 21 Jan 2017 12:39:29 -0800 Subject: [PATCH 02/25] check indentention on first code line as a guide --- src/platform/highlight/highlight.component.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/platform/highlight/highlight.component.ts b/src/platform/highlight/highlight.component.ts index b8214662e5..08cd35423e 100644 --- a/src/platform/highlight/highlight.component.ts +++ b/src/platform/highlight/highlight.component.ts @@ -35,8 +35,15 @@ export class TdHighlightComponent implements AfterViewInit { // Remove empty ending lines only this._removeEmptyElementAtEnd(lines); - // Make it so each line starts at 0 whitespace - let firstLineWhitespace: string = lines[0].match(/^\s*/)[0]; + // check how much indentation is used by the first actual code line + let firstLineWhitespace: string = ''; + for (let line of lines) { + if (line && line.trim().length > 0) { + firstLineWhitespace = line.match(/^\s*/)[0]; + break; + } + } + let startingWhitespaceRegex: RegExp = new RegExp('^' + firstLineWhitespace); lines = lines.map(function(line: string): string { return line From 4c74e0b74eda34f7b420b16bacf997f0ef1de78e Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sat, 21 Jan 2017 12:45:50 -0800 Subject: [PATCH 03/25] remove `html` lang workaround so code parsing is more generic now --- src/platform/highlight/highlight.component.ts | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/platform/highlight/highlight.component.ts b/src/platform/highlight/highlight.component.ts index 08cd35423e..8666176792 100644 --- a/src/platform/highlight/highlight.component.ts +++ b/src/platform/highlight/highlight.component.ts @@ -24,10 +24,11 @@ export class TdHighlightComponent implements AfterViewInit { let codeElement: HTMLElement = this.content.nativeElement; let code: string = codeElement.innerHTML; this.renderer.detachView([].slice.call(codeElement.childNodes)); - this.render(code, codeElement); + this.renderer.setElementClass(codeElement, 'highlight', true); + codeElement.innerHTML = this._render(code); } - render(contents: string, codeElement: HTMLElement): void { + private _render(contents: string): string { let lines: string[] = contents.split('\n'); // Remove empty start lines only @@ -52,22 +53,17 @@ export class TdHighlightComponent implements AfterViewInit { .replace(/\s+$/, ''); }); - this.renderer.setElementClass(codeElement, 'highlight', true); - let codeToParse: string = lines.join('\n') .replace(/\{ \{/gi, '{{').replace(/\} \}/gi, '}}') .replace(/</gi, '<').replace(/>/gi, '>'); // replace with < and > to render HTML in angular 2 - if (this.language === 'html') { // need to use CDATA for HTML - this.renderer.createText(codeElement, codeToParse, undefined); - hljs.highlightBlock(codeElement); - } else { - let highlightedCode: any = hljs.highlight(this.language, codeToParse, true); - highlightedCode.value = highlightedCode.value - .replace(/=""<\/span>/gi, '') - .replace('', '') - .replace('', ''); - codeElement.innerHTML = highlightedCode.value; - } + + // Parse code with highlight.js depending on language + let highlightedCode: any = hljs.highlight(this.language, codeToParse, true); + highlightedCode.value = highlightedCode.value + .replace(/=""<\/span>/gi, '') + .replace('', '') + .replace('', ''); + return highlightedCode.value; } /** From 4a95d9efb60a85c89e4337238cdb861860a16fef Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sat, 21 Jan 2017 13:10:20 -0800 Subject: [PATCH 04/25] fixed indendation in demo --- .../highlight/highlight.component.html | 76 ++++++++++--------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/src/app/components/components/highlight/highlight.component.html b/src/app/components/components/highlight/highlight.component.html index 0128fe7f54..973cf5e352 100644 --- a/src/app/components/components/highlight/highlight.component.html +++ b/src/app/components/components/highlight/highlight.component.html @@ -8,60 +8,62 @@

Also, to display model binding, add spaces between curly braces like:{{ '{' }} {{ '{' }} } } and wrap them with <![CDATA[ and ]]>

Example:

-

hello world!

{ {property} }
- ]]> + ]]>

here's what CSS looks like:

- - pre {{'{'}} - display: block; - overflow-x: auto; - padding: 0; - margin: 0; - background: #002451; - color: white; - font-family: Menlo, Monaco, "Andale Mono", "lucida console", "Courier New", monospace; - line-height: 1.45; - tab-size: 2; - -webkit-font-smoothing: auto; - -webkit-text-size-adjust: none; - position: relative; - border-radius: 2px; - } + +

and JavaScript (typescript):

} = {}; - private _observables: {[key: string]: Observable} = {}; + private _sources: {[key : string]: Subject} = {}; + private _observables: {[key: string]: Observable} = {}; - constructor(){ + constructor(){ - } + } - public register(name) : Observable { - this._sources[name] = new Subject(); - this._observables[name] = this._sources[name].asObservable(); - return this._observables[name]; - } + public register(name) : Observable { + this._sources[name] = new Subject(); + this._observables[name] = this._sources[name].asObservable(); + return this._observables[name]; + } - public emit(name: string): void { - if(this._sources[name]){ - this._sources[name].next(null); + public emit(name: string): void { + if(this._sources[name]){ + this._sources[name].next(null); + } } } - } ]]>

Setup:

@@ -79,7 +81,7 @@

Setup:

]]>

Reference the module in the system-config.js file.

- + Date: Sat, 21 Jan 2017 14:12:40 -0800 Subject: [PATCH 05/25] bugfix(highlight): Use Renderer to limit access to native DOM and DomSanitizer to prevent XSS issues. --- .../highlight/highlight.component.html | 6 +-- src/platform/highlight/highlight.component.ts | 40 +++++++++++++------ 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/platform/highlight/highlight.component.html b/src/platform/highlight/highlight.component.html index e210fd0718..95a0b70bdc 100644 --- a/src/platform/highlight/highlight.component.html +++ b/src/platform/highlight/highlight.component.html @@ -1,5 +1 @@ -
-  
-    
-  
-
\ No newline at end of file + \ No newline at end of file diff --git a/src/platform/highlight/highlight.component.ts b/src/platform/highlight/highlight.component.ts index 8666176792..66631a4f9e 100644 --- a/src/platform/highlight/highlight.component.ts +++ b/src/platform/highlight/highlight.component.ts @@ -1,4 +1,5 @@ -import { Component, AfterViewInit, ViewChild, ElementRef, Input, Renderer } from '@angular/core'; +import { Component, AfterViewInit, ElementRef, Input, Renderer, SecurityContext } from '@angular/core'; +import { DomSanitizer } from '@angular/platform-browser'; /* tslint:disable-next-line */ let hljs: any = require('highlight.js/lib'); @@ -11,21 +12,37 @@ export class TdHighlightComponent implements AfterViewInit { @Input('lang') language: string = 'javascript'; - @ViewChild('highlight') content: ElementRef; - - constructor(private renderer: Renderer) { - - } + constructor(private _renderer: Renderer, + private _elementRef: ElementRef, + private _domSanitizer: DomSanitizer) {} ngAfterViewInit(): void { if (!this.language) { throw 'Error: language attribute must be defined in TdHighlightComponent.'; } - let codeElement: HTMLElement = this.content.nativeElement; - let code: string = codeElement.innerHTML; - this.renderer.detachView([].slice.call(codeElement.childNodes)); - this.renderer.setElementClass(codeElement, 'highlight', true); - codeElement.innerHTML = this._render(code); + this._loadContent((this._elementRef.nativeElement).textContent); + } + + private _loadContent(code: string): void { + if (code && code.trim().length > 0) { + // Parse html string into actual HTML elements. + let preElement: HTMLPreElement = this._elementFromString(this._render(code)); + // Clean container + this._renderer.setElementProperty(this._elementRef.nativeElement, 'innerHTML', ''); + // Project DIV element into container + this._renderer.projectNodes(this._elementRef.nativeElement, [preElement]); + } + } + + private _elementFromString(codeStr: string): HTMLPreElement { + // Renderer doesnt have a parsing method, so we have to sanitize and use [innerHTML] + // to parse the string into DOM element for now. + const preElement: HTMLPreElement = this._renderer.createElement(this._elementRef.nativeElement, 'pre'); + const codeElement: HTMLElement = this._renderer.createElement(preElement, 'code'); + // Set .highlight class into element + this._renderer.setElementClass(codeElement, 'highlight', true); + codeElement.innerHTML = this._domSanitizer.sanitize(SecurityContext.HTML, codeStr); + return preElement; } private _render(contents: string): string { @@ -81,7 +98,6 @@ export class TdHighlightComponent implements AfterViewInit { } } - /** * Method to remove empty lines at the end of the array */ From 35b2114e4388674ee38991ce39dfc5a92b33f102 Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sat, 21 Jan 2017 14:17:53 -0800 Subject: [PATCH 06/25] feature(highlight): Added [content] input to td-highlight to load content dynamically. --- src/platform/highlight/highlight.component.ts | 38 +++++++++++++++++-- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/platform/highlight/highlight.component.ts b/src/platform/highlight/highlight.component.ts index 66631a4f9e..1a936de3e3 100644 --- a/src/platform/highlight/highlight.component.ts +++ b/src/platform/highlight/highlight.component.ts @@ -10,7 +10,31 @@ let hljs: any = require('highlight.js/lib'); }) export class TdHighlightComponent implements AfterViewInit { - @Input('lang') language: string = 'javascript'; + private _content: string; + + /** + * content?: string + * + * Code content to be parsed as highlighted html. + * Used to load data dynamically. + * + * e.g. `.html`, `.ts` , etc. + */ + @Input('content') + set content(content: string) { + this._content = content; + this._loadContent(this._content); + } + + /** + * lang?: string + * + * Language of the code content to be parsed as highlighted html. + * Defaults to `typescript` + * + * e.g. `typescript`, `html` , etc. + */ + @Input('lang') language: string = 'typescript'; constructor(private _renderer: Renderer, private _elementRef: ElementRef, @@ -18,11 +42,15 @@ export class TdHighlightComponent implements AfterViewInit { ngAfterViewInit(): void { if (!this.language) { - throw 'Error: language attribute must be defined in TdHighlightComponent.'; + throw 'Error: [lang] input must be defined in TdHighlightComponent.'; + } + if (!this._content) { + this._loadContent((this._elementRef.nativeElement).textContent); } - this._loadContent((this._elementRef.nativeElement).textContent); } - + /** + * General method to parse a string of code into HTML Elements and load them into the container + */ private _loadContent(code: string): void { if (code && code.trim().length > 0) { // Parse html string into actual HTML elements. @@ -46,6 +74,7 @@ export class TdHighlightComponent implements AfterViewInit { } private _render(contents: string): string { + // Split markup by line characters let lines: string[] = contents.split('\n'); // Remove empty start lines only @@ -62,6 +91,7 @@ export class TdHighlightComponent implements AfterViewInit { } } + // Remove all indentation spaces so code can be parsed correctly let startingWhitespaceRegex: RegExp = new RegExp('^' + firstLineWhitespace); lines = lines.map(function(line: string): string { return line From ae2baf3fb261c1a7cef46a453ed504e61f43fdbd Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sat, 21 Jan 2017 14:22:47 -0800 Subject: [PATCH 07/25] load README.md in highlight docs --- .../highlight/highlight.component.html | 53 +++---------------- .../highlight/highlight.component.ts | 20 ++++++- 2 files changed, 27 insertions(+), 46 deletions(-) diff --git a/src/app/components/components/highlight/highlight.component.html b/src/app/components/components/highlight/highlight.component.html index 973cf5e352..02eba043c5 100644 --- a/src/app/components/components/highlight/highlight.component.html +++ b/src/app/components/components/highlight/highlight.component.html @@ -35,7 +35,7 @@

hello world!

} ]]>
-

and JavaScript (typescript):

+

and TypeScript (javascript):

hello world! } ]]> -

Setup:

-

highlight.js needs to be added as vendor (installed as a highlight.js dependency).

- - - -

Reference the module in the system-config.js file.

- - - -

Then, import the [CovalentHighlightModule] using the forRoot() method in your NgModule:

- - - + + + + + + + diff --git a/src/app/components/components/highlight/highlight.component.ts b/src/app/components/components/highlight/highlight.component.ts index f3cc4a63ac..e6cdbe3ec5 100644 --- a/src/app/components/components/highlight/highlight.component.ts +++ b/src/app/components/components/highlight/highlight.component.ts @@ -1,4 +1,5 @@ -import { Component, HostBinding } from '@angular/core'; +import { Component, HostBinding, OnInit } from '@angular/core'; +import { Http, Response } from '@angular/http'; import { slideInDownAnimation } from '../../../app.animations'; @@ -13,4 +14,21 @@ export class HighlightDemoComponent { @HostBinding('@routeAnimation') routeAnimation: boolean = true; @HostBinding('class.td-route-animation') classAnimation: boolean = true; + content: string; + + constructor(private _http: Http) {} + + ngOnInit(): void { + let errorString: string = 'Warning: Resource could not be loaded.'; + this._http.get('platform/highlight/README.md').subscribe((res: Response) => { + try { + this.content = res.text(); + } catch (e) { + this.content = errorString; + } + }, (error: Error) => { + this.content = errorString; + }); + } + } From 3c18b4ea597e0f68d92da4708b83c8664a673830 Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sat, 21 Jan 2017 15:26:12 -0800 Subject: [PATCH 08/25] update README.md for highlight --- src/platform/highlight/README.md | 127 ++++++++++++++----------------- src/platform/markdown/README.md | 6 +- 2 files changed, 59 insertions(+), 74 deletions(-) diff --git a/src/platform/highlight/README.md b/src/platform/highlight/README.md index 1d96da240b..21943201d2 100644 --- a/src/platform/highlight/README.md +++ b/src/platform/highlight/README.md @@ -1,8 +1,8 @@ -# td-highlight +## TdHighlightComponent: td-markdown -`td-highlight` is an HTML wrapper `
` tags enhanced with styling and code parser for angular2 on top of the [highlightjs lib](https://highlightjs.org/).
+`td-highlight` is an @angular component that uses native **@angular** to parse code to HTML elements. It is based on [highlight.js](https://highlightjs.org/) library.
 
-This implementation supports all the Common languages in highlightjs and typescript.
+This implementation supports all the Common languages in *highlight.js*.
 
 ## API Summary
 
@@ -10,45 +10,26 @@ Properties:
 
 | Name | Type | Description |
 | --- | --- | --- |
-| `lang` | `"typescript"|"html"|"css"|[any common language supported in highlightjs]` | The language of the code thats inside the component.
+| `lang` | `[any common language supported in highlight.js]` | Language of the code content to be parsed as highlighted html.
+| `content` | `string` | Code content to be parsed as highlighted html. Used to load data dynamically. e.g. `.ts` content.
 
-## Installation
+**Note:** This module uses the **DomSanitizer** service to ~sanitize~ the parsed `html` from the `highlight.js` lib to avoid **XSS** issues.
 
-This component can be installed as npm package and can be included by importing from `@covalent/highlight`.
+By default, `--dev` build will log the following message in the console to let you know:
 
-## Setup
+`WARNING: sanitizing HTML stripped some content (see http://g.co/ng/security#xss).`
 
-`highlight.js` needs to be added as vendor (installed as a `highlight.js` dependency).
+## Installation
 
-```typescript
-module.exports = function(defaults) {
-  return new Angular2App(defaults, {
-    vendorNpmFiles: [
-      ...
-      'highlight.js/lib/**'
-    ]
-  });
-};
-```
-Reference the module in the `system-config.js` file.
+This component can be installed as npm package.
 
-```typescript
-  
+```npm
+npm i -save @covalent/highlight
 ```
 
-Then, import the [CovalentHighlightModule] using the forRoot() method in your NgModule:
+## Setup
+
+Then, import the **[CovalentHighlightModule]** using the *forRoot()* method in your NgModule:
 
 ```typescript
 import { CovalentHighlightModule } from '@covalent/highlight';
@@ -70,10 +51,12 @@ Also, to display model binding, add spaces between curly braces like: `{ { } }`
 Example for HTML usage:
 
  ```html
-       
+
   hello world!
-    { {property} }
+    
+      

hello world!

+ { {property} } +
]]>
``` @@ -81,22 +64,24 @@ Example for HTML usage: Example for CSS usage: ```html - - pre { - display: block; - overflow-x: auto; - padding: 0; - margin: 0; - background: #002451; - color: white; - font-family: Menlo, Monaco, "Andale Mono", "lucida console", "Courier New", monospace; - line-height: 1.45; - tab-size: 2; - -webkit-font-smoothing: auto; - -webkit-text-size-adjust: none; - position: relative; - border-radius: 2px; - } + + ``` @@ -105,32 +90,32 @@ Example for Typescript: ```html } = {}; - private _observables: {[key: string]: Observable} = {}; + private _sources: {[key : string]: Subject} = {}; + private _observables: {[key: string]: Observable} = {}; - constructor(){ + constructor(){ - } + } - public register(name) : Observable { - this._sources[name] = new Subject(); - this._observables[name] = this._sources[name].asObservable(); - return this._observables[name]; - } + public register(name) : Observable { + this._sources[name] = new Subject(); + this._observables[name] = this._sources[name].asObservable(); + return this._observables[name]; + } - public emit(name: string): void { - if(this._sources[name]){ - this._sources[name].next(null); + public emit(name: string): void { + if(this._sources[name]){ + this._sources[name].next(null); + } } } - } ]]> ``` diff --git a/src/platform/markdown/README.md b/src/platform/markdown/README.md index 0054bc0885..16611994c7 100644 --- a/src/platform/markdown/README.md +++ b/src/platform/markdown/README.md @@ -1,6 +1,6 @@ ## TdMarkdownComponent: td-markdown -`` is a directive for Github flavored Javascript Markdown to HTML converter. It is based on [showdown](https://github.com/showdownjs/showdown/) library. +`` is an @angular component for Github flavored Javascript Markdown to HTML converter. It is based on [showdown](https://github.com/showdownjs/showdown/) library. ## API Summary @@ -8,9 +8,9 @@ Methods: | Name | Type | Description | | --- | --- | --- | -| `content` | `string` | Markdown format content to be parsed as html markup. Used to load data dynamically. e.g. Resource file. +| `content` | `string` | Markdown format content to be parsed as html markup. Used to load data dynamically. e.g. `README.md` content. -**Note:** This module uses the **DomSanitizer** ng2 service to ~sanitize~ the parsed `html` from the `showdown` lib to avoid **XSS** issues. +**Note:** This module uses the **DomSanitizer** service to ~sanitize~ the parsed `html` from the `showdown` lib to avoid **XSS** issues. By default, `--dev` build will log the following message in the console to let you know: From fa6ae6e02fe72a8c4f9faffb2935ba4c496904eb Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sat, 21 Jan 2017 15:30:36 -0800 Subject: [PATCH 09/25] remove info thats already in README.md --- .../components/highlight/highlight.component.html | 5 +---- src/platform/highlight/README.md | 8 ++++---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/app/components/components/highlight/highlight.component.html b/src/app/components/components/highlight/highlight.component.html index 02eba043c5..a68983c0d1 100644 --- a/src/app/components/components/highlight/highlight.component.html +++ b/src/app/components/components/highlight/highlight.component.html @@ -3,10 +3,7 @@ Highlighting your code snippets -

Simply wrap your code snippets in ]]>

-

To use HTML brackets < and > wrap the code with <![CDATA[ and ]]> or replace with HTMLs character entities

-

Also, to display model binding, add spaces between curly braces like:{{ '{' }} {{ '{' }} } } and wrap them with <![CDATA[ and ]]> -

Example:

+

HTML highlight:

diff --git a/src/platform/highlight/README.md b/src/platform/highlight/README.md index 21943201d2..cdbf183e79 100644 --- a/src/platform/highlight/README.md +++ b/src/platform/highlight/README.md @@ -50,7 +50,7 @@ Also, to display model binding, add spaces between curly braces like: `{ { } }` Example for HTML usage: - ```html +```html @@ -59,11 +59,11 @@ Example for HTML usage: ]]> - ``` +``` Example for CSS usage: - ```html +```html - ``` +``` Example for Typescript: From 386749645bac96ca7e3637848ca3c6ab35193b18 Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sat, 21 Jan 2017 15:30:46 -0800 Subject: [PATCH 10/25] update docblock in markdown --- src/platform/markdown/markdown.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/markdown/markdown.component.ts b/src/platform/markdown/markdown.component.ts index 56d1ff974c..60a2cb90cd 100644 --- a/src/platform/markdown/markdown.component.ts +++ b/src/platform/markdown/markdown.component.ts @@ -18,7 +18,7 @@ export class TdMarkdownComponent implements AfterViewInit { * Markdown format content to be parsed as html markup. * Used to load data dynamically. * - * e.g. Resource file. + * e.g. README.md content. */ @Input('content') set content(content: string) { From ad5c8a4dc12960de081f608b0136fa0ad4097222 Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sat, 21 Jan 2017 15:34:10 -0800 Subject: [PATCH 11/25] polish README.md --- .../components/highlight/highlight.component.html | 3 ++- src/platform/highlight/README.md | 9 +++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/app/components/components/highlight/highlight.component.html b/src/app/components/components/highlight/highlight.component.html index a68983c0d1..60789bc19a 100644 --- a/src/app/components/components/highlight/highlight.component.html +++ b/src/app/components/components/highlight/highlight.component.html @@ -3,7 +3,8 @@ Highlighting your code snippets -

HTML highlight:

+

Example:

+

HTML usage:

diff --git a/src/platform/highlight/README.md b/src/platform/highlight/README.md index cdbf183e79..ba5a67a90c 100644 --- a/src/platform/highlight/README.md +++ b/src/platform/highlight/README.md @@ -45,10 +45,11 @@ export class MyModule {} ## Usage -Simply wrap your code snippets in ``. To use HTML brackets `<` and `>` wrap the code with `;` or replace with HTMLs character entities `<` and `>`. +Simply wrap your code snippets in ``. To use HTML brackets `<` and `>` wrap the code with `;` or replace with HTMLs character entities `<` and `>`. + Also, to display model binding, add spaces between curly braces like: `{ { } }` and wrap them with `;` -Example for HTML usage: +Example for **HTML** usage: ```html @@ -61,7 +62,7 @@ Example for HTML usage: ``` -Example for CSS usage: +Example for **CSS** usage: ```html @@ -85,7 +86,7 @@ Example for CSS usage: ``` -Example for Typescript: +Example for **Typescript**: ```html From e1092510e9dcf530df900f3827f63e9a76590e4c Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sat, 21 Jan 2017 15:49:35 -0800 Subject: [PATCH 12/25] move scss rules so we can apply any pre-built theme instead of the covalent-theme --- src/platform/highlight/_highlight-theme.scss | 10 +++++----- src/platform/highlight/highlight.component.scss | 14 +++++--------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/platform/highlight/_highlight-theme.scss b/src/platform/highlight/_highlight-theme.scss index bd7ec88d6d..66b4f22ee9 100644 --- a/src/platform/highlight/_highlight-theme.scss +++ b/src/platform/highlight/_highlight-theme.scss @@ -1,15 +1,15 @@ -@import '../core/common/styles/variables'; @import '~@angular/material/core/theming/theming'; @mixin covalent-highlight-theme() { td-highlight { + pre { + color: white; + } + background: #292348; + color: white; .highlight { color: md-color($md-indigo, 50); } - padding: $padding; - & + :host { - margin-top: $margin; /* 2nd neighbor & beyond will have margin */ - } .hljs-comment, .hljs-quote { diff --git a/src/platform/highlight/highlight.component.scss b/src/platform/highlight/highlight.component.scss index 2b4aa660c1..000de58283 100644 --- a/src/platform/highlight/highlight.component.scss +++ b/src/platform/highlight/highlight.component.scss @@ -1,5 +1,10 @@ $code-font: Menlo, Monaco, "Andale Mono", "lucida console", "Courier New", monospace; +$padding: 16px; + :host /deep/ { + display: block; + overflow-x: auto; + padding: $padding; pre, code, .highlight { @@ -11,7 +16,6 @@ $code-font: Menlo, Monaco, "Andale Mono", "lucida console", "Courier New", monos padding: 0; margin: 0; background: transparent; - color: white; font-family: $code-font; line-height: 1.45; tab-size: 2; @@ -36,11 +40,3 @@ $code-font: Menlo, Monaco, "Andale Mono", "lucida console", "Courier New", monos margin: 0; } } - -/* Use host as a parent here since hljs renders after dom & doesn't get Angular shadowdom */ -:host { - display: block; - overflow-x: auto; - background: #292348; - color: white; -} From d4d8ea55dd200baf8c126b20653a9deb12fcd0ac Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sat, 21 Jan 2017 16:03:35 -0800 Subject: [PATCH 13/25] update themeing in markdown and highlight --- src/platform/highlight/README.md | 33 +++++++++++++++++++++++++++++++- src/platform/markdown/README.md | 29 ++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/src/platform/highlight/README.md b/src/platform/highlight/README.md index ba5a67a90c..7bb764131a 100644 --- a/src/platform/highlight/README.md +++ b/src/platform/highlight/README.md @@ -29,10 +29,11 @@ npm i -save @covalent/highlight ## Setup -Then, import the **[CovalentHighlightModule]** using the *forRoot()* method in your NgModule: +Import the **[CovalentHighlightModule]** using the *forRoot()* method in your NgModule: ```typescript import { CovalentHighlightModule } from '@covalent/highlight'; + @NgModule({ imports: [ CovalentHighlightModule.forRoot(), @@ -43,6 +44,36 @@ import { CovalentHighlightModule } from '@covalent/highlight'; export class MyModule {} ``` +### Theming + +The `highlight` module comes with its own default `covalent` theme which you can use by importing our theme scss file. + +```css +@import '~@covalent/highlight/highlight-theme'; + +@include covalent-highlight-theme(); +``` + +Alternatively, you can use the *highlight.js* pre-built [themes](https://github.com/isagalaev/highlight.js/tree/master/src/styles) by loading them either by an import: + +```css +@import '~highlight.js/styles/vs.css'; +``` + +Loading them in the `angular-cli.json`: + +```json +"styles": [ + "/path/to/node_modules/highlight.js/styles/vs.css" +] +``` + +Or by loading them in the `index.html` file: + +```html + +``` + ## Usage Simply wrap your code snippets in ``. To use HTML brackets `<` and `>` wrap the code with `;` or replace with HTMLs character entities `<` and `>`. diff --git a/src/platform/markdown/README.md b/src/platform/markdown/README.md index 16611994c7..2f07004ec2 100644 --- a/src/platform/markdown/README.md +++ b/src/platform/markdown/README.md @@ -32,14 +32,14 @@ npm i -save @covalent/markdown ```json "scripts": [ - "../node_modules/showdown/dist/showdown.js" + "path/to/node_modules/showdown/dist/showdown.js" ] ``` **index.html**: ```html - + ``` Then, import the **[CovalentMarkdownModule]** using the *forRoot()* method in your NgModule: @@ -56,6 +56,31 @@ import { CovalentMarkdownModule } from '@covalent/markdown'; export class MyModule {} ``` +### Theming + +The `markdown` module comes with its own `covalent` theme which uses the material *theme* which is used by importing our theme scss file. + +```css +@import '~@angular/material/core/theming/all-theme'; +@import '~@covalent/markdown/markdown-theme'; + +@include md-core(); + +$primary: md-palette($md-orange, 800); +$accent: md-palette($md-light-blue, 600, A100, A400); +$warn: md-palette($md-red, 600); + +$theme: md-light-theme($primary, $accent, $warn); + +@include markdown-markdown-theme($theme); +``` + +Or by loading them in the `index.html` file: + +```html + +``` + ## Example **Html:** From 3ae80bad2ef5e441f114465b4b2009f70f5a6007 Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sat, 21 Jan 2017 16:07:32 -0800 Subject: [PATCH 14/25] comment pre-built theme in theme.scss --- src/theme.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/theme.scss b/src/theme.scss index 997f9b277a..981dfb807a 100644 --- a/src/theme.scss +++ b/src/theme.scss @@ -28,7 +28,7 @@ $theme: md-light-theme($primary, $accent, $warn); @include covalent-theme($theme); @include covalent-markdown-theme($theme); @include covalent-charts-theme($theme); -@include covalent-highlight-theme(); +@include covalent-highlight-theme(); // OR @import '~highlight.js/styles/vs.css'; // Custom theme examples .blue-orange { From c2fd9dea232ddeb86dcd06b38bf153122ae405ab Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sat, 21 Jan 2017 17:43:25 -0800 Subject: [PATCH 15/25] feature(highlight): Mimicking VS Dark+ theme as closely as possible by default in covalent-highlight-theme --- src/platform/highlight/_highlight-theme.scss | 84 ++++++++++++-------- 1 file changed, 52 insertions(+), 32 deletions(-) diff --git a/src/platform/highlight/_highlight-theme.scss b/src/platform/highlight/_highlight-theme.scss index 66b4f22ee9..5c86d14e6c 100644 --- a/src/platform/highlight/_highlight-theme.scss +++ b/src/platform/highlight/_highlight-theme.scss @@ -1,73 +1,93 @@ @import '~@angular/material/core/theming/theming'; +/** +* Mimicking VS Dark+ theme as closely as possible +*/ @mixin covalent-highlight-theme() { td-highlight { - pre { - color: white; - } - background: #292348; - color: white; + background: #1E1E21; .highlight { - color: md-color($md-indigo, 50); + color: md-color($md-grey, 50); } .hljs-comment, .hljs-quote { - color: md-color($md-purple, 200); + color: #608b4e; } - .hljs-variable, - .hljs-template-variable, .hljs-tag, .hljs-name, + .hljs-selector-tag, + .hljs-keyword, + .hljs-literal{ + color: #569cd6; + } + + .hljs-attr, + //.hljs-params, // Remove param color for now + .hljs-attribute { + color: #9cdcfe; + } + + .hljs-string, + .hljs-selector-attr { + color: #ce9178; + } + .hljs-selector-id, .hljs-selector-class, - .hljs-regexp, - .hljs-deletion { - color: md-color($md-pink, A100); + .hljs-selector-pseudo { + color: #d7ba7d; + } + + .hljs-meta { + color: #DCDCAA; } - .hljs-number, .hljs-built_in, .hljs-builtin-name, - .hljs-literal, .hljs-type, - .hljs-params, - .hljs-meta, - .hljs-link { - color: md-color($md-orange, 200); + .hljs-section, + .hljs-class .hljs-title, + .hljs-symbol, + .hljs-bullet { + color: #4EC9B0 } - .hljs-attribute { - color: md-color($md-deep-orange, 200); + .hljs-number { + color: #b5cea8; } - .hljs-string, - .hljs-symbol, - .hljs-bullet, - .hljs-addition { - color: md-color($md-lime, 200); + .hljs-variable, + .hljs-template-variable { + color: #660; } - .hljs-title, - .hljs-section { - color: md-color($md-light-blue, 200); + .hljs-regexp, + .hljs-link { + color: #646695; } - .hljs-keyword { - color: md-color($md-teal, A200); + .hljs-deletion { + color: #ffc8bd; } - .hljs-selector-tag { - color: md-color($md-blue, A100); + .hljs-addition { + background-color: #baeeba; } .hljs-emphasis { font-style: italic; } + .hljs-doctag, .hljs-strong { font-weight: bold; } + + .hljs-formula { + background-color: #eee; + font-style: italic; + } } } From de12b03ea584c9a91f8f051b44082fb8180ab282 Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sat, 21 Jan 2017 17:56:05 -0800 Subject: [PATCH 16/25] changed color for regexp and link --- src/platform/highlight/_highlight-theme.scss | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/platform/highlight/_highlight-theme.scss b/src/platform/highlight/_highlight-theme.scss index 5c86d14e6c..8cdeee0b1b 100644 --- a/src/platform/highlight/_highlight-theme.scss +++ b/src/platform/highlight/_highlight-theme.scss @@ -30,7 +30,9 @@ } .hljs-string, - .hljs-selector-attr { + .hljs-selector-attr, + .hljs-regexp, + .hljs-link { color: #ce9178; } @@ -63,11 +65,6 @@ color: #660; } - .hljs-regexp, - .hljs-link { - color: #646695; - } - .hljs-deletion { color: #ffc8bd; } From b878cd3060e8ef8198926b387947aea7dc0e0a56 Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sat, 21 Jan 2017 19:30:23 -0800 Subject: [PATCH 17/25] code-health(highlight): Added initial set of unit-tests. --- .../highlight/highlight.component.ts | 2 +- .../highlight/highlight.component.spec.ts | 133 ++++++++++++++++++ 2 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 src/platform/highlight/highlight.component.spec.ts diff --git a/src/app/components/components/highlight/highlight.component.ts b/src/app/components/components/highlight/highlight.component.ts index e6cdbe3ec5..bdcfc0c4a4 100644 --- a/src/app/components/components/highlight/highlight.component.ts +++ b/src/app/components/components/highlight/highlight.component.ts @@ -9,7 +9,7 @@ import { slideInDownAnimation } from '../../../app.animations'; templateUrl: './highlight.component.html', animations: [slideInDownAnimation], }) -export class HighlightDemoComponent { +export class HighlightDemoComponent implements OnInit { @HostBinding('@routeAnimation') routeAnimation: boolean = true; @HostBinding('class.td-route-animation') classAnimation: boolean = true; diff --git a/src/platform/highlight/highlight.component.spec.ts b/src/platform/highlight/highlight.component.spec.ts new file mode 100644 index 0000000000..c5f6f043c2 --- /dev/null +++ b/src/platform/highlight/highlight.component.spec.ts @@ -0,0 +1,133 @@ +import { + TestBed, + inject, + async, + ComponentFixture, +} from '@angular/core/testing'; +import 'hammerjs'; +import { Component } from '@angular/core'; +import { By } from '@angular/platform-browser'; +import { CovalentHighlightModule } from './'; + +describe('Component: Highlight', () => { + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + CovalentHighlightModule.forRoot(), + ], + declarations: [ + TdHighlightEmptyTestComponent, + TdHighlightStaticHtmlTestComponent, + TdHighlightDynamicCssTestComponent, + TdHighlightUndefinedLangTestComponent, + ], + }); + TestBed.compileComponents(); + })); + + it('should render empty', async(inject([], () => { + + let fixture: ComponentFixture = TestBed.createComponent(TdHighlightEmptyTestComponent); + let component: TdHighlightEmptyTestComponent = fixture.debugElement.componentInstance; + let element: HTMLElement = fixture.nativeElement; + + expect(fixture.debugElement.query(By.css('td-highlight')).nativeElement.textContent.trim()) + .toBe(``); + expect(fixture.debugElement.query(By.css('td-highlight pre code'))).toBeFalsy(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(fixture.debugElement.query(By.css('td-highlight pre code'))).toBeFalsy(); + expect(fixture.debugElement.query(By.css('td-highlight')).nativeElement.textContent.trim()).toBe(''); + }); + }))); + + it('should render code from static content', async(inject([], () => { + + let fixture: ComponentFixture = TestBed.createComponent(TdHighlightStaticHtmlTestComponent); + let component: TdHighlightStaticHtmlTestComponent = fixture.debugElement.componentInstance; + let element: HTMLElement = fixture.nativeElement; + + expect(fixture.debugElement.query(By.css('td-highlight')).nativeElement.textContent.trim()) + .toContain(`{ {property} }`.trim()); + expect(fixture.debugElement.query(By.css('td-highlight pre code'))).toBeFalsy(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(fixture.debugElement.query(By.css('td-highlight pre code'))).toBeTruthy(); + expect(element.querySelector('td-highlight pre code').textContent.trim()).toContain(`{{property}}`); + expect(element.querySelectorAll('.hljs-tag').length).toBe(6); + }); + }))); + + it('should render cpde from dynamic content', async(inject([], () => { + + let fixture: ComponentFixture = TestBed.createComponent(TdHighlightDynamicCssTestComponent); + let component: TdHighlightDynamicCssTestComponent = fixture.debugElement.componentInstance; + component.content = ` + pre { + background: #002451; + border-radius: 2px; + }`; + let element: HTMLElement = fixture.nativeElement; + + expect(fixture.debugElement.query(By.css('td-highlight')).nativeElement.textContent.trim()) + .toBe(''); + expect(fixture.debugElement.query(By.css('td-highlight pre code'))).toBeFalsy(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(fixture.debugElement.query(By.css('td-highlight pre code'))).toBeTruthy(); + expect(element.querySelectorAll('.hljs-number').length).toBe(2); + }); + }))); + + it('should throw error for undefined language', async(inject([], () => { + let fixture: ComponentFixture = TestBed.createComponent(TdHighlightUndefinedLangTestComponent); + let component: TdHighlightUndefinedLangTestComponent = fixture.debugElement.componentInstance; + expect(function(): void { + fixture.detectChanges(); + }).toThrowError(); + }))); + +}); + +@Component({ + template: ` + + `, +}) +class TdHighlightEmptyTestComponent { +} + +@Component({ + template: ` + +

hello world!

+ { {property} } +
+ ]]> +
`, +}) +class TdHighlightStaticHtmlTestComponent { +} + +@Component({ + template: ` + + `, +}) +class TdHighlightDynamicCssTestComponent { + content: string; +} + +@Component({ + template: ` + + `, +}) +class TdHighlightUndefinedLangTestComponent { + lang: string; +} From 59d667b60b7eab32bdf84551edc4ad73a34eac00 Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sat, 21 Jan 2017 19:44:00 -0800 Subject: [PATCH 18/25] wrong title in README.md --- src/platform/highlight/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/highlight/README.md b/src/platform/highlight/README.md index 7bb764131a..9197243d49 100644 --- a/src/platform/highlight/README.md +++ b/src/platform/highlight/README.md @@ -1,4 +1,4 @@ -## TdHighlightComponent: td-markdown +## TdHighlightComponent: td-highlight `td-highlight` is an @angular component that uses native **@angular** to parse code to HTML elements. It is based on [highlight.js](https://highlightjs.org/) library. From 4fe3b8e7073a8e17044f3f75208bb2be187063c9 Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sat, 21 Jan 2017 20:50:11 -0800 Subject: [PATCH 19/25] replace npm code block with bash --- src/platform/highlight/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/highlight/README.md b/src/platform/highlight/README.md index 9197243d49..ff5269de63 100644 --- a/src/platform/highlight/README.md +++ b/src/platform/highlight/README.md @@ -23,7 +23,7 @@ By default, `--dev` build will log the following message in the console to let y This component can be installed as npm package. -```npm +```bash npm i -save @covalent/highlight ``` From 584af7ddb16573d479df43593be95e4e854d049a Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sat, 21 Jan 2017 22:00:42 -0800 Subject: [PATCH 20/25] fix README.md in markdown --- src/platform/markdown/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/markdown/README.md b/src/platform/markdown/README.md index 2f07004ec2..e74757c7e5 100644 --- a/src/platform/markdown/README.md +++ b/src/platform/markdown/README.md @@ -20,7 +20,7 @@ By default, `--dev` build will log the following message in the console to let y This component can be installed as npm package. -```npm +```bash npm i -save @covalent/markdown ``` From 7166d70d21af1e7090b89684959335b8c4a4d475 Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sun, 22 Jan 2017 10:04:41 -0800 Subject: [PATCH 21/25] point to the main coveralls badge instead of develop branch --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3c9a5dda84..7fc6908cbe 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![npm version](https://badge.fury.io/js/%40covalent%2Fcore.svg)](https://badge.fury.io/js/%40covalent%2Fcore) [![Join the chat at https://gitter.im/Teradata/covalent](https://badges.gitter.im/Teradata/covalent.svg)](https://gitter.im/Teradata/covalent?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Dependency Status](https://dependencyci.com/github/Teradata/covalent/badge)](https://dependencyci.com/github/Teradata/covalent) -[![Coverage Status](https://coveralls.io/repos/github/Teradata/covalent/badge.svg?branch=develop)](https://coveralls.io/github/Teradata/covalent?branch=develop) +[![Coverage Status](https://coveralls.io/repos/github/Teradata/covalent/badge.svg)](https://coveralls.io/github/Teradata/covalent) Covalent From 8d73a54ed1a2332d2225134781c6b4a53279ec2a Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sun, 22 Jan 2017 13:45:34 -0800 Subject: [PATCH 22/25] remove methods and use regexp to remove leading and trailing new empty lines --- src/platform/highlight/highlight.component.ts | 49 ++----------------- 1 file changed, 5 insertions(+), 44 deletions(-) diff --git a/src/platform/highlight/highlight.component.ts b/src/platform/highlight/highlight.component.ts index 9a42bde5e0..1b7df38368 100644 --- a/src/platform/highlight/highlight.component.ts +++ b/src/platform/highlight/highlight.component.ts @@ -74,22 +74,14 @@ export class TdHighlightComponent implements AfterViewInit { } private _render(contents: string): string { + // Trim leading and trailing newlines + contents = contents.replace(/^(\s|\t)*\n+/g, '') + .replace(/(\s|\t)*\n+(\s|\t)*$/g, ''); // Split markup by line characters let lines: string[] = contents.split('\n'); - // Remove empty start lines only - this._removeEmptyElementAtStart(lines); - // Remove empty ending lines only - this._removeEmptyElementAtEnd(lines); - // check how much indentation is used by the first actual code line - let firstLineWhitespace: string = ''; - for (let line of lines) { - if (line && line.trim().length > 0) { - firstLineWhitespace = line.match(/^\s*/)[0]; - break; - } - } + let firstLineWhitespace: string = lines[0].match(/^(\s|\t)*/)[0]; // Remove all indentation spaces so code can be parsed correctly let startingWhitespaceRegex: RegExp = new RegExp('^' + firstLineWhitespace); @@ -97,7 +89,7 @@ export class TdHighlightComponent implements AfterViewInit { return line .replace('=""', '') // remove empty values .replace(startingWhitespaceRegex, '') - .replace(/\s+$/, ''); + .replace(/\s+$/, ''); // remove trailing white spaces }); let codeToParse: string = lines.join('\n') @@ -112,35 +104,4 @@ export class TdHighlightComponent implements AfterViewInit { .replace('', ''); return highlightedCode.value; } - - /** - * Method to remove empty lines at the beggining of the array - */ - private _removeEmptyElementAtStart(elements: string[]): void { - let emptyLines: number = 0; - for (; emptyLines < elements.length; emptyLines++) { - if (elements[emptyLines].trim().length > 0) { - break; - } - } - while (emptyLines--) { - elements.shift(); - } - } - - /** - * Method to remove empty lines at the end of the array - */ - private _removeEmptyElementAtEnd(elements: string[]): void { - let emptyLines: number = elements.length - 1; - for (; emptyLines >= 0; emptyLines--) { - if (elements[emptyLines].trim().length > 0) { - break; - } - } - emptyLines = (elements.length - 1) - emptyLines; - while (emptyLines--) { - elements.pop(); - } - } } From 39083da53d5b7c6a996985d358baccf597dca5cc Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sun, 22 Jan 2017 13:54:06 -0800 Subject: [PATCH 23/25] feature(markdown): Remove only empty lines at the beginning and end of code content only --- src/platform/markdown/markdown.component.ts | 27 +++++++++------------ 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/platform/markdown/markdown.component.ts b/src/platform/markdown/markdown.component.ts index 60a2cb90cd..a4e0ebb3f5 100644 --- a/src/platform/markdown/markdown.component.ts +++ b/src/platform/markdown/markdown.component.ts @@ -58,34 +58,31 @@ export class TdMarkdownComponent implements AfterViewInit { return div; } - private _render(markup: string): string { - // Split markup by line characters - let lines: string[] = markup.split('\n'); + private _render(markdown: string): string { + // Trim leading and trailing newlines + markdown = markdown.replace(/^(\s|\t)*\n+/g, '') + .replace(/(\s|\t)*\n+(\s|\t)*$/g, ''); + // Split markdown by line characters + let lines: string[] = markdown.split('\n'); - // check how much indentation is used by the first actual markup line - let firstLineWhitespace: string = ''; - for (let line of lines) { - if (line && line.trim().length > 0) { - firstLineWhitespace = line.match(/^\s*/)[0]; - break; - } - } + // check how much indentation is used by the first actual markdown line + let firstLineWhitespace: string = lines[0].match(/^(\s|\t)*/)[0]; - // Remove all indentation spaces so markup can be parsed correctly + // Remove all indentation spaces so markdown can be parsed correctly let startingWhitespaceRegex: RegExp = new RegExp('^' + firstLineWhitespace); lines = lines.map(function(line: string): string { return line.replace(startingWhitespaceRegex, ''); }); // Join lines again with line characters - let codeToParse: string = lines.join('\n'); + let markdownToParse: string = lines.join('\n'); - // Convert markup into html + // Convert markdown into html let converter: any = new showdown.Converter(); converter.setOption('ghCodeBlocks', true); converter.setOption('tasklists', true); converter.setOption('tables', true); - let html: string = converter.makeHtml(codeToParse); + let html: string = converter.makeHtml(markdownToParse); return html; } From 5dbc4dec8a2fb28019a4f58bcce9073ab6fcb45c Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Sun, 22 Jan 2017 13:54:46 -0800 Subject: [PATCH 24/25] fixed indentation --- src/platform/markdown/markdown.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/markdown/markdown.component.ts b/src/platform/markdown/markdown.component.ts index a4e0ebb3f5..dbd377d020 100644 --- a/src/platform/markdown/markdown.component.ts +++ b/src/platform/markdown/markdown.component.ts @@ -61,7 +61,7 @@ export class TdMarkdownComponent implements AfterViewInit { private _render(markdown: string): string { // Trim leading and trailing newlines markdown = markdown.replace(/^(\s|\t)*\n+/g, '') - .replace(/(\s|\t)*\n+(\s|\t)*$/g, ''); + .replace(/(\s|\t)*\n+(\s|\t)*$/g, ''); // Split markdown by line characters let lines: string[] = markdown.split('\n'); From 0706a750acf0325a252d3c76b0bd528addb0d90c Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Mon, 23 Jan 2017 15:01:18 -0800 Subject: [PATCH 25/25] fixed unit test typo --- src/platform/highlight/highlight.component.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/highlight/highlight.component.spec.ts b/src/platform/highlight/highlight.component.spec.ts index c5f6f043c2..f11df759cd 100644 --- a/src/platform/highlight/highlight.component.spec.ts +++ b/src/platform/highlight/highlight.component.spec.ts @@ -61,7 +61,7 @@ describe('Component: Highlight', () => { }); }))); - it('should render cpde from dynamic content', async(inject([], () => { + it('should render code from dynamic content', async(inject([], () => { let fixture: ComponentFixture = TestBed.createComponent(TdHighlightDynamicCssTestComponent); let component: TdHighlightDynamicCssTestComponent = fixture.debugElement.componentInstance;