From bd52e377d7ce27679a70ddb2c4e4dc43aeef2cc4 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Fri, 21 Jul 2017 00:44:29 +0200 Subject: [PATCH] Render markdown files directly in public share renders markdown files for single share pages directly inline and uses a readable styling Signed-off-by: Morris Jobke --- appinfo/app.php | 8 ++++- css/public-share.css | 77 ++++++++++++++++++++++++++++++++++++++++++++ js/public-share.js | 68 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 css/public-share.css create mode 100644 js/public-share.js diff --git a/appinfo/app.php b/appinfo/app.php index aa1d7ef9..df8e2b05 100644 --- a/appinfo/app.php +++ b/appinfo/app.php @@ -1,8 +1,9 @@ getEventDispatcher(); + // only load text editor if the user is logged in if (\OCP\User::isLoggedIn()) { - $eventDispatcher = \OC::$server->getEventDispatcher(); $eventDispatcher->addListener('OCA\Files::loadAdditionalScripts', function() { OCP\Util::addStyle('files_texteditor', 'merged'); OCP\Util::addScript('files_texteditor', 'merged'); @@ -14,3 +15,8 @@ }); } +$eventDispatcher->addListener('OCA\Files_Sharing::loadAdditionalScripts', function() { + OC_Util::addVendorScript('core', 'marked/marked.min'); + OCP\Util::addScript('files_texteditor', 'public-share'); + OCP\Util::addStyle('files_texteditor', 'public-share'); +}); diff --git a/css/public-share.css b/css/public-share.css new file mode 100644 index 00000000..8748e876 --- /dev/null +++ b/css/public-share.css @@ -0,0 +1,77 @@ +.preview { + max-width: 700px; + padding: 0px 20px !important; + box-sizing: border-box; + font-size: 18px; + line-height: 1.6em; + min-height: 440px; + color: #333; + text-align: left; + margin-bottom: 170px !important; +} + +.preview h1, +.preview h2, +.preview h3 { + margin-top: 1em; +} + +.preview h1 { + line-height: 1.1em; + margin-bottom: 1em; + text-align: center; + font-size: 3em; +} + +.preview h2 { + line-height: 1.1em; + margin-bottom: .5em; + font-size: 2em; +} + +.preview h3 { + line-height: 1.1em; + margin-bottom: .6em; + font-size: 1.4em; +} + +.preview p, +.preview ul, +.preview ol, +.preview pre { + margin-bottom: 17.6px; + line-height: 1.45em; +} +.preview ul, +.preview ol { + padding-left: 25px; +} + +.preview ul { + list-style-type: square; +} + +.preview ul ul { + list-style-type: circle; +} + +.preview a { + color: #448ac9; + text-decoration: none; +} +.preview a:hover, +.preview a:focus, +.preview a:active { + text-decoration: underline; +} + +.preview em { + opacity: 1; + font-style: italic; +} + +/* hide image preview during loading or if it renders fine */ +.icon-loading .text-preview, +.preview .text-preview { + display: none !important; +} diff --git a/js/public-share.js b/js/public-share.js new file mode 100644 index 00000000..7210ded9 --- /dev/null +++ b/js/public-share.js @@ -0,0 +1,68 @@ +// FIXME: Hack for single public file view since it is not attached to the fileslist +$(document).ready(function(){ + if ($('#isPublic').val() && + $('#mimetype').val() === 'text/markdown' && + $('#filesize').val() < 524288) { + + var sharingToken = $('#sharingToken').val(); + var downloadUrl = OC.generateUrl('/s/{token}/download', {token: sharingToken}); + var previewElement = $('#imgframe'); + var renderer = new marked.Renderer(); + renderer.link = function(href, title, text) { + try { + var prot = decodeURIComponent(unescape(href)) + .replace(/[^\w:]/g, '') + .toLowerCase(); + } catch (e) { + return ''; + } + + if (prot.indexOf('http:') !== 0 && prot.indexOf('https:') !== 0) { + return ''; + } + + var out = ''; + return out; + }; + renderer.image = function(href, title, text) { + if (text) { + return text; + } + return title; + }; + renderer.blockquote = function(quote) { + return quote; + }; + + previewElement + .addClass('icon-loading') + .children().detach(); + + $.get(downloadUrl).success(function(content) { + previewElement + .removeClass('icon-loading') + .addClass('preview') + .html(DOMPurify.sanitize( + marked(content, { + renderer: renderer, + gfm: false, + breaks: false, + pedantic: false, + sanitize: true, + smartLists: true, + smartypants: false + }), + { + SAFE_FOR_JQUERY: true + } + )); + }).fail(function(result){ + previewElement + .removeClass('icon-loading'); + }); + } +});