"use strict"; (function () { 'use strict'; /*usage: */ /*CKEditor plugins: * shared space - for shareing toolbar * source diaolog - for edit html of a section * youtube * find and reaplcae - own implementation * maximizze - own implementation * ka-link - own implementation * youtube - own implementation * image - added upload file format validation for image upload dialog * lang - added "uploadImageExtensionError":"Only images (jpg, jpeg, png, gif, bmp, tga, tif, tiff) allowed." for en, ... * wsc plugin - latest version from https://github.com/WebSpellChecker/ckeditor-plugin-wsc * */ angular.module('knowledgeArticleModule') .directive('editKnowledgeArticle', ['$window', '$modal', 'configurationModel', '$filter', 'systemAlertService', function ($window, $modal, configurationModel, $filter, systemAlertService) { return { restrict: 'E', templateUrl: 'views/knowledge-article/edit-knowledge-article.html', scope: { article: '=', styles: '=' }, link: function (scope, element, attrs) { var documentMenuOptions = ['PageBreak'], processingImageCount = 0; if (configurationModel.get('ckEditorSource').enabled) { documentMenuOptions.push('Sourcedialog'); } var options = { language: $window.myitsmLocale, toolbar_full: [ { name: 'basicstyles', items: ['Bold', 'Italic', 'Underline', 'Strike'] }, { name: 'editing', items: ['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'] }, { name: 'links', items: ['Link', 'Unlink', 'Anchor', 'Kalink'] }, { name: 'paragraph', items: ['BulletedList', 'NumberedList', 'Outdent', 'Indent', 'Blockquote'] }, { name: 'insert', items: ['Image', 'Table', 'Youtube'] }, '/', { name: 'styles', items: ['Format', 'FontSize', 'TextColor', 'PasteText', 'PasteFromWord', 'RemoveFormat'] }, { name: 'clipboard', items: ['Undo', 'Redo'] }, { name: 'document', items: documentMenuOptions }, { name: 'editing', items: ['Find', 'Replace', '-', 'SelectAll', '-'] }, { name: 'c_maximize', items: ['c_maximize'] } ], toolbar_merge: [ { name: 'basicstyles', items: ['Bold', 'Italic', 'Underline', 'Strike'] }, { name: 'editing', items: ['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'] }, { name: 'paragraph', items: ['BulletedList', 'NumberedList', 'Outdent', 'Indent', 'Blockquote'] }, { name: 'styles', items: ['Format', 'FontSize', 'TextColor'] } ], toolbar: attrs.toolbar || 'full', sharedSpaces: { top: 'ckeditor-top-bar', bottom: 'ckeditor-bottom-bar' }, extraPlugins: 'youtube,kalink,c_maximize,sourcedialog,simpleuploads', allowedContent: true, removePlugins: 'iframe', format_tags: 'p;h1;h2;h3;h4;h5;h6;pre;address', contentsCss: 'scripts/ckeditor/drop-down-override.css', simpleuploads_respectDialogUploads: true }; if (attrs.readOnly) { options.readOnly = scope.$eval(attrs.readOnly); } if (scope.styles) { var systemStyles = _.reject(scope.styles, 'userStyle'), userStyles = _.filter(scope.styles, 'userStyle'), formattedSystemStyles = {}, formattedUserStyles = []; _.forEach(systemStyles, function (style) { formattedSystemStyles['format_' + style.element] = { element: style.element, attributes: { style: style.styles } }; }); angular.extend(options, formattedSystemStyles); if (userStyles.length) { _.forEach(userStyles, function (style) { formattedUserStyles.push({ name: style.type, element: style.element, attributes: { style: style.styles } }); }); options.stylesSet = formattedUserStyles; var stylePanel = _.find(options.toolbar_full, { name: 'styles' }); stylePanel.items.splice(1, 0, 'Styles'); } } scope.editorOptions = options; scope.openSearchArticleModal = function (ckeditorKaInputId) { var modalInstance = $modal.open({ templateUrl: 'views/knowledge-article/insert-link-article-search-modal.html', controller: ['$scope', 'searchService', function ($scope, searchService) { var state = { searching: false, searchText: '', selectedArticle: null }; $scope.searchArticle = function () { state.searching = true; state.selectedArticle = null; var params = { search_text: state.searchText }, jsonParams = { types: ['knowledge'] }; return searchService.getGlobalSearchResults(params, jsonParams).then(function (data) { $scope.searchResults = data.items[0].results; }).finally(function () { state.searching = false; }); }; $scope.state = state; }], windowClass: 'modal-ka-finder', backdropClass: 'backdrop-ka-finder', keyboard: false }); modalInstance.result.then(function (article) { $('#' + ckeditorKaInputId).val(article.displayId); }); }; scope.handleSectionLabelClick = function (event) { $(event.target).next().find('.ka-ckeditor__section-content').focus(); }; function instanceReadyHandler(e) { e.editor.on('simpleuploads.startUpload', function (ev) { processingImageCount++; checkForImageUpload(e.editor, ev); }); e.editor.on('simpleuploads.endUpload', function (ev) { processingImageCount--; }); e.editor.on('simpleuploads.finishedUpload', function (ev) { ev.editor.setData(ev.editor.getData()); }); } function checkForImageUpload(editor, ev) { var embeddedImageLimit = editor.config && editor.config.embeddedImageLimit; if (!embeddedImageLimit) { // do nothing if we did not get embeddedImageLimit from backend return; } var tmpDiv = document.createElement('div'); tmpDiv.innerHTML = editor && editor.getData(true); var embeddedImages = tmpDiv.querySelectorAll('img[src*="/smartit/rest/"]'); // if we copy images in ckeditor, they have the same src. var uniqueImages = _.unique(embeddedImages, 'src'); var embeddedImageCount = uniqueImages.length; if (embeddedImageCount + processingImageCount > embeddedImageLimit) { processingImageCount--; systemAlertService.error({ text: $filter('i18n')('ka.ckeditor.imageLimitExceeded', [editor.config.title || ev.editor.title || '', embeddedImageLimit]), clear: true }); ev.cancel && ev.cancel(); } } function dialogDefinitionHandler(ev) { var dialogName = ev.data.name, dialogDefinition = ev.data.definition; if (dialogName === 'image') { ev.editor.isFileExtensionAllowed = configurationModel.isFileExtensionAllowed; ev.editor.uploadImageExtensionError = $filter('i18n')('attachment.fileExtension.error'); } if (dialogName === 'link') { dialogDefinition.getContents('info').get('protocol').items.splice(4, 1); } } CKEDITOR.on('instanceReady', instanceReadyHandler); CKEDITOR.on('dialogDefinition', dialogDefinitionHandler); scope.$on('$destroy', function () { CKEDITOR.removeListener('instanceReady', instanceReadyHandler); CKEDITOR.removeListener('dialogDefinition', dialogDefinitionHandler); }); } }; }]); }());