diff options
author | Joas Schilling <coding@schilljs.com> | 2017-01-17 11:11:16 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-17 11:11:16 +0100 |
commit | aea1b72f54d72331b8ea3b4e9cd4338ffbfe8ee9 (patch) | |
tree | d363ec4d37d33e14ab29c445fbfd6a7efd4741b3 /settings | |
parent | 012708e1badebe5dab6260c2e9edb521d5dbfee0 (diff) | |
parent | 6ba7ba6e0c7109b82c44316b1cdb181c1d37dbc7 (diff) | |
download | nextcloud-server-aea1b72f54d72331b8ea3b4e9cd4338ffbfe8ee9.tar.gz nextcloud-server-aea1b72f54d72331b8ea3b4e9cd4338ffbfe8ee9.zip |
Merge pull request #1594 from nextcloud/markdown-support-for-app-descriptions
Markdown support for app descriptions
Diffstat (limited to 'settings')
-rw-r--r-- | settings/css/settings.css | 23 | ||||
-rw-r--r-- | settings/js/apps.js | 65 | ||||
-rw-r--r-- | settings/templates/apps.php | 6 | ||||
-rw-r--r-- | settings/tests/js/appsSpec.js | 10 |
4 files changed, 99 insertions, 5 deletions
diff --git a/settings/css/settings.css b/settings/css/settings.css index 46394d3f03d..557395c5717 100644 --- a/settings/css/settings.css +++ b/settings/css/settings.css @@ -551,6 +551,26 @@ span.version { flex-basis: 90%; } +#apps-list .app-description p { + margin: 10px 0; +} +#apps-list .app-description ul { + list-style: disc; +} +#apps-list .app-description ol { + list-style: decimal; +} +#apps-list .app-description > ul, +#apps-list .app-description > ol { + margin-left: 19px; +} +#apps-list .app-description ol ol, +#apps-list .app-description ol ul, +#apps-list .app-description ul ol, +#apps-list .app-description ul ul { + padding-left: 15px; +} + @media (min-width: 1601px) { #apps-list .section { width: 22%; @@ -634,9 +654,6 @@ form.section { .app-description { clear: both; } -.app-description pre { - white-space: pre-line; -} #apps-list .groups-enable { margin-top: 8px; diff --git a/settings/js/apps.js b/settings/js/apps.js index 61d817e43e4..1538e71a491 100644 --- a/settings/js/apps.js +++ b/settings/js/apps.js @@ -19,6 +19,8 @@ Handlebars.registerHelper('level', function() { OC.Settings = OC.Settings || {}; OC.Settings.Apps = OC.Settings.Apps || { + markedOptions: {}, + setupGroupsSelect: function($elements) { OC.Settings.setupGroupsSelect($elements, { placeholder: t('core', 'All') @@ -186,6 +188,25 @@ OC.Settings.Apps = OC.Settings.Apps || { app.author = app.author['@value']; } + // Parse markdown in app description + app.description = DOMPurify.sanitize( + marked(app.description.trim(), OC.Settings.Apps.markedOptions), + { + SAFE_FOR_JQUERY: true, + ALLOWED_TAGS: [ + 'strong', + 'p', + 'a', + 'ul', + 'ol', + 'li', + 'em', + 'del', + 'blockquote' + ] + } + ); + var html = template(app); if (selector) { selector.html(html); @@ -633,6 +654,50 @@ OC.Settings.Apps = OC.Settings.Apps || { * Initializes the apps list */ initialize: function($el) { + + 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 = '<a href="' + href + '" rel="noreferrer noopener"'; + if (title) { + out += ' title="' + title + '"'; + } + out += '>' + text + '</a>'; + return out; + }; + renderer.image = function(href, title, text) { + if (text) { + return text; + } + return title; + }; + renderer.blockquote = function(quote) { + return quote; + }; + + OC.Settings.Apps.markedOptions = { + renderer: renderer, + gfm: false, + highlight: false, + tables: false, + breaks: false, + pedantic: false, + sanitize: true, + smartLists: true, + smartypants: false + }; + OC.Plugins.register('OCA.Search', OC.Settings.Apps.Search); OC.Settings.Apps.loadCategories(); OC.Util.History.addOnPopStateHandler(_.bind(this._onPopState, this)); diff --git a/settings/templates/apps.php b/settings/templates/apps.php index 24f8061a530..a4b08f11693 100644 --- a/settings/templates/apps.php +++ b/settings/templates/apps.php @@ -3,7 +3,9 @@ style('settings', 'settings'); vendor_script( 'core', [ - 'handlebars/handlebars' + 'handlebars/handlebars', + 'marked/marked.min', + 'DOMPurify/dist/purify.min', ] ); script( @@ -59,7 +61,7 @@ script( <div class="app-detailpage"></div> <div class="app-description-container hidden"> - <div class="app-description"><pre>{{description}}</pre></div> + <div class="app-description">{{{description}}}</div> <!--<div class="app-changed">{{changed}}</div>--> {{#if documentation}} <p class="documentation"> diff --git a/settings/tests/js/appsSpec.js b/settings/tests/js/appsSpec.js index aa785a6768e..4b917b425c1 100644 --- a/settings/tests/js/appsSpec.js +++ b/settings/tests/js/appsSpec.js @@ -185,23 +185,27 @@ describe('OC.Settings.Apps tests', function() { { id: 'foo', name: 'Foo app', + description: 'Hello', level: 0, author: 'foo' }, { id: 'alpha', name: 'Alpha app', + description: 'Hello', level: 300, author: ['alpha', 'beta'] }, { id: 'nolevel', name: 'No level', + description: 'Hello', author: 'bar' }, { id: 'zork', name: 'Some famous adventure game', + description: 'Hello', level: 200, author: 'baz' @@ -209,6 +213,7 @@ describe('OC.Settings.Apps tests', function() { { id: 'delta', name: 'Mathematical symbol', + description: 'Hello', level: 200, author: 'foobar' } @@ -223,29 +228,34 @@ describe('OC.Settings.Apps tests', function() { 'foo': { id: 'foo', name: 'Foo app', + description: 'Hello', level: 0, author: 'foo' }, 'alpha': { id: 'alpha', name: 'Alpha app', + description: 'Hello', level: 300, author: ['alpha', 'beta'] }, 'nolevel': { id: 'nolevel', name: 'No level', + description: 'Hello', author: 'bar' }, 'zork': { id: 'zork', name: 'Some famous adventure game', + description: 'Hello', level: 200, author: 'baz', }, 'delta': { id: 'delta', name: 'Mathematical symbol', + description: 'Hello', level: 200, author: 'foobar' } |