@@ -11,6 +11,8 @@ import TelemetryReporter from 'vscode-extension-telemetry';
1111import { MarkdownEngine } from './markdownEngine' ;
1212import DocumentLinkProvider from './documentLinkProvider' ;
1313import MDDocumentSymbolProvider from './documentSymbolProvider' ;
14+ import { MDDocumentContentProvider , getMarkdownUri , isMarkdownFile } from './previewContentProvider' ;
15+
1416
1517interface IPackageInfo {
1618 name : string ;
@@ -102,14 +104,7 @@ export function activate(context: vscode.ExtensionContext) {
102104 } ) ) ;
103105}
104106
105- function isMarkdownFile ( document : vscode . TextDocument ) {
106- return document . languageId === 'markdown'
107- && document . uri . scheme !== 'markdown' ; // prevent processing of own documents
108- }
109107
110- function getMarkdownUri ( uri : vscode . Uri ) {
111- return uri . with ( { scheme : 'markdown' , path : uri . path + '.rendered' , query : uri . toString ( ) } ) ;
112- }
113108
114109function showPreview ( uri ?: vscode . Uri , sideBySide : boolean = false ) {
115110
@@ -195,129 +190,4 @@ function getPackageInfo(): IPackageInfo | null {
195190 return null ;
196191}
197192
198- class MDDocumentContentProvider implements vscode . TextDocumentContentProvider {
199- private _onDidChange = new vscode . EventEmitter < vscode . Uri > ( ) ;
200- private _waiting : boolean ;
201-
202- constructor (
203- private engine : MarkdownEngine ,
204- private context : vscode . ExtensionContext
205- ) {
206- this . _waiting = false ;
207- }
208-
209- private getMediaPath ( mediaFile : string ) : string {
210- return this . context . asAbsolutePath ( path . join ( 'media' , mediaFile ) ) ;
211- }
212193
213- private isAbsolute ( p : string ) : boolean {
214- return path . normalize ( p + '/' ) === path . normalize ( path . resolve ( p ) + '/' ) ;
215- }
216-
217- private fixHref ( resource : vscode . Uri , href : string ) : string {
218- if ( href ) {
219- // Use href if it is already an URL
220- if ( vscode . Uri . parse ( href ) . scheme ) {
221- return href ;
222- }
223-
224- // Use href as file URI if it is absolute
225- if ( this . isAbsolute ( href ) ) {
226- return vscode . Uri . file ( href ) . toString ( ) ;
227- }
228-
229- // use a workspace relative path if there is a workspace
230- let rootPath = vscode . workspace . rootPath ;
231- if ( rootPath ) {
232- return vscode . Uri . file ( path . join ( rootPath , href ) ) . toString ( ) ;
233- }
234-
235- // otherwise look relative to the markdown file
236- return vscode . Uri . file ( path . join ( path . dirname ( resource . fsPath ) , href ) ) . toString ( ) ;
237- }
238- return href ;
239- }
240-
241- private computeCustomStyleSheetIncludes ( uri : vscode . Uri ) : string {
242- const styles = vscode . workspace . getConfiguration ( 'markdown' ) [ 'styles' ] ;
243- if ( styles && Array . isArray ( styles ) && styles . length > 0 ) {
244- return styles . map ( ( style ) => {
245- return `<link rel="stylesheet" href="${ this . fixHref ( uri , style ) } " type="text/css" media="screen">` ;
246- } ) . join ( '\n' ) ;
247- }
248- return '' ;
249- }
250-
251- private getSettingsOverrideStyles ( ) : string {
252- const previewSettings = vscode . workspace . getConfiguration ( 'markdown' ) [ 'preview' ] ;
253- if ( ! previewSettings ) {
254- return '' ;
255- }
256- const { fontFamily, fontSize, lineHeight} = previewSettings ;
257- return `<style>
258- body {
259- ${ fontFamily ? `font-family: ${ fontFamily } ;` : '' }
260- ${ + fontSize > 0 ? `font-size: ${ fontSize } px;` : '' }
261- ${ + lineHeight > 0 ? `line-height: ${ lineHeight } ;` : '' }
262- }
263- </style>` ;
264- }
265-
266- public provideTextDocumentContent ( uri : vscode . Uri ) : Thenable < string > {
267- const sourceUri = vscode . Uri . parse ( uri . query ) ;
268- return vscode . workspace . openTextDocument ( sourceUri ) . then ( document => {
269- const scrollBeyondLastLine = vscode . workspace . getConfiguration ( 'editor' ) [ 'scrollBeyondLastLine' ] ;
270- const wordWrap = vscode . workspace . getConfiguration ( 'editor' ) [ 'wordWrap' ] ;
271-
272- const markdownConfig = vscode . workspace . getConfiguration ( 'markdown' ) ;
273- const previewFrontMatter = markdownConfig . get ( 'previewFrontMatter' , 'hide' ) ;
274-
275- let initialLine = 0 ;
276- const editor = vscode . window . activeTextEditor ;
277- if ( editor && editor . document . uri . path === sourceUri . path ) {
278- initialLine = editor . selection . active . line ;
279- }
280-
281- const body = this . engine . render ( sourceUri , previewFrontMatter === 'hide' , document . getText ( ) ) ;
282-
283- return `<!DOCTYPE html>
284- <html>
285- <head>
286- <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
287- <link rel="stylesheet" type="text/css" href="${ this . getMediaPath ( 'markdown.css' ) } ">
288- <link rel="stylesheet" type="text/css" href="${ this . getMediaPath ( 'tomorrow.css' ) } ">
289- ${ this . getSettingsOverrideStyles ( ) }
290- ${ this . computeCustomStyleSheetIncludes ( uri ) }
291- <base href="${ document . uri . toString ( true ) } ">
292- </head>
293- <body class="${ scrollBeyondLastLine ? 'scrollBeyondLastLine' : '' } ${ wordWrap ? 'wordWrap' : '' } ${ ! ! markdownConfig . get ( 'preview.markEditorSelection' ) ? 'showEditorSelection' : '' } ">
294- ${ body }
295- <script>
296- window.initialData = {
297- source: "${ encodeURIComponent ( sourceUri . scheme + '://' + sourceUri . path ) } ",
298- line: ${ initialLine } ,
299- scrollPreviewWithEditorSelection: ${ ! ! markdownConfig . get ( 'preview.scrollPreviewWithEditorSelection' , true ) } ,
300- scrollEditorWithPreview: ${ ! ! markdownConfig . get ( 'preview.scrollEditorWithPreview' , true ) } ,
301- doubleClickToSwitchToEditor: ${ ! ! markdownConfig . get ( 'preview.doubleClickToSwitchToEditor' , true ) } ,
302- };
303- </script>
304- <script src="${ this . getMediaPath ( 'main.js' ) } "></script>
305- </body>
306- </html>` ;
307- } ) ;
308- }
309-
310- get onDidChange ( ) : vscode . Event < vscode . Uri > {
311- return this . _onDidChange . event ;
312- }
313-
314- public update ( uri : vscode . Uri ) {
315- if ( ! this . _waiting ) {
316- this . _waiting = true ;
317- setTimeout ( ( ) => {
318- this . _waiting = false ;
319- this . _onDidChange . fire ( uri ) ;
320- } , 300 ) ;
321- }
322- }
323- }
0 commit comments