66 if ( media ) { style . setAttribute ( 'media' , media ) ; }
77 document . head . appendChild ( style ) ;
88}
9+ function addExtensionStylesheet ( href , media ) {
10+ addStylesheet ( browser . extension . getURL ( href ) , media ) ;
11+ }
912
1013function processMarkdown ( textContent ) {
1114 // Parse the content Markdown => HTML
15+ var md = markdownit ( {
16+ html : true ,
17+ linkify : true ,
18+ // Shameless copypasta https://github.com/markdown-it/markdown-it#syntax-highlighting
19+ highlight : function ( str , lang ) {
20+ if ( lang && hljs . getLanguage ( lang ) ) {
21+ try {
22+ return hljs . highlight ( lang , str ) . value ;
23+ } catch ( __ ) { }
24+ }
1225
13- var hljs = require ( 'highlight.js' ) ;
14-
15- var md = require ( 'markdown-it' ) ( {
16- html : true ,
17- linkify : true ,
18- // Shameless copypasta https://github.com/markdown-it/markdown-it#syntax-highlighting
19- highlight : function ( str , lang ) {
20- if ( lang && hljs . getLanguage ( lang ) ) {
21- try {
22- return hljs . highlight ( lang , str ) . value ;
23- } catch ( __ ) { }
24- }
25-
26- try {
27- return hljs . highlightAuto ( str ) . value ;
28- } catch ( __ ) { }
29- return '' ; // use external default escaping
30- }
31- } )
32- //markdown-it plugins:
33- . use ( require ( 'markdown-it-checkbox' ) ) ; //to format [ ] and [x]
26+ try {
27+ return hljs . highlightAuto ( str ) . value ;
28+ } catch ( __ ) { }
29+ return '' ; // use external default escaping
30+ }
31+ } )
32+ //markdown-it plugins:
33+ . use ( markdownitCheckbox ) ; //to format [ ] and [x]
3434
3535 var html = md . render ( textContent ) ;
3636
3737 // Style the page and code highlights.
38- addStylesheet ( browser . extension . getURL ( ' lib/sss/sss.css') ) ;
39- addStylesheet ( browser . extension . getURL ( ' lib/sss/sss.print.css') , 'print' ) ;
40- addStylesheet ( browser . extension . getURL ( ' lib/highlightjs/styles/default.css') ) ;
38+ addExtensionStylesheet ( '/ lib/sss/sss.css') ;
39+ addExtensionStylesheet ( '/ lib/sss/sss.print.css', 'print' ) ;
40+ addExtensionStylesheet ( '/ lib/highlightjs/styles/default.css') ;
4141 // User-defined stylesheet.
4242 addStylesheet ( '_markdown.css' ) ;
4343
@@ -52,43 +52,58 @@ function processMarkdown(textContent) {
5252 markdownRoot . className = "markdownRoot" ;
5353 markdownRoot . innerHTML = html ;
5454
55- // Trample out script elements.
56- markdownRoot . querySelectorAll ( 'script' ) . forEach ( each => {
57- each . innerText = '' ;
58- each . src = '' ;
59- } ) ;
60- // Remove hrefs that don't look like URLs.
61- const likeUrl = / ^ [ - a - z ] * : \/ \/ / i;
62- markdownRoot . querySelectorAll ( '[href]' ) . forEach ( each => {
63- if ( ! likeUrl . test ( each . href ) ) {
64- each . href = '' ;
55+ var title = null ;
56+ var headers = [ 'H1' , 'H2' , 'H3' , 'H4' , 'H5' , 'H6' ] ;
57+ const jsLink = / ^ \s * j a v a s c r i p t : / i;
58+ var eachElement ,
59+ allElements = document . createNodeIterator ( markdownRoot , NodeFilter . SHOW_ELEMENT ) ;
60+ while ( eachElement = allElements . nextNode ( ) ) {
61+ var tagName = eachElement . tagName . toUpperCase ( ) ;
62+
63+ // Find a header to use as the page title.
64+ if ( ! title && headers . includes ( tagName ) ) {
65+ title = eachElement . textContent . trim ( ) ;
6566 }
66- } ) ;
67- // Remove event handlers. (Others?)
68- var events = [ 'onclick' , 'onload' , 'onmouseover' , 'onmouseout' ] ;
69- var eventsJoined = '[' + events . join ( '],[' ) + ']' ;
70- markdownRoot . querySelectorAll ( eventsJoined ) . forEach ( each => {
71- events . forEach ( attr => {
72- if ( each . getAttribute ( attr ) ) { each . setAttribute ( attr , null ) ; }
73- } ) ;
74- } ) ;
67+ // Crush scripts.
68+ if ( tagName === 'SCRIPT' ) {
69+ eachElement . innerText = '' ;
70+ eachElement . src = '' ;
71+ }
72+ // Trample JavaScript hrefs.
73+ if ( eachElement . getAttribute ( "href" ) && jsLink . test ( eachElement . href ) ) {
74+ eachElement . setAttribute ( "href" , "javascript:;" ) ;
75+ }
76+ // Remove event handlers.
77+ var eachAttributes = Array . from ( eachElement . attributes ) ;
78+ for ( var j = 0 ; j < eachAttributes . length ; j ++ ) {
79+ var attr = eachAttributes [ j ] ;
80+ if ( attr . name . toLowerCase ( ) . startsWith ( 'on' ) ) {
81+ eachElement . removeAttribute ( attr . name ) ;
82+ }
83+ }
84+ }
7585
7686 // Set the page title.
77- var title = markdownRoot . querySelector ( 'h1, h2, h3, h4, h5, h6' ) ; // First header
78- if ( title ) {
79- title = title . textContent . trim ( ) ;
80- } else {
81- title = markdownRoot . textContent . trim ( ) . split ( "\n" , 1 ) [ 0 ] . trim ( ) ; // First line
87+ if ( ! title ) {
88+ // Get first line if no header.
89+ title = markdownRoot . textContent . trim ( ) . split ( "\n" , 1 ) [ 0 ] . trim ( ) ;
8290 }
83- if ( title . length > 50 ) {
84- title = title . substr ( 0 , 50 ) + "..." ;
91+ if ( title . length > 128 ) {
92+ // Limit its length.
93+ title = title . substr ( 0 , 125 ) + "..." ;
8594 }
8695 document . title = title ;
8796
8897 // Finally insert the markdown.
8998 document . body . appendChild ( markdownRoot ) ;
9099}
91100
101+ function loadScriptThen ( path , nextStep ) {
102+ browser . runtime . sendMessage ( { scriptToInject : path } , ( response ) => {
103+ if ( response . success ) { nextStep ( ) ; }
104+ } ) ;
105+ }
106+
92107// Execute only if .md is unprocessed text.
93108var body = document . body ;
94109if ( body . childNodes . length === 1 &&
@@ -98,5 +113,11 @@ if (body.childNodes.length === 1 &&
98113 var textContent = body . textContent ;
99114 body . textContent = '' ;
100115
101- processMarkdown ( textContent ) ;
116+ loadScriptThen ( '/lib/markdown-it/dist/markdown-it.min.js' , ( ) => {
117+ loadScriptThen ( '/lib/markdown-it-checkbox/dist/markdown-it-checkbox.min.js' , ( ) => {
118+ loadScriptThen ( '/lib/highlightjs/highlight.pack.min.js' , ( ) => {
119+ processMarkdown ( textContent ) ;
120+ } )
121+ } )
122+ } ) ;
102123}
0 commit comments