11/* tslint:disable component-selector */
2- import { Component , ElementRef , Input , OnInit , AfterViewInit , ViewChild } from '@angular/core' ;
2+ import { Component , ElementRef , Input , OnInit , OnDestroy , AfterViewInit , ViewChild } from '@angular/core' ;
33import { Location } from '@angular/common' ;
44
5+ import { Subject } from 'rxjs/Subject' ;
6+ import 'rxjs/add/operator/takeUntil' ;
7+
58import { DeviceService } from 'app/shared/device.service' ;
69
710const defaultPlnkrImg = 'plunker/placeholder.png' ;
@@ -12,18 +15,18 @@ const zipBase = 'content/zips/';
1215/**
1316* Angular.io Live Example Embedded Component
1417*
15- * Renders a link to a live/host example of the doc page (except on mobile) .
18+ * Renders a link to a live/host example of the doc page.
1619*
1720* All attributes and the text content are optional
1821*
1922* Usage:
2023* <live-example
2124* [name="..."] // name of the example directory
2225* [plnkr="...""] // name of the plunker file (becomes part of zip file name as well)
23- * [embedded] // embed the plunker in the doc page, else display in new browser tab (external )
26+ * [embedded] // embed the plunker in the doc page, else display in new browser tab (default )
2427* [img="..."] // image to display if embedded in doc page
25- * [embedded-style] // show external plnkr in embedded style
26- * [flat-style] // show external plnkr in flat (original) style
28+ * [embedded-style] // show plnkr in embedded style (default and on narrow screens)
29+ * [flat-style] // show plnkr in flat (original) style
2730* [noDownload] // no downloadable zip option
2831* [title="..."]> // text for live example link and tooltip
2932* text // higher precedence way to specify text for live example link and tooltip
@@ -65,62 +68,73 @@ const zipBase = 'content/zips/';
6568 selector : 'live-example' ,
6669 templateUrl : 'live-example.component.html'
6770} )
68- export class LiveExampleComponent implements OnInit {
71+ export class LiveExampleComponent implements OnInit , OnDestroy {
72+
73+ // Will force to embedded-style when viewport width is narrow
74+ // "narrow" value was picked based on phone dimensions from http://screensiz.es/phone
75+ readonly narrowWidth = 1000 ;
6976
77+ attrs : any ;
7078 enableDownload = true ;
71- mode : string ;
79+ exampleDir : string ;
80+ isEmbedded = false ;
81+ mode = 'disabled' ;
82+ onDestroy = new Subject ( ) ;
7283 plnkr : string ;
84+ plnkrName : string ;
7385 plnkrImg : string ;
7486 showEmbedded = false ;
7587 title : string ;
7688 zip : string ;
7789
7890 constructor (
79- deviceService : DeviceService ,
91+ private deviceService : DeviceService ,
8092 private elementRef : ElementRef ,
8193 location : Location ) {
8294
83- const attrs = this . getAttrs ( ) ;
84-
95+ const attrs = this . attrs = this . getAttrs ( ) ;
8596 let exampleDir = attrs . name ;
8697 if ( ! exampleDir ) {
8798 // take last segment, excluding hash fragment and query params
8899 exampleDir = location . path ( false ) . match ( / [ ^ \/ ? \# ] + (? = \/ ? (?: $ | \# | \? ) ) / ) [ 0 ] ;
89100 }
90- exampleDir = exampleDir . trim ( ) ;
101+ this . exampleDir = exampleDir . trim ( ) ;
102+ this . plnkrName = attrs . plnkr ? attrs . plnkr . trim ( ) + '.' : '' ;
103+ this . zip = `${ zipBase } ${ exampleDir } /${ this . plnkrName } ${ exampleDir } .zip` ;
91104
92- let plnkrStyle = 'eplnkr' ;
105+ const noDownload = this . getAttrValue ( [ 'noDownload' , 'nodownload' ] ) ; // noDownload aliases
106+ this . enableDownload = ! boolFromAtty ( noDownload ) ;
107+ this . plnkrImg = imageBase + ( attrs . img || defaultPlnkrImg ) ;
108+ }
93109
94- const isEmbedded = boolFromAtty ( attrs . embedded ) ;
95- if ( ! isEmbedded ) {
96- // Not embedded in doc page; determine if is embedded- or flat-style in another browser tab.
97- // External plunker is embedded style by default.
98- // Make flat style with `flat-style` or `embedded-style="false`
99- // Must support aliases
100- const flatStyle = getAttrValue ( [ 'flat-style' , 'flatstyle' , 'flatStyle' ] ) ;
101- const isFlatStyle = boolFromAtty ( flatStyle ) ;
102- const embeddedStyle = getAttrValue ( [ 'embedded-style' , 'embeddedstyle' , 'embeddedStyle' ] ) ;
103- const isEmbeddedStyle = boolFromAtty ( embeddedStyle , ! isFlatStyle ) ;
104-
105- plnkrStyle = isEmbeddedStyle ? 'eplnkr' : 'plnkr' ;
106- }
110+ calcPlnkrLink ( width : number ) {
107111
108- this . mode = deviceService . isMobile ? 'mobile' : isEmbedded ? 'embedded' : 'default' ;
112+ const attrs = this . attrs ;
113+ const exampleDir = this . exampleDir ;
109114
110- const plnkrName = attrs . plnkr ? attrs . plnkr . trim ( ) + '.' : '' ;
115+ let plnkrStyle = 'eplnkr' ; // embedded style by default
116+ this . mode = 'default' ; // display in another browser tab by default
111117
112- this . plnkr = `${ liveExampleBase } ${ exampleDir } /${ plnkrName } ${ plnkrStyle } .html` ;
113- this . zip = `${ zipBase } ${ exampleDir } /${ plnkrName } ${ exampleDir } .zip` ;
118+ this . isEmbedded = boolFromAtty ( attrs . embedded ) ;
114119
115- const noDownload = getAttrValue ( [ 'noDownload' , 'nodownload' ] ) ; // noDownload aliases
116- this . enableDownload = ! boolFromAtty ( noDownload ) ;
117- this . plnkrImg = imageBase + ( attrs . img || defaultPlnkrImg ) ;
118-
119- this . title = attrs . title || '' ;
120-
121- function getAttrValue ( atty : string | string [ ] ) {
122- return attrs [ typeof atty === 'string' ? atty : atty . find ( a => attrs [ a ] !== undefined ) ] ;
120+ if ( this . isEmbedded ) {
121+ this . mode = 'embedded' ; // display embedded in the doc
122+ } else {
123+ // Not embedded in doc page; determine if is embedded- or flat-style in another browser tab.
124+ // Embedded style if on tiny screen (reg. plunker no good on narrow screen)
125+ // If wide enough, choose style based on style attributes
126+ if ( width > this . narrowWidth ) {
127+ // Make flat style with `flat-style` or `embedded-style="false`; support atty aliases
128+ const flatStyle = this . getAttrValue ( [ 'flat-style' , 'flatstyle' , 'flatStyle' ] ) ;
129+ const isFlatStyle = boolFromAtty ( flatStyle ) ;
130+
131+ const embeddedStyle = this . getAttrValue ( [ 'embedded-style' , 'embeddedstyle' , 'embeddedStyle' ] ) ;
132+ const isEmbeddedStyle = boolFromAtty ( embeddedStyle , ! isFlatStyle ) ;
133+ plnkrStyle = isEmbeddedStyle ? 'eplnkr' : 'plnkr' ;
134+ }
123135 }
136+
137+ this . plnkr = `${ liveExampleBase } ${ exampleDir } /${ this . plnkrName } ${ plnkrStyle } .html` ;
124138 }
125139
126140 getAttrs ( ) : any {
@@ -130,12 +144,22 @@ export class LiveExampleComponent implements OnInit {
130144 return attrMap ;
131145 }
132146
147+ getAttrValue ( atty : string | string [ ] ) {
148+ return this . attrs [ typeof atty === 'string' ? atty : atty . find ( a => this . attrs [ a ] !== undefined ) ] ;
149+ }
150+
133151 ngOnInit ( ) {
134152 // The `liveExampleContent` property is set by the DocViewer when it builds this component.
135153 // It is the original innerHTML of the host element.
136154 // Angular will sanitize this title when displayed so should be plain text.
137155 const title = this . elementRef . nativeElement . liveExampleContent ;
138- this . title = ( title || this . title || 'live example' ) . trim ( ) ;
156+ this . title = ( title || this . attrs . title || 'live example' ) . trim ( ) ;
157+
158+ this . deviceService . displayWidth . takeUntil ( this . onDestroy ) . subscribe ( width => this . calcPlnkrLink ( width ) ) ;
159+ }
160+
161+ ngOnDestroy ( ) {
162+ this . onDestroy . next ( ) ;
139163 }
140164
141165 toggleEmbedded ( ) { this . showEmbedded = ! this . showEmbedded ; }
0 commit comments