2 * DO NOT EDIT THIS FILE.
3 * See the following change record for more information,
4 * https://www.drupal.org/node/2815083
8 (function ($, _, Drupal, document) {
9 Drupal.editorConfiguration = {
10 addedFeature: function addedFeature(feature) {
11 $(document).trigger('drupalEditorFeatureAdded', feature);
13 removedFeature: function removedFeature(feature) {
14 $(document).trigger('drupalEditorFeatureRemoved', feature);
16 modifiedFeature: function modifiedFeature(feature) {
17 $(document).trigger('drupalEditorFeatureModified', feature);
19 featureIsAllowedByFilters: function featureIsAllowedByFilters(feature) {
20 function generateUniverseFromFeatureRequirements(feature) {
21 var properties = ['attributes', 'styles', 'classes'];
24 for (var r = 0; r < feature.rules.length; r++) {
25 var featureRule = feature.rules[r];
27 var requiredTags = featureRule.required.tags;
28 for (var t = 0; t < requiredTags.length; t++) {
29 universe[requiredTags[t]] = {
32 touchedByAllowedPropertyRule: false,
34 touchedBytouchedByForbiddenPropertyRule: false
38 if (emptyProperties(featureRule.required)) {
42 for (var p = 0; p < properties.length; p++) {
43 var property = properties[p];
44 for (var pv = 0; pv < featureRule.required[property].length; pv++) {
45 var propertyValue = featureRule.required[property];
46 universe[requiredTags][property + ':' + propertyValue] = false;
54 function emptyProperties(section) {
55 return section.attributes.length === 0 && section.classes.length === 0 && section.styles.length === 0;
58 function findPropertyValuesOnTag(universe, tag, property, propertyValues, allowing) {
60 return findPropertyValuesOnAllTags(universe, property, propertyValues, allowing);
63 var atLeastOneFound = false;
64 _.each(propertyValues, function (propertyValue) {
65 if (findPropertyValueOnTag(universe, tag, property, propertyValue, allowing)) {
66 atLeastOneFound = true;
69 return atLeastOneFound;
72 function findPropertyValuesOnAllTags(universe, property, propertyValues, allowing) {
73 var atLeastOneFound = false;
74 _.each(_.keys(universe), function (tag) {
75 if (findPropertyValuesOnTag(universe, tag, property, propertyValues, allowing)) {
76 atLeastOneFound = true;
79 return atLeastOneFound;
82 function findPropertyValueOnTag(universe, tag, property, propertyValue, allowing) {
83 if (!_.has(universe, tag)) {
87 var key = property + ':' + propertyValue;
90 universe[tag].touchedByAllowedPropertyRule = true;
93 if (_.indexOf(propertyValue, '*') === -1) {
94 if (_.has(universe, tag) && _.has(universe[tag], key)) {
96 universe[tag][key] = true;
104 var atLeastOneFound = false;
105 var regex = key.replace(/\*/g, '[^ ]*');
106 _.each(_.keys(universe[tag]), function (key) {
107 if (key.match(regex)) {
108 atLeastOneFound = true;
110 universe[tag][key] = true;
114 return atLeastOneFound;
117 function deleteFromUniverseIfAllowed(universe, tag) {
119 return deleteAllTagsFromUniverseIfAllowed(universe);
121 if (_.has(universe, tag) && _.every(_.omit(universe[tag], 'touchedByAllowedPropertyRule'))) {
122 delete universe[tag];
128 function deleteAllTagsFromUniverseIfAllowed(universe) {
129 var atLeastOneDeleted = false;
130 _.each(_.keys(universe), function (tag) {
131 if (deleteFromUniverseIfAllowed(universe, tag)) {
132 atLeastOneDeleted = true;
135 return atLeastOneDeleted;
138 function anyForbiddenFilterRuleMatches(universe, filterStatus) {
139 var properties = ['attributes', 'styles', 'classes'];
141 var allRequiredTags = _.keys(universe);
142 var filterRule = void 0;
143 for (var i = 0; i < filterStatus.rules.length; i++) {
144 filterRule = filterStatus.rules[i];
145 if (filterRule.allow === false) {
146 if (_.intersection(allRequiredTags, filterRule.tags).length > 0) {
152 for (var n = 0; n < filterStatus.rules.length; n++) {
153 filterRule = filterStatus.rules[n];
155 if (filterRule.restrictedTags.tags.length && !emptyProperties(filterRule.restrictedTags.forbidden)) {
156 for (var j = 0; j < filterRule.restrictedTags.tags.length; j++) {
157 var tag = filterRule.restrictedTags.tags[j];
159 for (var k = 0; k < properties.length; k++) {
160 var property = properties[k];
162 if (findPropertyValuesOnTag(universe, tag, property, filterRule.restrictedTags.forbidden[property], false)) {
173 function markAllowedTagsAndPropertyValues(universe, filterStatus) {
174 var properties = ['attributes', 'styles', 'classes'];
176 var filterRule = void 0;
178 for (var l = 0; !_.isEmpty(universe) && l < filterStatus.rules.length; l++) {
179 filterRule = filterStatus.rules[l];
180 if (filterRule.allow === true) {
181 for (var m = 0; !_.isEmpty(universe) && m < filterRule.tags.length; m++) {
182 tag = filterRule.tags[m];
183 if (_.has(universe, tag)) {
184 universe[tag].tag = true;
185 deleteFromUniverseIfAllowed(universe, tag);
191 for (var i = 0; !_.isEmpty(universe) && i < filterStatus.rules.length; i++) {
192 filterRule = filterStatus.rules[i];
194 if (filterRule.restrictedTags.tags.length && !emptyProperties(filterRule.restrictedTags.allowed)) {
195 for (var j = 0; !_.isEmpty(universe) && j < filterRule.restrictedTags.tags.length; j++) {
196 tag = filterRule.restrictedTags.tags[j];
198 for (var k = 0; k < properties.length; k++) {
199 var property = properties[k];
201 if (findPropertyValuesOnTag(universe, tag, property, filterRule.restrictedTags.allowed[property], true)) {
202 deleteFromUniverseIfAllowed(universe, tag);
210 function filterStatusAllowsFeature(filterStatus, feature) {
211 if (!filterStatus.active) {
215 if (feature.rules.length === 0) {
219 if (filterStatus.rules.length === 0) {
223 var universe = generateUniverseFromFeatureRequirements(feature);
225 if (anyForbiddenFilterRuleMatches(universe, filterStatus)) {
229 markAllowedTagsAndPropertyValues(universe, filterStatus);
231 if (_.some(_.pluck(filterStatus.rules, 'allow'))) {
232 if (_.isEmpty(universe)) {
236 if (!_.every(_.pluck(universe, 'tag'))) {
241 var tags = _.keys(universe);
243 for (var i = 0; i < tags.length; i++) {
245 if (_.has(universe, tag)) {
246 if (universe[tag].touchedByAllowedPropertyRule === false) {
247 delete universe[tag];
251 return _.isEmpty(universe);
258 Drupal.filterConfiguration.update();
259 for (var filterID in Drupal.filterConfiguration.statuses) {
260 if (Drupal.filterConfiguration.statuses.hasOwnProperty(filterID)) {
261 var filterStatus = Drupal.filterConfiguration.statuses[filterID];
262 if (!filterStatusAllowsFeature(filterStatus, feature)) {
272 Drupal.EditorFeatureHTMLRule = function () {
273 this.required = { tags: [], attributes: [], styles: [], classes: [] };
275 this.allowed = { tags: [], attributes: [], styles: [], classes: [] };
280 Drupal.EditorFeature = function (name) {
285 Drupal.EditorFeature.prototype.addHTMLRule = function (rule) {
286 this.rules.push(rule);
289 Drupal.FilterStatus = function (name) {
297 Drupal.FilterStatus.prototype.addHTMLRule = function (rule) {
298 this.rules.push(rule);
301 Drupal.FilterHTMLRule = function () {
305 this.restrictedTags = {
307 allowed: { attributes: [], styles: [], classes: [] },
308 forbidden: { attributes: [], styles: [], classes: [] }
314 Drupal.FilterHTMLRule.prototype.clone = function () {
315 var clone = new Drupal.FilterHTMLRule();
316 clone.tags = this.tags.slice(0);
317 clone.allow = this.allow;
318 clone.restrictedTags.tags = this.restrictedTags.tags.slice(0);
319 clone.restrictedTags.allowed.attributes = this.restrictedTags.allowed.attributes.slice(0);
320 clone.restrictedTags.allowed.styles = this.restrictedTags.allowed.styles.slice(0);
321 clone.restrictedTags.allowed.classes = this.restrictedTags.allowed.classes.slice(0);
322 clone.restrictedTags.forbidden.attributes = this.restrictedTags.forbidden.attributes.slice(0);
323 clone.restrictedTags.forbidden.styles = this.restrictedTags.forbidden.styles.slice(0);
324 clone.restrictedTags.forbidden.classes = this.restrictedTags.forbidden.classes.slice(0);
328 Drupal.filterConfiguration = {
331 liveSettingParsers: {},
333 update: function update() {
334 for (var filterID in Drupal.filterConfiguration.statuses) {
335 if (Drupal.filterConfiguration.statuses.hasOwnProperty(filterID)) {
336 Drupal.filterConfiguration.statuses[filterID].active = $('[name="filters[' + filterID + '][status]"]').is(':checked');
338 if (Drupal.filterConfiguration.liveSettingParsers[filterID]) {
339 Drupal.filterConfiguration.statuses[filterID].rules = Drupal.filterConfiguration.liveSettingParsers[filterID].getRules();
346 Drupal.behaviors.initializeFilterConfiguration = {
347 attach: function attach(context, settings) {
348 var $context = $(context);
350 $context.find('#filters-status-wrapper input.form-checkbox').once('filter-editor-status').each(function () {
351 var $checkbox = $(this);
352 var nameAttribute = $checkbox.attr('name');
354 var filterID = nameAttribute.substring(8, nameAttribute.indexOf(']'));
356 Drupal.filterConfiguration.statuses[filterID] = new Drupal.FilterStatus(filterID);
360 })(jQuery, _, Drupal, document);