PageSourceSearch

https://mgrsdcg.nl/CKEditor/config_comments.js

js mgrsdcg.nl collected 2026-10-07 16:48:47 UTC 13,900 bytes, 428 lines download raw bytes

1/**
2 * @license Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
3 * For licensing, see LICENSE.html or http://ckeditor.com/license
4 */
5
6if (!CKEDITOR.env.iOS) CKEDITOR.env.mobile = false;
7
8var maxCommentEditorChars = 10000;
9
10// Mett CKEditor plugin language.
11var mettEditorPluginLang = {};
12
13mettEditorPluginLang["nl"] = {
14	link: {
15		linkType: "Interne link",
16		internalSection: "Pagina",
17		internalSectionDefaultLabel: "Kies een interne pagina",
18		internalContentPage: "Pagina item (optioneel)",
19		internalContentPageDefaultLabel: "Kies een item",
20		internalOpenInViewerOrDownload: "Openen in viewer of downloaden",
21		internalOpenInViewer: "Openen in viewer",
22		internalDownload: "Downloaden",
23		externalIcon: "Toon icoon externe link",
24		ariaLabel: "Aria label toevoegen (optioneel)",
25		tel: "Telefoonnummer",
26		telEmpty: "Telefoonnummer is niet ingevuld",
27		telInvalid: "Er is geen geldig telefoonnummer ingevoerd",
28	},
29	image2: {
30		urlDescription: " (Let op! Via deze link is de afbeelding ook zonder inloggen te benaderen)",
31	},
32};
33
34mettEditorPluginLang["en"] = {
35	link: {
36		linkType: "Internal link",
37		internalSection: "Page",
38		internalSectionDefaultLabel: "Select an internal page",
39		internalContentPage: "Page item (optional)",
40		internalContentPageDefaultLabel: "Select an item",
41		internalOpenInViewerOrDownload: "Open in viewer or download",
42		internalOpenInViewer: "Open in viewer",
43		internalDownload: "Download",
44		externalIcon: "Show external link icon",
45		ariaLabel: "Add aria label (optional)",
46		tel: "Phone number",
47		telEmpty: "Phone number is empty",
48		telInvalid: "The phone number is not valid",
49	},
50	image2: {
51		urlDescription: " (Warning! Everybody can view the image using this link without logging in)",
52	},
53};
54
55// Check if all editors are initialized properly.
56CKEDITOR.on("instanceReady", function (event) {
57	var editor = event.editor;
58	var iFrame = $(editor.container.$).find(".cke_wysiwyg_frame");
59
60	if (editor.container.$.id !== undefined) {
61		$("#" + editor.container.$.id)
62			.parent()
63			.addClass("ready");
64	}
65
66	editor.on("fileUploadRequest", function () {
67		// Upload started (disable submit buttons).
68		toggleSubmitButtons();
69	});
70
71	editor.on("fileUploadResponse", function (event) {
72		var xhr = event.data.fileLoader.xhr;
73		var response;
74
75		// Upload finished, successfully or not.
76		toggleSubmitButtons(true);
77
78		if (xhr.status == 200) {
79			try {
80				response = JSON.parse(xhr.responseText);
81
82				if (response && response.url) {
83					// Upload successful.
84				} else if (response && response.error && response.error.number !== 105) {
85					$.fn.showError(settings.errors.uploadFailedText + " (500.126)", "alert", response.error);
86				}
87			} catch (e) {
88				$.fn.showError(settings.errors.uploadFailedText + " (500.127)", "alert", e);
89			}
90		} else {
91			$.fn.showError(settings.errors.uploadFailedText + " (500.128)", "alert", xhr.status);
92		}
93	});
94
95	if (iFrame && settings) {
96		if ($(".commentFieldEditor").length > 0 || $("#comments.comments").length > 0) {
97			iFrame.attr("title", settings.ckeditor.commentEditorTitle);
98			iFrame.parents(".cke.cke_reset").find(".cke_voice_label:eq(0)").text(settings.ckeditor.commentEditorTitle);
99			iFrame.contents().find("body").attr("aria-label", settings.ckeditor.commentEditorTitle);
100		}
101	}
102
103	editor._mettLastValidData = editor.getData() || "";
104	editor._mettSetDataLock = false;
105	editor._mettMaxCharsWarningShown = false;
106
107	editor.on("key", function (evt) {
108		if (getEditorTextLength(editor) < maxCommentEditorChars) return;
109
110		var keyCode = evt.data && evt.data.keyCode ? evt.data.keyCode : 0;
111		var domEvent = evt.data && evt.data.domEvent && evt.data.domEvent.$ ? evt.data.domEvent.$ : null;
112		var hasModifier = domEvent && (domEvent.ctrlKey || domEvent.metaKey || domEvent.altKey);
113		var allowedKeys = {
114			8: true,
115			9: true,
116			13: true,
117			33: true,
118			34: true,
119			35: true,
120			36: true,
121			37: true,
122			38: true,
123			39: true,
124			40: true,
125			46: true,
126		};
127
128		if (!allowedKeys[keyCode] && !hasModifier) {
129			evt.cancel();
130
131			if (!editor._mettMaxCharsWarningShown) {
132				$.fn.showError(settings.warnings.maxEditorCharsText.replace("{0}", maxCommentEditorChars), "alert");
133				editor._mettMaxCharsWarningShown = true;
134			}
135		}
136	});
137
138	editor.on("paste", function (evt) {
139		var currentLength = getEditorTextLength(editor);
140		var pastedLength = getHtmlTextLength(evt.data && evt.data.dataValue ? evt.data.dataValue : "");
141
142		if (currentLength + pastedLength > maxCommentEditorChars) {
143			evt.cancel();
144
145			if (!editor._mettMaxCharsWarningShown) {
146				$.fn.showError(settings.warnings.maxEditorCharsText.replace("{0}", maxCommentEditorChars), "alert");
147				editor._mettMaxCharsWarningShown = true;
148			}
149		}
150	});
151
152	editor.on("change", function () {
153		if (editor._mettSetDataLock) return;
154
155		if (getEditorTextLength(editor) <= maxCommentEditorChars) {
156			editor._mettLastValidData = editor.getData() || "";
157			editor._mettMaxCharsWarningShown = false;
158			return;
159		}
160
161		editor._mettSetDataLock = true;
162		editor.setData(editor._mettLastValidData || "");
163		editor._mettSetDataLock = false;
164
165		if (!editor._mettMaxCharsWarningShown) {
166			$.fn.showError(settings.warnings.maxEditorCharsText.replace("{0}", maxCommentEditorChars), "alert");
167			editor._mettMaxCharsWarningShown = true;
168		}
169	});
170
171	function toggleSubmitButtons(enable) {
172		if (enable === undefined) {
173			enable = false;
174		}
175
176		$(".toolbar .button.save, .toolbar .button.saveSend, .toolbar .button.addComment").each(function () {
177			var button = $(this);
178			var buttonInput = button.find("input:button, input:submit");
179			enable ? button.removeClass("disabled") : button.addClass("disabled");
180			enable ? buttonInput.removeAttr("title") : buttonInput.attr("title", settings.warnings.uploadInProgress);
181
182			buttonInput.prop("disabled", !enable);
183		});
184	}
185});
186
187var mention_users = [];
188
189$.ajax({
190	url: "/api/user/GetCommentersByPermissionsJson",
191	data: {
192		sectionID: settings.section.ID,
193		contentPageID: settings.section.itemID,
194		token: $("input[name='__RequestVerificationToken']").val(),
195	},
196}).done(function (data) {
197	var users = JSON.parse(data);
198
199	if (users.length > 0) {
200		$.each(users, function (i) {
201			var avatar = users[i].Avatar;
202
203			if (avatar == "") avatar = "/communities/common/themes/mett%20responsive/images/various/user-circle.png";
204
205			var user = {
206				id: users[i].UserId,
207				avatar: avatar,
208				fullname: HTMLDecode(users[i].FullName),
209				useremail: users[i].UserEmail,
210			};
211
212			mention_users.push(user);
213		});
214	}
215});
216
217function HTMLDecode(item) {
218	return $("<div></div>").html(item).text();
219}
220
221CKEDITOR.editorConfig = function (config) {
222	// General.
223	config.ImageDlgHideAdvanced = true;
224	config.TemplateReplaceCheckbox = false;
225	config.resize_enabled = true;
226
227	// IE only.
228	config.AutoDetectPasteFromWord = true;
229	config.LinkDlgHideTarget = true;
230
231	// Pasting.
232	config.forcePasteAsPlainText = false;
233	config.pasteFromWordRemoveFontStyles = true;
234	config.pasteFromWordRemoveStyles = true;
235	config.clipboard_handleImages = false;
236
237	// Force all CKEditor file browser/upload flows to Images-only in CKFinder.
238	config.filebrowserBrowseUrl = "/ckfinder/ckfinder.html?v=20260408&type=Images";
239	config.filebrowserImageBrowseUrl = "/ckfinder/ckfinder.html?v=20260408&type=Images";
240	config.filebrowserUploadUrl = "/ckfinder/connector?command=QuickUpload&type=Images";
241	config.filebrowserImageUploadUrl = "/ckfinder/connector?command=QuickUpload&type=Images";
242	config.filebrowserImage2UploadUrl = "/ckfinder/connector?command=QuickUpload&type=Images";
243	config.uploadUrl = "/ckfinder/connector?command=QuickUpload&type=Images&responseType=json";
244	config.imageUploadUrl = "/ckfinder/connector?command=QuickUpload&type=Images&responseType=json";
245	config.uploadImage_supportedTypes = /image\/(bmp|gif|jpe?g|png|tiff)/i;
246
247	// Plugins.
248	config.removePlugins = "exportpdf,image";
249	config.extraPlugins = "wordcount,image2,youtube,smiley,textmatch,autolink,ajax,xml,textwatcher,autocomplete,mentions,smiley,language,bidi";
250
251	// Youtube plugin.
252	config.youtube_responsive = true;
253	config.youtube_related = false;
254
255	// Language plugin.
256	config.language_list = ["nl:Dutch", "en:English", "fr:French", "de:German", "es:Spanish"];
257
258	// Word count.
259	config.wordcount = { showCharCount: true };
260
261	// Sandbox config.
262	config.iframe_attributes = {
263		sandbox:
264			"allow-scripts allow-same-origin allow-presentation allow-forms allow-modals allow-popups allow-popups-to-escape-sandbox allow-top-navigation-by-user-activation allow-downloads",
265		allow: "autoplay; clipboard-write",
266	};
267
268	config.mentions = [
269		{
270			feed: mentionFeed,
271			itemTemplate:
272				'<li class="mention-user" data-id="{id}">' +
273				'<img class="mention-avatar" src="{avatar}" /> ' +
274				'<strong class="user-fullname">{fullname}</strong></li>',
275			outputTemplate: '<a data-user-id={id} href="/shortcuts/Users_ShowProfile.aspx?userkey={id}">{fullname}</a><span>&nbsp;</span>',
276			minChars: 0,
277			marker: "@",
278		},
279	];
280
281	var extraAllowedContent =
282		"*[id,class,style,align,valign,bgcolor,rowspan,colspan,border,usemap,cid,data-*,aria-*,role,rel,autocomplete](*){*};map[*](*){*};area[*](*){*};sup[*](*){*};sub[*](*){*};pre[*](*){*};span[*](*){*};div[*](*){*};object[*](*){*};param[*](*){*};img[width,height];iframe[*](*){*};video[*](*){*};source[*](*){*};track[*](*){*};td[width,height](*){*};label[*](*){*};blockquote[*](*){*};details[*](*){*};summary[*](*){*};figure[*](*){*};figcaption[*](*){*}";
283	var disallowedContent = "table[border,cellpadding,cellspacing];img[onload,onerror]";
284
285	// CSS.
286	if (typeof settings != "undefined") {
287		// Responsive template.
288		config.contentsCss = "/ckeditor/responsive.css";
289	}
290
291	// Allowed & disallowed content.
292	config.extraAllowedContent = extraAllowedContent;
293	config.disallowedContent = disallowedContent;
294
295	// Toolbar configuration.
296	var row1Block1 = {
297		name: "row1Block1",
298		items: ["Bold", "Italic"],
299	};
300	var row1Block2 = {
301		name: "row1Block2",
302		items: ["Copy", "Cut", "Paste"],
303	};
304	var row1Block3 = {
305		name: "row1Block3",
306		items: ["Outdent", "Indent", "BulletedList", "NumberedList"],
307	};
308	var row1Block4 = {
309		name: "row3Block5",
310		items: ["Language", "BidiLtr", "BidiRtl"],
311	};
312	var row1Block5 = {
313		name: "row1Block4",
314		items: ["Link", "Unlink", "Anchor"],
315	};
316
317	if (typeof settings != "undefined" && settings.user.ID === -1) {
318		var row1Block6 = {
319			name: "row1Block5",
320			items: ["Youtube", "Smiley"],
321		};
322	} else {
323		var row1Block6 = {
324			name: "row1Block5",
325			items: ["Image", "Youtube", "Smiley"],
326		};
327	}
328
329	var row1Block7 = {
330		name: "row1Block6",
331		items: ["Maximize"],
332	};
333
334	// Toolbar.
335	config.toolbar_Mett = [row1Block1, row1Block2, row1Block3, row1Block4, row1Block5, row1Block6, row1Block7];
336
337	config.toolbar = "Mett";
338
339	// Remove some tabs from the link dialogs.
340	config.removeDialogTabs = "link:upload;link:advanced;";
341
342	for (name in CKEDITOR.instances) {
343		CKEDITOR.instances[name].on("dialogHide", function (aEvent) {
344			if (typeof aEvent.editor != "undefined" && aEvent.editor != null) {
345				var theWrappingDiv = $("<div>");
346				var theTextArea = $(aEvent.editor.container.$).find("textarea.cke_source");
347
348				if (theTextArea.length > 0) {
349					theWrappingDiv.append($(theTextArea.val()));
350					theWrappingDiv.find("script").remove();
351
352					theTextArea.val(theWrappingDiv.html());
353				}
354
355				// Get data from the CKEditor.
356				var theData = aEvent.sender.getData();
357				var theImagesRegEx = /(\<img\s.*?\ssrc\=\")(.*?)(\".*?\>)/gi;
358				var theHrefsRegEx = /(\shref\=\")(\/[^\"]*?)(\")/gi;
359				var theLinksRegEx = /<a[\s]+([^>]+)>((?:.(?!\<\/a\>))*.)<\/a>/gi;
360
361				if (typeof theData != "undefined" && theData != null && trim(theData) != "") {
362					while ((theMatch = theLinksRegEx.exec(theData)) != null) {
363						var link = $(theMatch[0]);
364
365						if (link.attr("target") == "_blank") {
366							// Add rel="noreferrer noopener" to links with target="_blank", to prevent "tab nabbing".
367							link.attr("rel", "noreferrer noopener");
368						} else {
369							// Remove rel.
370							link.removeAttr("rel");
371						}
372
373						theData = theData.replace(theMatch[0], link.get(0).outerHTML);
374					}
375
376					// Set data in CKEditor.
377					aEvent.sender.setData(theData);
378					aEvent.editor.focus();
379				}
380			}
381		});
382
383		CKEDITOR.instances[name].on("change", function (aEvent) {
384			if (typeof globals != "undefined") globals.pageChanged = true;
385		});
386
387		CKEDITOR.instances[name].on("pasteFromWord", function (aEvent) {
388			// Clone the filter, so that it is based on current editor filter settings.
389			var filter = aEvent.editor.filter.clone();
390			var fragment = CKEDITOR.htmlParser.fragment.fromHtml(aEvent.data.dataValue);
391			var writer = new CKEDITOR.htmlParser.basicWriter();
392
393			// Remove styles.
394			filter.disallow("*[style](*){*};");
395
396			// Filter and overwrite.
397			filter.applyTo(fragment);
398			fragment.writeHtml(writer);
399			aEvent.data.dataValue = writer.getHtml();
400		});
401	}
402};
403
404function mentionFeed(opts, callback) {
405	var matchProperty = "fullname",
406		data = mention_users.filter(function (item) {
407			return item[matchProperty].toLowerCase().indexOf(opts.query.toLowerCase()) == 0;
408		});
409
410	data = data.sort(function (a, b) {
411		return a[matchProperty].localeCompare(b[matchProperty], undefined, {
412			sensitivity: "accent",
413		});
414	});
415
416	callback(data);
417}
418
419function getEditorTextLength(editor) {
420	var html = editor.getData() || "";
421	return $("<div>").html(html).text().length;
422}
423
424function getHtmlTextLength(html) {
425	return $("<div>")
426		.html(html || "")
427		.text().length;
428}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.