summaryrefslogtreecommitdiffstats
path: root/settings
diff options
context:
space:
mode:
authorJoas Schilling <coding@schilljs.com>2017-01-17 11:11:16 +0100
committerGitHub <noreply@github.com>2017-01-17 11:11:16 +0100
commitaea1b72f54d72331b8ea3b4e9cd4338ffbfe8ee9 (patch)
treed363ec4d37d33e14ab29c445fbfd6a7efd4741b3 /settings
parent012708e1badebe5dab6260c2e9edb521d5dbfee0 (diff)
parent6ba7ba6e0c7109b82c44316b1cdb181c1d37dbc7 (diff)
downloadnextcloud-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.css23
-rw-r--r--settings/js/apps.js65
-rw-r--r--settings/templates/apps.php6
-rw-r--r--settings/tests/js/appsSpec.js10
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'
}