js/galleryinfobox.js   A
last analyzed

Complexity

Total Complexity 19
Complexity/F 1.9

Size

Lines of Code 170
Function Count 10

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 103
dl 0
loc 170
rs 10
c 0
b 0
f 0
wmc 19
mnd 9
bc 9
fnc 10
bpm 0.9
cpm 1.9
noi 0
1
/**
2
 * Nextcloud - Gallery
3
 *
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Olivier Paroz <[email protected]>
9
 *
10
 * @copyright Olivier Paroz 2017
11
 */
12
/* global Gallery, commonmark, DOMPurify */
13
(function ($, t, Gallery) {
14
	"use strict";
15
	/**
16
	 * Shows some information about the current album
17
	 *
18
	 * @constructor
19
	 */
20
	var InfoBox = function () {
21
		this.infoContentContainer = $('.album-info-container');
22
		this.infoContentSpinner = this.infoContentContainer.children('.album-info-loader');
23
		this.infoContentElement = this.infoContentContainer.children('.album-info-content');
24
		this.markdownReader = new commonmark.Parser();
25
		this.htmlWriter = new commonmark.HtmlRenderer();
26
	};
27
28
	InfoBox.prototype = {
29
		infoContentContainer: null,
30
		infoContentSpinner: null,
31
		infoContentElement: null,
32
		albumInfo: null,
33
		markdownReader: null,
34
		htmlWriter: null,
35
36
		/**
37
		 * Shows an information box to the user
38
		 */
39
		showInfo: function () {
40
			if(!_.isUndefined(Gallery.Share)){
41
				Gallery.Share.hideDropDown();
42
			}
43
			if (this.infoContentContainer.is(':visible')) {
44
				this.infoContentContainer.slideUp();
45
			} else {
46
				this.albumInfo = Gallery.config.albumInfo;
47
48
				if (!this.albumInfo.infoLoaded) {
49
					this.infoContentSpinner.addClass('icon-loading');
50
					this.infoContentElement.empty();
51
					this.infoContentElement.height(100);
52
					this.infoContentContainer.slideDown();
53
					if (!$.isEmptyObject(this.albumInfo.descriptionLink)) {
54
						var path = '/' + this.albumInfo.filePath;
55
						var file = this.albumInfo.descriptionLink;
56
						var descriptionUrl = Gallery.utility.buildFilesUrl(path, file);
57
						var thisInfoBox = this;
58
						$.get(descriptionUrl).done(function (data) {
59
								thisInfoBox._addContent(data);
60
							}
61
						).fail(function () {
62
							thisInfoBox._addContent(t('gallery',
63
								'Could not load the description'));
64
						});
65
					} else {
66
						this._addContent(this.albumInfo.description);
67
					}
68
					Gallery.config.infoLoaded = true;
69
				} else {
70
					this.infoContentContainer.slideDown();
71
				}
72
				this.infoContentContainer.scrollTop(0);
73
			}
74
		},
75
76
		/**
77
		 * Adds our album information to the infoBox
78
		 *
79
		 * @param {string} content
80
		 * @private
81
		 */
82
		_addContent: function (content) {
83
			try {
84
				content = this._parseMarkdown(content);
85
			} catch (exception) {
86
				content = t('gallery',
87
					'Could not load the description: ' + exception.message);
88
			}
89
			this.infoContentElement.append(content);
90
			this.infoContentElement.find('a').attr("target", "_blank");
91
			this._showCopyright();
92
			this._adjustHeight();
93
		},
94
95
		/**
96
		 * Parses markdown content and sanitizes the HTML
97
		 *
98
		 * @param {string} content
99
		 * @private
100
		 */
101
		_parseMarkdown: function (content) {
102
			return DOMPurify.sanitize(this.htmlWriter.render(this.markdownReader.parse(content), {
103
				smart: true,
104
				safe: true
105
			}), {
106
				ALLOWED_TAGS: ['p', 'b', 'em', 'i', 'pre', 'sup', 'sub', 'strong', 'strike', 'br',
107
					'hr', 'h1', 'h2', 'h3', 'li', 'ul', 'ol', 'a', 'img', 'blockquote', 'code'
108
				]
109
			});
110
		},
111
112
		/**
113
		 * Adjusts the height of the element to match the content
114
		 * @private
115
		 */
116
		_adjustHeight: function () {
117
			this.infoContentSpinner.removeClass('icon-loading');
118
			var newHeight = this.infoContentContainer[0].scrollHeight;
119
			this.infoContentContainer.animate({
120
				height: newHeight + 40
121
			}, 500);
122
			this.infoContentContainer.scrollTop(0);
123
		},
124
125
		/**
126
		 * Adds copyright information to the information box
127
		 * @private
128
		 */
129
		_showCopyright: function () {
130
			if (!$.isEmptyObject(this.albumInfo.copyright) ||
131
				!$.isEmptyObject(this.albumInfo.copyrightLink)) {
132
				var copyright;
133
				var copyrightTitle = $('<h4/>');
134
				copyrightTitle.append(t('gallery', 'Copyright'));
135
				this.infoContentElement.append(copyrightTitle);
136
137
				if (!$.isEmptyObject(this.albumInfo.copyright)) {
138
					try {
139
						copyright = this._parseMarkdown(this.albumInfo.copyright);
140
					} catch (exception) {
141
						copyright =
142
							t('gallery',
143
								'Could not load the copyright notice: ' + exception.message);
144
					}
145
				} else {
146
					copyright = '<p>' + t('gallery', 'Copyright notice') + '</p>';
147
				}
148
149
				if (!$.isEmptyObject(this.albumInfo.copyrightLink)) {
150
					this._addCopyrightLink(copyright);
151
				} else {
152
					this.infoContentElement.append(copyright);
153
					this.infoContentElement.find('a').attr("target", "_blank");
154
				}
155
			}
156
		},
157
158
		/**
159
		 * Adds a link to a copyright document
160
		 *
161
		 * @param {string} copyright
162
		 * @private
163
		 */
164
		_addCopyrightLink: function (copyright) {
165
			var path = '/' + this.albumInfo.filePath;
166
			var file = this.albumInfo.copyrightLink;
167
			var copyrightUrl = Gallery.utility.buildFilesUrl(path, file);
168
			var copyrightElement = $(copyright);
169
			copyrightElement.find('a').removeAttr("href");
170
			copyright = copyrightElement.html();
171
			var copyrightLink = $('<a>', {
172
				html: copyright,
173
				title: t('gallery', 'Link to copyright document'),
174
				href: copyrightUrl,
175
				target: "_blank"
176
			});
177
			this.infoContentElement.append(copyrightLink);
178
		}
179
	};
180
181
	Gallery.InfoBox = InfoBox;
182
})(jQuery, t, Gallery);
183