From bb533ee246b673510095d5be3e123a0383030314 Mon Sep 17 00:00:00 2001 From: Keith Robertson Date: Wed, 29 Nov 2017 13:13:35 -0500 Subject: [PATCH] Update 1.2.1 - Reverts script embedding with browserify, since it was rejected by AMO. - Removes all event handlers starting with "on", not just four of them. - Walks the tree just once. - Made Mardown icon square as now required by AMO. --- README.md | 1 - build.bat | 9 ++-- build.sh | 11 ++-- ext/background.js | 2 +- ext/content.js | 123 ++++++++++++++++++++++++------------------ ext/markdown-mark.svg | 5 +- manifest.json | 2 +- test/test-file.md | 8 +-- 8 files changed, 90 insertions(+), 71 deletions(-) diff --git a/README.md b/README.md index 80d4824..7713115 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,6 @@ Markdown (.md) file viewer [WebExtension](https://developer.mozilla.org/en-US/Ad * Required: * [nodejs](https://nodejs.org/) with npm * [web-ext](https://github.com/mozilla/web-ext/) (npm install -g web-ext) - * [browserify](https://github.com/browserify/browserify/) (npm install -g browserify) * Run `build.bat` (Windows) or `build.sh` (Linux) ## Test diff --git a/build.bat b/build.bat index 02741bf..4d57d4c 100644 --- a/build.bat +++ b/build.bat @@ -5,17 +5,14 @@ LICENSE manifest.json ext\*.* + lib\highlightjs\highlight.pack.min.js lib\highlightjs\styles\default.css + lib\markdown-it\dist\markdown-it.min.js + lib\markdown-it-checkbox\dist\markdown-it-checkbox.min.js lib\sss\sss.css lib\sss\sss.print.css ) do @call :copyfile %%f staging\%%f -@call browserify .\ext\content.js^ - -r .\lib\highlightjs\highlight.pack.min.js:highlight.js^ - -r .\lib\markdown-it\dist\markdown-it.min.js:markdown-it^ - -r .\lib\markdown-it-checkbox\dist\markdown-it-checkbox.min.js:markdown-it-checkbox^ - -o .\staging\ext\content.js - @call web-ext build -s staging @goto :EOF diff --git a/build.sh b/build.sh index 8aa25ee..c48b462 100644 --- a/build.sh +++ b/build.sh @@ -4,7 +4,10 @@ rm -r web-ext-artifacts 2>/dev/null for f in LICENSE \ manifest.json \ ext/* \ - ib/highlightjs/styles/default.css \ + lib/highlightjs/highlight.pack.min.js \ + lib/highlightjs/styles/default.css \ + lib/markdown-it/dist/markdown-it.min.js \ + lib/markdown-it-checkbox/dist/markdown-it-checkbox.min.js \ lib/sss/sss.css \ lib/sss/sss.print.css do @@ -12,10 +15,4 @@ do cp $f staging/$f done -browserify ./ext/content.js\ - -r ./lib/highlightjs/highlight.pack.min.js:highlight.js\ - -r ./lib/markdown-it/dist/markdown-it.min.js:markdown-it\ - -r ./lib/markdown-it-checkbox/dist/markdown-it-checkbox.min.js:markdown-it-checkbox\ - -o ./staging/ext/content.js - web-ext build -s staging diff --git a/ext/background.js b/ext/background.js index a3f3d3c..c5108b7 100644 --- a/ext/background.js +++ b/ext/background.js @@ -15,6 +15,6 @@ return false; }); - browser.tabs.executeScript(id, { file: "ext/content.js" }); + browser.tabs.executeScript(id, { file: "/ext/content.js" }); } }); diff --git a/ext/content.js b/ext/content.js index 0533563..dde97e6 100644 --- a/ext/content.js +++ b/ext/content.js @@ -6,38 +6,38 @@ if (media) { style.setAttribute('media', media); } document.head.appendChild(style); } +function addExtensionStylesheet(href, media) { + addStylesheet(browser.extension.getURL(href), media); +} function processMarkdown(textContent) { // Parse the content Markdown => HTML + var md = markdownit({ + html: true, + linkify: true, + // Shameless copypasta https://github.com/markdown-it/markdown-it#syntax-highlighting + highlight: function (str, lang) { + if (lang && hljs.getLanguage(lang)) { + try { + return hljs.highlight(lang, str).value; + } catch (__) {} + } - var hljs = require('highlight.js'); - - var md = require('markdown-it')({ - html: true, - linkify: true, - // Shameless copypasta https://github.com/markdown-it/markdown-it#syntax-highlighting - highlight: function (str, lang) { - if (lang && hljs.getLanguage(lang)) { - try { - return hljs.highlight(lang, str).value; - } catch (__) {} - } - - try { - return hljs.highlightAuto(str).value; - } catch (__) {} - return ''; // use external default escaping - } - }) - //markdown-it plugins: - .use(require('markdown-it-checkbox')); //to format [ ] and [x] + try { + return hljs.highlightAuto(str).value; + } catch (__) {} + return ''; // use external default escaping + } + }) + //markdown-it plugins: + .use(markdownitCheckbox); //to format [ ] and [x] var html = md.render(textContent); // Style the page and code highlights. - addStylesheet(browser.extension.getURL('lib/sss/sss.css')); - addStylesheet(browser.extension.getURL('lib/sss/sss.print.css'), 'print'); - addStylesheet(browser.extension.getURL('lib/highlightjs/styles/default.css')); + addExtensionStylesheet('/lib/sss/sss.css'); + addExtensionStylesheet('/lib/sss/sss.print.css', 'print'); + addExtensionStylesheet('/lib/highlightjs/styles/default.css'); // User-defined stylesheet. addStylesheet('_markdown.css'); @@ -52,36 +52,45 @@ function processMarkdown(textContent) { markdownRoot.className = "markdownRoot"; markdownRoot.innerHTML = html; - // Trample out script elements. - markdownRoot.querySelectorAll('script').forEach(each => { - each.innerText = ''; - each.src = ''; - }); - // Remove hrefs that don't look like URLs. - const likeUrl = /^[-a-z]*:\/\//i; - markdownRoot.querySelectorAll('[href]').forEach(each => { - if (!likeUrl.test(each.href)) { - each.href = ''; + var title = null; + var headers = ['H1', 'H2', 'H3', 'H4', 'H5', 'H6']; + const jsLink = /^\s*javascript:/i; + var eachElement, + allElements = document.createNodeIterator(markdownRoot, NodeFilter.SHOW_ELEMENT); + while (eachElement = allElements.nextNode()) { + var tagName = eachElement.tagName.toUpperCase(); + + // Find a header to use as the page title. + if (!title && headers.includes(tagName)) { + title = eachElement.textContent.trim(); } - }); - // Remove event handlers. (Others?) - var events = ['onclick', 'onload', 'onmouseover', 'onmouseout']; - var eventsJoined = '[' + events.join('],[') + ']'; - markdownRoot.querySelectorAll(eventsJoined).forEach(each => { - events.forEach(attr => { - if (each.getAttribute(attr)) { each.setAttribute(attr, null); } - }); - }); + // Crush scripts. + if (tagName === 'SCRIPT') { + eachElement.innerText = ''; + eachElement.src = ''; + } + // Trample JavaScript hrefs. + if (eachElement.getAttribute("href") && jsLink.test(eachElement.href)) { + eachElement.setAttribute("href", "javascript:;"); + } + // Remove event handlers. + var eachAttributes = Array.from(eachElement.attributes); + for (var j = 0; j < eachAttributes.length; j++) { + var attr = eachAttributes[j]; + if (attr.name.toLowerCase().startsWith('on')) { + eachElement.removeAttribute(attr.name); + } + } + } // Set the page title. - var title = markdownRoot.querySelector('h1, h2, h3, h4, h5, h6'); // First header - if (title) { - title = title.textContent.trim(); - } else { - title = markdownRoot.textContent.trim().split("\n", 1)[0].trim(); // First line + if (!title) { + // Get first line if no header. + title = markdownRoot.textContent.trim().split("\n", 1)[0].trim(); } - if (title.length > 50) { - title = title.substr(0, 50) + "..."; + if (title.length > 128) { + // Limit its length. + title = title.substr(0, 125) + "..."; } document.title = title; @@ -89,6 +98,12 @@ function processMarkdown(textContent) { document.body.appendChild(markdownRoot); } +function loadScriptThen(path, nextStep) { + browser.runtime.sendMessage({ scriptToInject: path }, (response) => { + if (response.success) { nextStep(); } + }); +} + // Execute only if .md is unprocessed text. var body = document.body; if (body.childNodes.length === 1 && @@ -98,5 +113,11 @@ if (body.childNodes.length === 1 && var textContent = body.textContent; body.textContent = ''; - processMarkdown(textContent); + loadScriptThen('/lib/markdown-it/dist/markdown-it.min.js', () => { + loadScriptThen('/lib/markdown-it-checkbox/dist/markdown-it-checkbox.min.js', () => { + loadScriptThen('/lib/highlightjs/highlight.pack.min.js', () => { + processMarkdown(textContent); + }) + }) + }); } diff --git a/ext/markdown-mark.svg b/ext/markdown-mark.svg index f3ed113..a49dc22 100644 --- a/ext/markdown-mark.svg +++ b/ext/markdown-mark.svg @@ -1 +1,4 @@ - \ No newline at end of file + + + + \ No newline at end of file diff --git a/manifest.json b/manifest.json index 1bdcb64..fa5e4b7 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 2, "name": "Markdown Viewer Webext", - "version": "1.2.0", + "version": "1.2.1", "homepage_url": "https://github.com/KeithLRobertson/markdown-viewer", "description": "Displays markdown documents beautified in your browser.", diff --git a/test/test-file.md b/test/test-file.md index 2672e8f..365efc1 100644 --- a/test/test-file.md +++ b/test/test-file.md @@ -62,10 +62,12 @@ function myFunction() { ![Large image (should be resized)](http://lorempixel.com/1200/200/) -HTML is supported +HTML is supported But scripts (in script elements or from events) are not accepted - + - + + +JavaScript links are trampled out, too