Chris@0: /** Chris@0: * DO NOT EDIT THIS FILE. Chris@0: * See the following change record for more information, Chris@0: * https://www.drupal.org/node/2815083 Chris@0: * @preserve Chris@0: **/ Chris@0: Chris@0: (function ($, _, Drupal, document) { Chris@0: Drupal.editorConfiguration = { Chris@0: addedFeature: function addedFeature(feature) { Chris@0: $(document).trigger('drupalEditorFeatureAdded', feature); Chris@0: }, Chris@0: removedFeature: function removedFeature(feature) { Chris@0: $(document).trigger('drupalEditorFeatureRemoved', feature); Chris@0: }, Chris@0: modifiedFeature: function modifiedFeature(feature) { Chris@0: $(document).trigger('drupalEditorFeatureModified', feature); Chris@0: }, Chris@0: featureIsAllowedByFilters: function featureIsAllowedByFilters(feature) { Chris@17: function emptyProperties(section) { Chris@17: return section.attributes.length === 0 && section.classes.length === 0 && section.styles.length === 0; Chris@17: } Chris@17: Chris@0: function generateUniverseFromFeatureRequirements(feature) { Chris@0: var properties = ['attributes', 'styles', 'classes']; Chris@0: var universe = {}; Chris@0: Chris@0: for (var r = 0; r < feature.rules.length; r++) { Chris@0: var featureRule = feature.rules[r]; Chris@0: Chris@0: var requiredTags = featureRule.required.tags; Chris@0: for (var t = 0; t < requiredTags.length; t++) { Chris@0: universe[requiredTags[t]] = { Chris@0: tag: false, Chris@0: Chris@0: touchedByAllowedPropertyRule: false, Chris@0: Chris@0: touchedBytouchedByForbiddenPropertyRule: false Chris@0: }; Chris@0: } Chris@0: Chris@0: if (emptyProperties(featureRule.required)) { Chris@0: continue; Chris@0: } Chris@0: Chris@0: for (var p = 0; p < properties.length; p++) { Chris@0: var property = properties[p]; Chris@0: for (var pv = 0; pv < featureRule.required[property].length; pv++) { Chris@0: var propertyValue = featureRule.required[property]; Chris@0: universe[requiredTags][property + ':' + propertyValue] = false; Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: return universe; Chris@0: } Chris@0: Chris@0: function findPropertyValueOnTag(universe, tag, property, propertyValue, allowing) { Chris@0: if (!_.has(universe, tag)) { Chris@0: return false; Chris@0: } Chris@0: Chris@0: var key = property + ':' + propertyValue; Chris@0: Chris@0: if (allowing) { Chris@0: universe[tag].touchedByAllowedPropertyRule = true; Chris@0: } Chris@0: Chris@0: if (_.indexOf(propertyValue, '*') === -1) { Chris@0: if (_.has(universe, tag) && _.has(universe[tag], key)) { Chris@0: if (allowing) { Chris@0: universe[tag][key] = true; Chris@0: } Chris@0: return true; Chris@0: } Chris@0: return false; Chris@0: } Chris@0: Chris@0: Chris@0: var atLeastOneFound = false; Chris@0: var regex = key.replace(/\*/g, '[^ ]*'); Chris@0: _.each(_.keys(universe[tag]), function (key) { Chris@0: if (key.match(regex)) { Chris@0: atLeastOneFound = true; Chris@0: if (allowing) { Chris@0: universe[tag][key] = true; Chris@0: } Chris@0: } Chris@0: }); Chris@0: return atLeastOneFound; Chris@0: } Chris@0: Chris@17: function findPropertyValuesOnAllTags(universe, property, propertyValues, allowing) { Chris@17: var atLeastOneFound = false; Chris@17: _.each(_.keys(universe), function (tag) { Chris@17: if (findPropertyValuesOnTag(universe, tag, property, propertyValues, allowing)) { Chris@17: atLeastOneFound = true; Chris@17: } Chris@17: }); Chris@17: return atLeastOneFound; Chris@17: } Chris@17: Chris@17: function findPropertyValuesOnTag(universe, tag, property, propertyValues, allowing) { Chris@0: if (tag === '*') { Chris@17: return findPropertyValuesOnAllTags(universe, property, propertyValues, allowing); Chris@0: } Chris@17: Chris@17: var atLeastOneFound = false; Chris@17: _.each(propertyValues, function (propertyValue) { Chris@17: if (findPropertyValueOnTag(universe, tag, property, propertyValue, allowing)) { Chris@17: atLeastOneFound = true; Chris@17: } Chris@17: }); Chris@17: return atLeastOneFound; Chris@0: } Chris@0: Chris@0: function deleteAllTagsFromUniverseIfAllowed(universe) { Chris@0: var atLeastOneDeleted = false; Chris@0: _.each(_.keys(universe), function (tag) { Chris@0: if (deleteFromUniverseIfAllowed(universe, tag)) { Chris@0: atLeastOneDeleted = true; Chris@0: } Chris@0: }); Chris@0: return atLeastOneDeleted; Chris@0: } Chris@0: Chris@17: function deleteFromUniverseIfAllowed(universe, tag) { Chris@17: if (tag === '*') { Chris@17: return deleteAllTagsFromUniverseIfAllowed(universe); Chris@17: } Chris@17: if (_.has(universe, tag) && _.every(_.omit(universe[tag], 'touchedByAllowedPropertyRule'))) { Chris@17: delete universe[tag]; Chris@17: return true; Chris@17: } Chris@17: return false; Chris@17: } Chris@17: Chris@0: function anyForbiddenFilterRuleMatches(universe, filterStatus) { Chris@0: var properties = ['attributes', 'styles', 'classes']; Chris@0: Chris@0: var allRequiredTags = _.keys(universe); Chris@0: var filterRule = void 0; Chris@0: for (var i = 0; i < filterStatus.rules.length; i++) { Chris@0: filterRule = filterStatus.rules[i]; Chris@0: if (filterRule.allow === false) { Chris@0: if (_.intersection(allRequiredTags, filterRule.tags).length > 0) { Chris@0: return true; Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: for (var n = 0; n < filterStatus.rules.length; n++) { Chris@0: filterRule = filterStatus.rules[n]; Chris@0: Chris@0: if (filterRule.restrictedTags.tags.length && !emptyProperties(filterRule.restrictedTags.forbidden)) { Chris@0: for (var j = 0; j < filterRule.restrictedTags.tags.length; j++) { Chris@0: var tag = filterRule.restrictedTags.tags[j]; Chris@0: Chris@0: for (var k = 0; k < properties.length; k++) { Chris@0: var property = properties[k]; Chris@0: Chris@0: if (findPropertyValuesOnTag(universe, tag, property, filterRule.restrictedTags.forbidden[property], false)) { Chris@0: return true; Chris@0: } Chris@0: } Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: return false; Chris@0: } Chris@0: Chris@0: function markAllowedTagsAndPropertyValues(universe, filterStatus) { Chris@0: var properties = ['attributes', 'styles', 'classes']; Chris@0: Chris@0: var filterRule = void 0; Chris@0: var tag = void 0; Chris@0: for (var l = 0; !_.isEmpty(universe) && l < filterStatus.rules.length; l++) { Chris@0: filterRule = filterStatus.rules[l]; Chris@0: if (filterRule.allow === true) { Chris@0: for (var m = 0; !_.isEmpty(universe) && m < filterRule.tags.length; m++) { Chris@0: tag = filterRule.tags[m]; Chris@0: if (_.has(universe, tag)) { Chris@0: universe[tag].tag = true; Chris@0: deleteFromUniverseIfAllowed(universe, tag); Chris@0: } Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: for (var i = 0; !_.isEmpty(universe) && i < filterStatus.rules.length; i++) { Chris@0: filterRule = filterStatus.rules[i]; Chris@0: Chris@0: if (filterRule.restrictedTags.tags.length && !emptyProperties(filterRule.restrictedTags.allowed)) { Chris@0: for (var j = 0; !_.isEmpty(universe) && j < filterRule.restrictedTags.tags.length; j++) { Chris@0: tag = filterRule.restrictedTags.tags[j]; Chris@0: Chris@0: for (var k = 0; k < properties.length; k++) { Chris@0: var property = properties[k]; Chris@0: Chris@0: if (findPropertyValuesOnTag(universe, tag, property, filterRule.restrictedTags.allowed[property], true)) { Chris@0: deleteFromUniverseIfAllowed(universe, tag); Chris@0: } Chris@0: } Chris@0: } Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: function filterStatusAllowsFeature(filterStatus, feature) { Chris@0: if (!filterStatus.active) { Chris@0: return true; Chris@0: } Chris@0: Chris@0: if (feature.rules.length === 0) { Chris@0: return true; Chris@0: } Chris@0: Chris@0: if (filterStatus.rules.length === 0) { Chris@0: return true; Chris@0: } Chris@0: Chris@0: var universe = generateUniverseFromFeatureRequirements(feature); Chris@0: Chris@0: if (anyForbiddenFilterRuleMatches(universe, filterStatus)) { Chris@0: return false; Chris@0: } Chris@0: Chris@0: markAllowedTagsAndPropertyValues(universe, filterStatus); Chris@0: Chris@0: if (_.some(_.pluck(filterStatus.rules, 'allow'))) { Chris@0: if (_.isEmpty(universe)) { Chris@0: return true; Chris@0: } Chris@0: Chris@0: if (!_.every(_.pluck(universe, 'tag'))) { Chris@0: return false; Chris@0: } Chris@0: Chris@0: Chris@0: var tags = _.keys(universe); Chris@0: Chris@0: for (var i = 0; i < tags.length; i++) { Chris@0: var tag = tags[i]; Chris@0: if (_.has(universe, tag)) { Chris@0: if (universe[tag].touchedByAllowedPropertyRule === false) { Chris@0: delete universe[tag]; Chris@0: } Chris@0: } Chris@0: } Chris@0: return _.isEmpty(universe); Chris@0: } Chris@0: Chris@0: Chris@0: return true; Chris@0: } Chris@0: Chris@0: Drupal.filterConfiguration.update(); Chris@17: return Object.keys(Drupal.filterConfiguration.statuses).every(function (filterID) { Chris@17: return filterStatusAllowsFeature(Drupal.filterConfiguration.statuses[filterID], feature); Chris@17: }); Chris@0: } Chris@0: }; Chris@0: Chris@0: Drupal.EditorFeatureHTMLRule = function () { Chris@17: this.required = { Chris@17: tags: [], Chris@17: attributes: [], Chris@17: styles: [], Chris@17: classes: [] Chris@17: }; Chris@0: Chris@17: this.allowed = { Chris@17: tags: [], Chris@17: attributes: [], Chris@17: styles: [], Chris@17: classes: [] Chris@17: }; Chris@0: Chris@0: this.raw = null; Chris@0: }; Chris@0: Chris@0: Drupal.EditorFeature = function (name) { Chris@0: this.name = name; Chris@0: this.rules = []; Chris@0: }; Chris@0: Chris@0: Drupal.EditorFeature.prototype.addHTMLRule = function (rule) { Chris@0: this.rules.push(rule); Chris@0: }; Chris@0: Chris@0: Drupal.FilterStatus = function (name) { Chris@0: this.name = name; Chris@0: Chris@0: this.active = false; Chris@0: Chris@0: this.rules = []; Chris@0: }; Chris@0: Chris@0: Drupal.FilterStatus.prototype.addHTMLRule = function (rule) { Chris@0: this.rules.push(rule); Chris@0: }; Chris@0: Chris@0: Drupal.FilterHTMLRule = function () { Chris@0: this.tags = []; Chris@0: this.allow = null; Chris@0: Chris@0: this.restrictedTags = { Chris@0: tags: [], Chris@0: allowed: { attributes: [], styles: [], classes: [] }, Chris@0: forbidden: { attributes: [], styles: [], classes: [] } Chris@0: }; Chris@0: Chris@0: return this; Chris@0: }; Chris@0: Chris@0: Drupal.FilterHTMLRule.prototype.clone = function () { Chris@0: var clone = new Drupal.FilterHTMLRule(); Chris@0: clone.tags = this.tags.slice(0); Chris@0: clone.allow = this.allow; Chris@0: clone.restrictedTags.tags = this.restrictedTags.tags.slice(0); Chris@0: clone.restrictedTags.allowed.attributes = this.restrictedTags.allowed.attributes.slice(0); Chris@0: clone.restrictedTags.allowed.styles = this.restrictedTags.allowed.styles.slice(0); Chris@0: clone.restrictedTags.allowed.classes = this.restrictedTags.allowed.classes.slice(0); Chris@0: clone.restrictedTags.forbidden.attributes = this.restrictedTags.forbidden.attributes.slice(0); Chris@0: clone.restrictedTags.forbidden.styles = this.restrictedTags.forbidden.styles.slice(0); Chris@0: clone.restrictedTags.forbidden.classes = this.restrictedTags.forbidden.classes.slice(0); Chris@0: return clone; Chris@0: }; Chris@0: Chris@0: Drupal.filterConfiguration = { Chris@0: statuses: {}, Chris@0: Chris@0: liveSettingParsers: {}, Chris@0: Chris@0: update: function update() { Chris@14: Object.keys(Drupal.filterConfiguration.statuses || {}).forEach(function (filterID) { Chris@14: Drupal.filterConfiguration.statuses[filterID].active = $('[name="filters[' + filterID + '][status]"]').is(':checked'); Chris@0: Chris@14: if (Drupal.filterConfiguration.liveSettingParsers[filterID]) { Chris@14: Drupal.filterConfiguration.statuses[filterID].rules = Drupal.filterConfiguration.liveSettingParsers[filterID].getRules(); Chris@0: } Chris@14: }); Chris@0: } Chris@0: }; Chris@0: Chris@0: Drupal.behaviors.initializeFilterConfiguration = { Chris@0: attach: function attach(context, settings) { Chris@0: var $context = $(context); Chris@0: Chris@0: $context.find('#filters-status-wrapper input.form-checkbox').once('filter-editor-status').each(function () { Chris@0: var $checkbox = $(this); Chris@0: var nameAttribute = $checkbox.attr('name'); Chris@0: Chris@0: var filterID = nameAttribute.substring(8, nameAttribute.indexOf(']')); Chris@0: Chris@0: Drupal.filterConfiguration.statuses[filterID] = new Drupal.FilterStatus(filterID); Chris@0: }); Chris@0: } Chris@0: }; Chris@0: })(jQuery, _, Drupal, document);