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> </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.