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