ControllerView.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /**
  2. * DO NOT EDIT THIS FILE.
  3. * See the following change record for more information,
  4. * https://www.drupal.org/node/2815083
  5. * @preserve
  6. **/
  7. (function ($, Drupal, Backbone, CKEDITOR, _) {
  8. Drupal.ckeditor.ControllerView = Backbone.View.extend({
  9. events: {},
  10. initialize: function initialize() {
  11. this.getCKEditorFeatures(this.model.get('hiddenEditorConfig'), this.disableFeaturesDisallowedByFilters.bind(this));
  12. this.model.listenTo(this.model, 'change:activeEditorConfig', this.model.sync);
  13. this.listenTo(this.model, 'change:isDirty', this.parseEditorDOM);
  14. },
  15. parseEditorDOM: function parseEditorDOM(model, isDirty, options) {
  16. if (isDirty) {
  17. var currentConfig = this.model.get('activeEditorConfig');
  18. var rows = [];
  19. this.$el.find('.ckeditor-active-toolbar-configuration').children('.ckeditor-row').each(function () {
  20. var groups = [];
  21. $(this).find('.ckeditor-toolbar-group').each(function () {
  22. var $group = $(this);
  23. var $buttons = $group.find('.ckeditor-button');
  24. if ($buttons.length) {
  25. var group = {
  26. name: $group.attr('data-drupal-ckeditor-toolbar-group-name'),
  27. items: []
  28. };
  29. $group.find('.ckeditor-button, .ckeditor-multiple-button').each(function () {
  30. group.items.push($(this).attr('data-drupal-ckeditor-button-name'));
  31. });
  32. groups.push(group);
  33. }
  34. });
  35. if (groups.length) {
  36. rows.push(groups);
  37. }
  38. });
  39. this.model.set('activeEditorConfig', rows);
  40. this.model.set('isDirty', false);
  41. if (options.broadcast !== false) {
  42. var prev = this.getButtonList(currentConfig);
  43. var next = this.getButtonList(rows);
  44. if (prev.length !== next.length) {
  45. this.$el.find('.ckeditor-toolbar-active').trigger('CKEditorToolbarChanged', [prev.length < next.length ? 'added' : 'removed', _.difference(_.union(prev, next), _.intersection(prev, next))[0]]);
  46. }
  47. }
  48. }
  49. },
  50. getCKEditorFeatures: function getCKEditorFeatures(CKEditorConfig, callback) {
  51. var getProperties = function getProperties(CKEPropertiesList) {
  52. return _.isObject(CKEPropertiesList) ? _.keys(CKEPropertiesList) : [];
  53. };
  54. var convertCKERulesToEditorFeature = function convertCKERulesToEditorFeature(feature, CKEFeatureRules) {
  55. for (var i = 0; i < CKEFeatureRules.length; i++) {
  56. var CKERule = CKEFeatureRules[i];
  57. var rule = new Drupal.EditorFeatureHTMLRule();
  58. var tags = getProperties(CKERule.elements);
  59. rule.required.tags = CKERule.propertiesOnly ? [] : tags;
  60. rule.allowed.tags = tags;
  61. rule.required.attributes = getProperties(CKERule.requiredAttributes);
  62. rule.allowed.attributes = getProperties(CKERule.attributes);
  63. rule.required.styles = getProperties(CKERule.requiredStyles);
  64. rule.allowed.styles = getProperties(CKERule.styles);
  65. rule.required.classes = getProperties(CKERule.requiredClasses);
  66. rule.allowed.classes = getProperties(CKERule.classes);
  67. rule.raw = CKERule;
  68. feature.addHTMLRule(rule);
  69. }
  70. };
  71. var hiddenCKEditorID = 'ckeditor-hidden';
  72. if (CKEDITOR.instances[hiddenCKEditorID]) {
  73. CKEDITOR.instances[hiddenCKEditorID].destroy(true);
  74. }
  75. var hiddenEditorConfig = this.model.get('hiddenEditorConfig');
  76. if (hiddenEditorConfig.drupalExternalPlugins) {
  77. var externalPlugins = hiddenEditorConfig.drupalExternalPlugins;
  78. Object.keys(externalPlugins || {}).forEach(function (pluginName) {
  79. CKEDITOR.plugins.addExternal(pluginName, externalPlugins[pluginName], '');
  80. });
  81. }
  82. CKEDITOR.inline($('#' + hiddenCKEditorID).get(0), CKEditorConfig);
  83. CKEDITOR.once('instanceReady', function (e) {
  84. if (e.editor.name === hiddenCKEditorID) {
  85. var CKEFeatureRulesMap = {};
  86. var rules = e.editor.filter.allowedContent;
  87. var rule = void 0;
  88. var name = void 0;
  89. for (var i = 0; i < rules.length; i++) {
  90. rule = rules[i];
  91. name = rule.featureName || ':(';
  92. if (!CKEFeatureRulesMap[name]) {
  93. CKEFeatureRulesMap[name] = [];
  94. }
  95. CKEFeatureRulesMap[name].push(rule);
  96. }
  97. var features = {};
  98. var buttonsToFeatures = {};
  99. Object.keys(CKEFeatureRulesMap).forEach(function (featureName) {
  100. var feature = new Drupal.EditorFeature(featureName);
  101. convertCKERulesToEditorFeature(feature, CKEFeatureRulesMap[featureName]);
  102. features[featureName] = feature;
  103. var command = e.editor.getCommand(featureName);
  104. if (command) {
  105. buttonsToFeatures[command.uiItems[0].name] = featureName;
  106. }
  107. });
  108. callback(features, buttonsToFeatures);
  109. }
  110. });
  111. },
  112. getFeatureForButton: function getFeatureForButton(button) {
  113. if (button === '-') {
  114. return false;
  115. }
  116. var featureName = this.model.get('buttonsToFeatures')[button.toLowerCase()];
  117. if (!featureName) {
  118. featureName = button.toLowerCase();
  119. }
  120. var featuresMetadata = this.model.get('featuresMetadata');
  121. if (!featuresMetadata[featureName]) {
  122. featuresMetadata[featureName] = new Drupal.EditorFeature(featureName);
  123. this.model.set('featuresMetadata', featuresMetadata);
  124. }
  125. return featuresMetadata[featureName];
  126. },
  127. disableFeaturesDisallowedByFilters: function disableFeaturesDisallowedByFilters(features, buttonsToFeatures) {
  128. this.model.set('featuresMetadata', features);
  129. this.model.set('buttonsToFeatures', buttonsToFeatures);
  130. this.broadcastConfigurationChanges(this.$el);
  131. var existingButtons = [];
  132. var buttonGroups = _.flatten(this.model.get('activeEditorConfig'));
  133. for (var i = 0; i < buttonGroups.length; i++) {
  134. var buttons = buttonGroups[i].items;
  135. for (var k = 0; k < buttons.length; k++) {
  136. existingButtons.push(buttons[k]);
  137. }
  138. }
  139. existingButtons = _.unique(existingButtons);
  140. for (var n = 0; n < existingButtons.length; n++) {
  141. var button = existingButtons[n];
  142. var feature = this.getFeatureForButton(button);
  143. if (feature === false) {
  144. continue;
  145. }
  146. if (Drupal.editorConfiguration.featureIsAllowedByFilters(feature)) {
  147. this.$el.find('.ckeditor-toolbar-active').trigger('CKEditorToolbarChanged', ['added', existingButtons[n]]);
  148. } else {
  149. $('.ckeditor-toolbar-active li[data-drupal-ckeditor-button-name="' + button + '"]').detach().appendTo('.ckeditor-toolbar-disabled > .ckeditor-toolbar-available > ul');
  150. this.model.set({ isDirty: true }, { broadcast: false });
  151. }
  152. }
  153. },
  154. broadcastConfigurationChanges: function broadcastConfigurationChanges($ckeditorToolbar) {
  155. var view = this;
  156. var hiddenEditorConfig = this.model.get('hiddenEditorConfig');
  157. var getFeatureForButton = this.getFeatureForButton.bind(this);
  158. var getCKEditorFeatures = this.getCKEditorFeatures.bind(this);
  159. $ckeditorToolbar.find('.ckeditor-toolbar-active').on('CKEditorToolbarChanged.ckeditorAdmin', function (event, action, button) {
  160. var feature = getFeatureForButton(button);
  161. if (feature === false) {
  162. return;
  163. }
  164. var configEvent = action === 'added' ? 'addedFeature' : 'removedFeature';
  165. Drupal.editorConfiguration[configEvent](feature);
  166. }).on('CKEditorPluginSettingsChanged.ckeditorAdmin', function (event, settingsChanges) {
  167. Object.keys(settingsChanges || {}).forEach(function (key) {
  168. hiddenEditorConfig[key] = settingsChanges[key];
  169. });
  170. getCKEditorFeatures(hiddenEditorConfig, function (features) {
  171. var featuresMetadata = view.model.get('featuresMetadata');
  172. Object.keys(features || {}).forEach(function (name) {
  173. var feature = features[name];
  174. if (featuresMetadata.hasOwnProperty(name) && !_.isEqual(featuresMetadata[name], feature)) {
  175. Drupal.editorConfiguration.modifiedFeature(feature);
  176. }
  177. });
  178. view.model.set('featuresMetadata', features);
  179. });
  180. });
  181. },
  182. getButtonList: function getButtonList(config) {
  183. var buttons = [];
  184. config = _.flatten(config);
  185. config.forEach(function (group) {
  186. group.items.forEach(function (button) {
  187. buttons.push(button);
  188. });
  189. });
  190. return _.without(buttons, '-');
  191. }
  192. });
  193. })(jQuery, Drupal, Backbone, CKEDITOR, _);