Loading core/modules/editor/editor.libraries.yml +0 −1 Original line number Diff line number Diff line Loading @@ -6,7 +6,6 @@ drupal.editor.admin: - core/jquery - core/once - core/drupal - core/internal.underscore drupal.editor: version: VERSION Loading core/modules/editor/js/editor.admin.es6.js +35 −24 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ * to automatically adjust their settings based on the editor configuration. */ (function ($, _, Drupal, document) { (function ($, Drupal, document) { /** * Editor configuration namespace. * Loading Loading @@ -226,7 +226,7 @@ ) { // If the tag does not exist in the universe, then it definitely can't // have this specific property value. if (!_.has(universe, tag)) { if (!universe.hasOwnProperty(tag)) { return false; } Loading @@ -240,8 +240,11 @@ } // The simple case: no wildcard in property value. if (_.indexOf(propertyValue, '*') === -1) { if (_.has(universe, tag) && _.has(universe[tag], key)) { if (propertyValue.indexOf('*') === -1) { if ( universe.hasOwnProperty(tag) && universe[tag].hasOwnProperty(key) ) { if (allowing) { universe[tag][key] = true; } Loading @@ -253,7 +256,7 @@ let atLeastOneFound = false; const regex = key.replace(/\*/g, '[^ ]*'); _.each(_.keys(universe[tag]), (key) => { Object.keys(universe[tag]).forEach((key) => { if (key.match(regex)) { atLeastOneFound = true; if (allowing) { Loading Loading @@ -286,7 +289,7 @@ allowing, ) { let atLeastOneFound = false; _.each(_.keys(universe), (tag) => { Object.keys(universe).forEach((tag) => { if ( // eslint-disable-next-line no-use-before-define findPropertyValuesOnTag( Loading Loading @@ -340,7 +343,7 @@ } let atLeastOneFound = false; _.each(propertyValues, (propertyValue) => { propertyValues.forEach((propertyValue) => { if ( findPropertyValueOnTag( universe, Loading @@ -367,7 +370,7 @@ */ function deleteAllTagsFromUniverseIfAllowed(universe) { let atLeastOneDeleted = false; _.each(_.keys(universe), (tag) => { Object.keys(universe).forEach((tag) => { // eslint-disable-next-line no-use-before-define if (deleteFromUniverseIfAllowed(universe, tag)) { atLeastOneDeleted = true; Loading @@ -394,8 +397,10 @@ return deleteAllTagsFromUniverseIfAllowed(universe); } if ( _.has(universe, tag) && _.every(_.omit(universe[tag], 'touchedByAllowedPropertyRule')) universe.hasOwnProperty(tag) && Object.keys(universe[tag]) .filter((key) => key !== 'touchedByAllowedPropertyRule') .every((key) => universe[tag][key]) ) { delete universe[tag]; return true; Loading @@ -419,12 +424,15 @@ const properties = ['attributes', 'styles', 'classes']; // Check if a tag in the universe is forbidden. const allRequiredTags = _.keys(universe); const allRequiredTags = Object.keys(universe); let filterRule; for (let i = 0; i < filterStatus.rules.length; i++) { filterRule = filterStatus.rules[i]; if (filterRule.allow === false) { if (_.intersection(allRequiredTags, filterRule.tags).length > 0) { const intersection = filterRule.tags.filter((tag) => allRequiredTags.includes(tag), ); if (intersection.length > 0) { return true; } } Loading Loading @@ -485,18 +493,18 @@ let tag; for ( let l = 0; !_.isEmpty(universe) && l < filterStatus.rules.length; Object.keys(universe).length > 0 && l < filterStatus.rules.length; l++ ) { filterRule = filterStatus.rules[l]; if (filterRule.allow === true) { for ( let m = 0; !_.isEmpty(universe) && m < filterRule.tags.length; Object.keys(universe).length > 0 && m < filterRule.tags.length; m++ ) { tag = filterRule.tags[m]; if (_.has(universe, tag)) { if (universe.hasOwnProperty(tag)) { universe[tag].tag = true; deleteFromUniverseIfAllowed(universe, tag); } Loading @@ -508,7 +516,7 @@ // For all filter rules… for ( let i = 0; !_.isEmpty(universe) && i < filterStatus.rules.length; Object.keys(universe).length > 0 && i < filterStatus.rules.length; i++ ) { filterRule = filterStatus.rules[i]; Loading @@ -520,7 +528,8 @@ // … for all those tags … for ( let j = 0; !_.isEmpty(universe) && j < filterRule.restrictedTags.tags.length; Object.keys(universe).length > 0 && j < filterRule.restrictedTags.tags.length; j++ ) { tag = filterRule.restrictedTags.tags[j]; Loading Loading @@ -604,17 +613,19 @@ // values and/or rules for forbidding tag property values. For details: // see the comments below. // @see generateUniverseFromFeatureRequirements() if (_.some(_.pluck(filterStatus.rules, 'allow'))) { if (filterStatus.rules.some(({ allow }) => allow)) { // If the universe is empty, then everything was explicitly allowed // and our job is done: this filter allows this feature! if (_.isEmpty(universe)) { if (Object.keys(universe).length === 0) { return true; } // Otherwise, it is still possible that this feature is allowed. // Every tag must be explicitly allowed if there are filter rules // doing tag whitelisting. if (!_.every(_.pluck(universe, 'tag'))) { if ( !Object.keys(universe).every((tagName) => universe[tagName].tag) ) { return false; } // Every tag was explicitly allowed, but since the universe is not Loading @@ -626,18 +637,18 @@ // matter that the properties: this could never have happened // anyway. It's only this late that we can know this for certain. const tags = _.keys(universe); const tags = Object.keys(universe); // Figure out if there was any rule applying whitelisting tag // restrictions to each of the remaining tags. for (let i = 0; i < tags.length; i++) { const tag = tags[i]; if (_.has(universe, tag)) { if (universe.hasOwnProperty(tag)) { if (universe[tag].touchedByAllowedPropertyRule === false) { delete universe[tag]; } } } return _.isEmpty(universe); return Object.keys(universe).length === 0; } // Otherwise, if all filter rules were doing blacklisting, then the sole // fact that we got to this point indicates that this filter allows for Loading Loading @@ -1023,4 +1034,4 @@ }); }, }; })(jQuery, _, Drupal, document); })(jQuery, Drupal, document); core/modules/editor/js/editor.admin.js +30 −33 Original line number Diff line number Diff line Loading @@ -5,7 +5,7 @@ * @preserve **/ (function ($, _, Drupal, document) { (function ($, Drupal, document) { Drupal.editorConfiguration = { addedFeature(feature) { $(document).trigger('drupalEditorFeatureAdded', feature); Loading Loading @@ -57,7 +57,7 @@ } function findPropertyValueOnTag(universe, tag, property, propertyValue, allowing) { if (!_.has(universe, tag)) { if (!universe.hasOwnProperty(tag)) { return false; } Loading @@ -67,8 +67,8 @@ universe[tag].touchedByAllowedPropertyRule = true; } if (_.indexOf(propertyValue, '*') === -1) { if (_.has(universe, tag) && _.has(universe[tag], key)) { if (propertyValue.indexOf('*') === -1) { if (universe.hasOwnProperty(tag) && universe[tag].hasOwnProperty(key)) { if (allowing) { universe[tag][key] = true; } Loading @@ -81,8 +81,7 @@ let atLeastOneFound = false; const regex = key.replace(/\*/g, '[^ ]*'); _.each(_.keys(universe[tag]), key => { Object.keys(universe[tag]).forEach(key => { if (key.match(regex)) { atLeastOneFound = true; Loading @@ -91,19 +90,16 @@ } } }); return atLeastOneFound; } function findPropertyValuesOnAllTags(universe, property, propertyValues, allowing) { let atLeastOneFound = false; _.each(_.keys(universe), tag => { Object.keys(universe).forEach(tag => { if (findPropertyValuesOnTag(universe, tag, property, propertyValues, allowing)) { atLeastOneFound = true; } }); return atLeastOneFound; } Loading @@ -113,25 +109,21 @@ } let atLeastOneFound = false; _.each(propertyValues, propertyValue => { propertyValues.forEach(propertyValue => { if (findPropertyValueOnTag(universe, tag, property, propertyValue, allowing)) { atLeastOneFound = true; } }); return atLeastOneFound; } function deleteAllTagsFromUniverseIfAllowed(universe) { let atLeastOneDeleted = false; _.each(_.keys(universe), tag => { Object.keys(universe).forEach(tag => { if (deleteFromUniverseIfAllowed(universe, tag)) { atLeastOneDeleted = true; } }); return atLeastOneDeleted; } Loading @@ -140,7 +132,7 @@ return deleteAllTagsFromUniverseIfAllowed(universe); } if (_.has(universe, tag) && _.every(_.omit(universe[tag], 'touchedByAllowedPropertyRule'))) { if (universe.hasOwnProperty(tag) && Object.keys(universe[tag]).filter(key => key !== 'touchedByAllowedPropertyRule').every(key => universe[tag][key])) { delete universe[tag]; return true; } Loading @@ -150,16 +142,16 @@ function anyForbiddenFilterRuleMatches(universe, filterStatus) { const properties = ['attributes', 'styles', 'classes']; const allRequiredTags = _.keys(universe); const allRequiredTags = Object.keys(universe); let filterRule; for (let i = 0; i < filterStatus.rules.length; i++) { filterRule = filterStatus.rules[i]; if (filterRule.allow === false) { if (_.intersection(allRequiredTags, filterRule.tags).length > 0) { const intersection = filterRule.tags.filter(tag => allRequiredTags.includes(tag)); if (intersection.length > 0) { return true; } } Loading Loading @@ -191,14 +183,14 @@ let filterRule; let tag; for (let l = 0; !_.isEmpty(universe) && l < filterStatus.rules.length; l++) { for (let l = 0; Object.keys(universe).length > 0 && l < filterStatus.rules.length; l++) { filterRule = filterStatus.rules[l]; if (filterRule.allow === true) { for (let m = 0; !_.isEmpty(universe) && m < filterRule.tags.length; m++) { for (let m = 0; Object.keys(universe).length > 0 && m < filterRule.tags.length; m++) { tag = filterRule.tags[m]; if (_.has(universe, tag)) { if (universe.hasOwnProperty(tag)) { universe[tag].tag = true; deleteFromUniverseIfAllowed(universe, tag); } Loading @@ -206,11 +198,11 @@ } } for (let i = 0; !_.isEmpty(universe) && i < filterStatus.rules.length; i++) { for (let i = 0; Object.keys(universe).length > 0 && i < filterStatus.rules.length; i++) { filterRule = filterStatus.rules[i]; if (filterRule.restrictedTags.tags.length && !emptyProperties(filterRule.restrictedTags.allowed)) { for (let j = 0; !_.isEmpty(universe) && j < filterRule.restrictedTags.tags.length; j++) { for (let j = 0; Object.keys(universe).length > 0 && j < filterRule.restrictedTags.tags.length; j++) { tag = filterRule.restrictedTags.tags[j]; for (let k = 0; k < properties.length; k++) { Loading Loading @@ -246,28 +238,33 @@ markAllowedTagsAndPropertyValues(universe, filterStatus); if (_.some(_.pluck(filterStatus.rules, 'allow'))) { if (_.isEmpty(universe)) { if (filterStatus.rules.some(_ref => { let { allow } = _ref; return allow; })) { if (Object.keys(universe).length === 0) { return true; } if (!_.every(_.pluck(universe, 'tag'))) { if (!Object.keys(universe).every(tagName => universe[tagName].tag)) { return false; } const tags = _.keys(universe); const tags = Object.keys(universe); for (let i = 0; i < tags.length; i++) { const tag = tags[i]; if (_.has(universe, tag)) { if (universe.hasOwnProperty(tag)) { if (universe[tag].touchedByAllowedPropertyRule === false) { delete universe[tag]; } } } return _.isEmpty(universe); return Object.keys(universe).length === 0; } return true; Loading Loading @@ -373,4 +370,4 @@ } }; })(jQuery, _, Drupal, document); No newline at end of file })(jQuery, Drupal, document); No newline at end of file core/modules/filter/filter.filter_html.admin.es6.js +72 −55 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ * Attaches behavior for updating filter_html's settings automatically. */ (function ($, Drupal, _, document) { (function ($, Drupal, document) { if (Drupal.filterConfiguration) { /** * Implement a live setting parser to prevent text editors from automatically Loading Loading @@ -35,6 +35,21 @@ }; } /** * Gets the values that are present in one array but not another. * * @param {Array[]} args * The list of arrays to process. * * @return {Array} * Returns the first array without the values present in other arrays. */ function difference(...args) { return args.reduce((mainData, otherData) => mainData.filter((data) => !otherData.includes(data)), ); } /** * Displays and updates what HTML tags are allowed to use in a filter. * Loading Loading @@ -99,9 +114,9 @@ // When the allowed tags list is manually changed, update userTags. that.$allowedHTMLFormItem.on('change.updateUserTags', function () { that.userTags = _.difference( that._parseSetting(this.value), that.autoTags, that.userTags = difference( Object.values(that._parseSetting(this.value)), Object.values(that.autoTags), ); }); }); Loading @@ -121,14 +136,18 @@ this.$allowedHTMLDescription.find('.editor-update-message').remove(); // If any auto-created tags: insert message and update form item. if (!_.isEmpty(this.autoTags)) { if (Object.keys(this.autoTags).length > 0) { this.$allowedHTMLDescription.append( Drupal.theme('filterFilterHTMLUpdateMessage', this.autoTags), ); const userTagsWithoutOverrides = _.omit( this.userTags, _.keys(this.autoTags), ); const userTagsWithoutOverrides = {}; Object.keys(this.userTags) .filter((tag) => !this.autoTags.hasOwnProperty(tag)) .forEach((tag) => { userTagsWithoutOverrides[tag] = this.userTags[tag]; }); this.$allowedHTMLFormItem.val( `${this._generateSetting( userTagsWithoutOverrides, Loading Loading @@ -171,7 +190,7 @@ featureRule = feature[f]; for (let t = 0; t < featureRule.required.tags.length; t++) { tag = featureRule.required.tags[t]; if (!_.has(editorRequiredTags, tag)) { if (!editorRequiredTags.hasOwnProperty(tag)) { filterRule = new Drupal.FilterHTMLRule(); filterRule.restrictedTags.tags = [tag]; // @todo Neither Drupal.FilterHtmlRule nor Loading @@ -191,14 +210,14 @@ // attributes. else { filterRule = editorRequiredTags[tag]; filterRule.restrictedTags.allowed.attributes = _.union( filterRule.restrictedTags.allowed.attributes, featureRule.required.attributes, ); filterRule.restrictedTags.allowed.classes = _.union( filterRule.restrictedTags.allowed.classes, featureRule.required.classes, ); filterRule.restrictedTags.allowed.attributes = [ ...filterRule.restrictedTags.allowed.attributes, ...featureRule.required.attributes, ]; filterRule.restrictedTags.allowed.classes = [ ...filterRule.restrictedTags.allowed.classes, ...featureRule.required.classes, ]; } } } Loading @@ -214,7 +233,7 @@ Object.keys(editorRequiredTags).forEach((tag) => { // If userAllowedTags does not contain a rule for this editor-required // tag, then add it to the list of automatically allowed tags. if (!_.has(userAllowedTags, tag)) { if (!userAllowedTags.hasOwnProperty(tag)) { autoAllowedTags[tag] = editorRequiredTags[tag]; } // Otherwise, if userAllowedTags already allows this tag, then check if Loading @@ -227,28 +246,28 @@ userAllowedTags[tag].restrictedTags.allowed.attributes; const needsAdditionalAttributes = requiredAttributes.length && _.difference(requiredAttributes, allowedAttributes).length; difference(requiredAttributes, allowedAttributes).length; const requiredClasses = editorRequiredTags[tag].restrictedTags.allowed.classes; const allowedClasses = userAllowedTags[tag].restrictedTags.allowed.classes; const needsAdditionalClasses = requiredClasses.length && _.difference(requiredClasses, allowedClasses).length; difference(requiredClasses, allowedClasses).length; if (needsAdditionalAttributes || needsAdditionalClasses) { autoAllowedTags[tag] = userAllowedTags[tag].clone(); } if (needsAdditionalAttributes) { autoAllowedTags[tag].restrictedTags.allowed.attributes = _.union( allowedAttributes, requiredAttributes, ); autoAllowedTags[tag].restrictedTags.allowed.attributes = [ ...allowedAttributes, ...requiredAttributes, ]; } if (needsAdditionalClasses) { autoAllowedTags[tag].restrictedTags.allowed.classes = _.union( allowedClasses, requiredClasses, ); autoAllowedTags[tag].restrictedTags.allowed.classes = [ ...allowedClasses, ...requiredClasses, ]; } } }); Loading Loading @@ -322,9 +341,9 @@ * The string representation of the setting. e.g. "<p> <br> <a>" */ _generateSetting(tags) { return _.reduce( tags, (setting, rule, tag) => { return Object.keys(tags).reduce((setting, tag) => { const rule = tags[tag]; if (setting.length) { setting += ' '; } Loading @@ -346,9 +365,7 @@ setting += '>'; return setting; }, '', ); }, ''); }, }; Loading @@ -373,4 +390,4 @@ html += '</p>'; return html; }; })(jQuery, Drupal, _, document); })(jQuery, Drupal, document); core/modules/filter/filter.filter_html.admin.js +27 −19 Original line number Diff line number Diff line Loading @@ -5,7 +5,7 @@ * @preserve **/ (function ($, Drupal, _, document) { (function ($, Drupal, document) { if (Drupal.filterConfiguration) { Drupal.filterConfiguration.liveSettingParsers.filter_html = { getRules() { Loading @@ -23,6 +23,14 @@ }; } function difference() { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return args.reduce((mainData, otherData) => mainData.filter(data => !otherData.includes(data))); } Drupal.behaviors.filterFilterHtmlUpdating = { $allowedHTMLFormItem: null, $allowedHTMLDescription: null, Loading Loading @@ -54,7 +62,7 @@ } }); that.$allowedHTMLFormItem.on('change.updateUserTags', function () { that.userTags = _.difference(that._parseSetting(this.value), that.autoTags); that.userTags = difference(Object.values(that._parseSetting(this.value)), Object.values(that.autoTags)); }); }); }, Loading @@ -63,11 +71,12 @@ this.autoTags = this._calculateAutoAllowedTags(this.userTags, this.newFeatures); this.$allowedHTMLDescription.find('.editor-update-message').remove(); if (!_.isEmpty(this.autoTags)) { if (Object.keys(this.autoTags).length > 0) { this.$allowedHTMLDescription.append(Drupal.theme('filterFilterHTMLUpdateMessage', this.autoTags)); const userTagsWithoutOverrides = _.omit(this.userTags, _.keys(this.autoTags)); const userTagsWithoutOverrides = {}; Object.keys(this.userTags).filter(tag => !this.autoTags.hasOwnProperty(tag)).forEach(tag => { userTagsWithoutOverrides[tag] = this.userTags[tag]; }); this.$allowedHTMLFormItem.val(`${this._generateSetting(userTagsWithoutOverrides)} ${this._generateSetting(this.autoTags)}`); } else { this.$allowedHTMLFormItem.val(this._generateSetting(this.userTags)); Loading @@ -88,7 +97,7 @@ for (let t = 0; t < featureRule.required.tags.length; t++) { tag = featureRule.required.tags[t]; if (!_.has(editorRequiredTags, tag)) { if (!editorRequiredTags.hasOwnProperty(tag)) { filterRule = new Drupal.FilterHTMLRule(); filterRule.restrictedTags.tags = [tag]; filterRule.restrictedTags.allowed.attributes = featureRule.required.attributes.slice(0); Loading @@ -96,37 +105,34 @@ editorRequiredTags[tag] = filterRule; } else { filterRule = editorRequiredTags[tag]; filterRule.restrictedTags.allowed.attributes = _.union(filterRule.restrictedTags.allowed.attributes, featureRule.required.attributes); filterRule.restrictedTags.allowed.classes = _.union(filterRule.restrictedTags.allowed.classes, featureRule.required.classes); filterRule.restrictedTags.allowed.attributes = [...filterRule.restrictedTags.allowed.attributes, ...featureRule.required.attributes]; filterRule.restrictedTags.allowed.classes = [...filterRule.restrictedTags.allowed.classes, ...featureRule.required.classes]; } } } }); const autoAllowedTags = {}; Object.keys(editorRequiredTags).forEach(tag => { if (!_.has(userAllowedTags, tag)) { if (!userAllowedTags.hasOwnProperty(tag)) { autoAllowedTags[tag] = editorRequiredTags[tag]; } else { const requiredAttributes = editorRequiredTags[tag].restrictedTags.allowed.attributes; const allowedAttributes = userAllowedTags[tag].restrictedTags.allowed.attributes; const needsAdditionalAttributes = requiredAttributes.length && _.difference(requiredAttributes, allowedAttributes).length; const needsAdditionalAttributes = requiredAttributes.length && difference(requiredAttributes, allowedAttributes).length; const requiredClasses = editorRequiredTags[tag].restrictedTags.allowed.classes; const allowedClasses = userAllowedTags[tag].restrictedTags.allowed.classes; const needsAdditionalClasses = requiredClasses.length && _.difference(requiredClasses, allowedClasses).length; const needsAdditionalClasses = requiredClasses.length && difference(requiredClasses, allowedClasses).length; if (needsAdditionalAttributes || needsAdditionalClasses) { autoAllowedTags[tag] = userAllowedTags[tag].clone(); } if (needsAdditionalAttributes) { autoAllowedTags[tag].restrictedTags.allowed.attributes = _.union(allowedAttributes, requiredAttributes); autoAllowedTags[tag].restrictedTags.allowed.attributes = [...allowedAttributes, ...requiredAttributes]; } if (needsAdditionalClasses) { autoAllowedTags[tag].restrictedTags.allowed.classes = _.union(allowedClasses, requiredClasses); autoAllowedTags[tag].restrictedTags.allowed.classes = [...allowedClasses, ...requiredClasses]; } } }); Loading Loading @@ -167,7 +173,9 @@ }, _generateSetting(tags) { return _.reduce(tags, (setting, rule, tag) => { return Object.keys(tags).reduce((setting, tag) => { const rule = tags[tag]; if (setting.length) { setting += ' '; } Loading Loading @@ -201,4 +209,4 @@ html += '</p>'; return html; }; })(jQuery, Drupal, _, document); No newline at end of file })(jQuery, Drupal, document); No newline at end of file Loading
core/modules/editor/editor.libraries.yml +0 −1 Original line number Diff line number Diff line Loading @@ -6,7 +6,6 @@ drupal.editor.admin: - core/jquery - core/once - core/drupal - core/internal.underscore drupal.editor: version: VERSION Loading
core/modules/editor/js/editor.admin.es6.js +35 −24 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ * to automatically adjust their settings based on the editor configuration. */ (function ($, _, Drupal, document) { (function ($, Drupal, document) { /** * Editor configuration namespace. * Loading Loading @@ -226,7 +226,7 @@ ) { // If the tag does not exist in the universe, then it definitely can't // have this specific property value. if (!_.has(universe, tag)) { if (!universe.hasOwnProperty(tag)) { return false; } Loading @@ -240,8 +240,11 @@ } // The simple case: no wildcard in property value. if (_.indexOf(propertyValue, '*') === -1) { if (_.has(universe, tag) && _.has(universe[tag], key)) { if (propertyValue.indexOf('*') === -1) { if ( universe.hasOwnProperty(tag) && universe[tag].hasOwnProperty(key) ) { if (allowing) { universe[tag][key] = true; } Loading @@ -253,7 +256,7 @@ let atLeastOneFound = false; const regex = key.replace(/\*/g, '[^ ]*'); _.each(_.keys(universe[tag]), (key) => { Object.keys(universe[tag]).forEach((key) => { if (key.match(regex)) { atLeastOneFound = true; if (allowing) { Loading Loading @@ -286,7 +289,7 @@ allowing, ) { let atLeastOneFound = false; _.each(_.keys(universe), (tag) => { Object.keys(universe).forEach((tag) => { if ( // eslint-disable-next-line no-use-before-define findPropertyValuesOnTag( Loading Loading @@ -340,7 +343,7 @@ } let atLeastOneFound = false; _.each(propertyValues, (propertyValue) => { propertyValues.forEach((propertyValue) => { if ( findPropertyValueOnTag( universe, Loading @@ -367,7 +370,7 @@ */ function deleteAllTagsFromUniverseIfAllowed(universe) { let atLeastOneDeleted = false; _.each(_.keys(universe), (tag) => { Object.keys(universe).forEach((tag) => { // eslint-disable-next-line no-use-before-define if (deleteFromUniverseIfAllowed(universe, tag)) { atLeastOneDeleted = true; Loading @@ -394,8 +397,10 @@ return deleteAllTagsFromUniverseIfAllowed(universe); } if ( _.has(universe, tag) && _.every(_.omit(universe[tag], 'touchedByAllowedPropertyRule')) universe.hasOwnProperty(tag) && Object.keys(universe[tag]) .filter((key) => key !== 'touchedByAllowedPropertyRule') .every((key) => universe[tag][key]) ) { delete universe[tag]; return true; Loading @@ -419,12 +424,15 @@ const properties = ['attributes', 'styles', 'classes']; // Check if a tag in the universe is forbidden. const allRequiredTags = _.keys(universe); const allRequiredTags = Object.keys(universe); let filterRule; for (let i = 0; i < filterStatus.rules.length; i++) { filterRule = filterStatus.rules[i]; if (filterRule.allow === false) { if (_.intersection(allRequiredTags, filterRule.tags).length > 0) { const intersection = filterRule.tags.filter((tag) => allRequiredTags.includes(tag), ); if (intersection.length > 0) { return true; } } Loading Loading @@ -485,18 +493,18 @@ let tag; for ( let l = 0; !_.isEmpty(universe) && l < filterStatus.rules.length; Object.keys(universe).length > 0 && l < filterStatus.rules.length; l++ ) { filterRule = filterStatus.rules[l]; if (filterRule.allow === true) { for ( let m = 0; !_.isEmpty(universe) && m < filterRule.tags.length; Object.keys(universe).length > 0 && m < filterRule.tags.length; m++ ) { tag = filterRule.tags[m]; if (_.has(universe, tag)) { if (universe.hasOwnProperty(tag)) { universe[tag].tag = true; deleteFromUniverseIfAllowed(universe, tag); } Loading @@ -508,7 +516,7 @@ // For all filter rules… for ( let i = 0; !_.isEmpty(universe) && i < filterStatus.rules.length; Object.keys(universe).length > 0 && i < filterStatus.rules.length; i++ ) { filterRule = filterStatus.rules[i]; Loading @@ -520,7 +528,8 @@ // … for all those tags … for ( let j = 0; !_.isEmpty(universe) && j < filterRule.restrictedTags.tags.length; Object.keys(universe).length > 0 && j < filterRule.restrictedTags.tags.length; j++ ) { tag = filterRule.restrictedTags.tags[j]; Loading Loading @@ -604,17 +613,19 @@ // values and/or rules for forbidding tag property values. For details: // see the comments below. // @see generateUniverseFromFeatureRequirements() if (_.some(_.pluck(filterStatus.rules, 'allow'))) { if (filterStatus.rules.some(({ allow }) => allow)) { // If the universe is empty, then everything was explicitly allowed // and our job is done: this filter allows this feature! if (_.isEmpty(universe)) { if (Object.keys(universe).length === 0) { return true; } // Otherwise, it is still possible that this feature is allowed. // Every tag must be explicitly allowed if there are filter rules // doing tag whitelisting. if (!_.every(_.pluck(universe, 'tag'))) { if ( !Object.keys(universe).every((tagName) => universe[tagName].tag) ) { return false; } // Every tag was explicitly allowed, but since the universe is not Loading @@ -626,18 +637,18 @@ // matter that the properties: this could never have happened // anyway. It's only this late that we can know this for certain. const tags = _.keys(universe); const tags = Object.keys(universe); // Figure out if there was any rule applying whitelisting tag // restrictions to each of the remaining tags. for (let i = 0; i < tags.length; i++) { const tag = tags[i]; if (_.has(universe, tag)) { if (universe.hasOwnProperty(tag)) { if (universe[tag].touchedByAllowedPropertyRule === false) { delete universe[tag]; } } } return _.isEmpty(universe); return Object.keys(universe).length === 0; } // Otherwise, if all filter rules were doing blacklisting, then the sole // fact that we got to this point indicates that this filter allows for Loading Loading @@ -1023,4 +1034,4 @@ }); }, }; })(jQuery, _, Drupal, document); })(jQuery, Drupal, document);
core/modules/editor/js/editor.admin.js +30 −33 Original line number Diff line number Diff line Loading @@ -5,7 +5,7 @@ * @preserve **/ (function ($, _, Drupal, document) { (function ($, Drupal, document) { Drupal.editorConfiguration = { addedFeature(feature) { $(document).trigger('drupalEditorFeatureAdded', feature); Loading Loading @@ -57,7 +57,7 @@ } function findPropertyValueOnTag(universe, tag, property, propertyValue, allowing) { if (!_.has(universe, tag)) { if (!universe.hasOwnProperty(tag)) { return false; } Loading @@ -67,8 +67,8 @@ universe[tag].touchedByAllowedPropertyRule = true; } if (_.indexOf(propertyValue, '*') === -1) { if (_.has(universe, tag) && _.has(universe[tag], key)) { if (propertyValue.indexOf('*') === -1) { if (universe.hasOwnProperty(tag) && universe[tag].hasOwnProperty(key)) { if (allowing) { universe[tag][key] = true; } Loading @@ -81,8 +81,7 @@ let atLeastOneFound = false; const regex = key.replace(/\*/g, '[^ ]*'); _.each(_.keys(universe[tag]), key => { Object.keys(universe[tag]).forEach(key => { if (key.match(regex)) { atLeastOneFound = true; Loading @@ -91,19 +90,16 @@ } } }); return atLeastOneFound; } function findPropertyValuesOnAllTags(universe, property, propertyValues, allowing) { let atLeastOneFound = false; _.each(_.keys(universe), tag => { Object.keys(universe).forEach(tag => { if (findPropertyValuesOnTag(universe, tag, property, propertyValues, allowing)) { atLeastOneFound = true; } }); return atLeastOneFound; } Loading @@ -113,25 +109,21 @@ } let atLeastOneFound = false; _.each(propertyValues, propertyValue => { propertyValues.forEach(propertyValue => { if (findPropertyValueOnTag(universe, tag, property, propertyValue, allowing)) { atLeastOneFound = true; } }); return atLeastOneFound; } function deleteAllTagsFromUniverseIfAllowed(universe) { let atLeastOneDeleted = false; _.each(_.keys(universe), tag => { Object.keys(universe).forEach(tag => { if (deleteFromUniverseIfAllowed(universe, tag)) { atLeastOneDeleted = true; } }); return atLeastOneDeleted; } Loading @@ -140,7 +132,7 @@ return deleteAllTagsFromUniverseIfAllowed(universe); } if (_.has(universe, tag) && _.every(_.omit(universe[tag], 'touchedByAllowedPropertyRule'))) { if (universe.hasOwnProperty(tag) && Object.keys(universe[tag]).filter(key => key !== 'touchedByAllowedPropertyRule').every(key => universe[tag][key])) { delete universe[tag]; return true; } Loading @@ -150,16 +142,16 @@ function anyForbiddenFilterRuleMatches(universe, filterStatus) { const properties = ['attributes', 'styles', 'classes']; const allRequiredTags = _.keys(universe); const allRequiredTags = Object.keys(universe); let filterRule; for (let i = 0; i < filterStatus.rules.length; i++) { filterRule = filterStatus.rules[i]; if (filterRule.allow === false) { if (_.intersection(allRequiredTags, filterRule.tags).length > 0) { const intersection = filterRule.tags.filter(tag => allRequiredTags.includes(tag)); if (intersection.length > 0) { return true; } } Loading Loading @@ -191,14 +183,14 @@ let filterRule; let tag; for (let l = 0; !_.isEmpty(universe) && l < filterStatus.rules.length; l++) { for (let l = 0; Object.keys(universe).length > 0 && l < filterStatus.rules.length; l++) { filterRule = filterStatus.rules[l]; if (filterRule.allow === true) { for (let m = 0; !_.isEmpty(universe) && m < filterRule.tags.length; m++) { for (let m = 0; Object.keys(universe).length > 0 && m < filterRule.tags.length; m++) { tag = filterRule.tags[m]; if (_.has(universe, tag)) { if (universe.hasOwnProperty(tag)) { universe[tag].tag = true; deleteFromUniverseIfAllowed(universe, tag); } Loading @@ -206,11 +198,11 @@ } } for (let i = 0; !_.isEmpty(universe) && i < filterStatus.rules.length; i++) { for (let i = 0; Object.keys(universe).length > 0 && i < filterStatus.rules.length; i++) { filterRule = filterStatus.rules[i]; if (filterRule.restrictedTags.tags.length && !emptyProperties(filterRule.restrictedTags.allowed)) { for (let j = 0; !_.isEmpty(universe) && j < filterRule.restrictedTags.tags.length; j++) { for (let j = 0; Object.keys(universe).length > 0 && j < filterRule.restrictedTags.tags.length; j++) { tag = filterRule.restrictedTags.tags[j]; for (let k = 0; k < properties.length; k++) { Loading Loading @@ -246,28 +238,33 @@ markAllowedTagsAndPropertyValues(universe, filterStatus); if (_.some(_.pluck(filterStatus.rules, 'allow'))) { if (_.isEmpty(universe)) { if (filterStatus.rules.some(_ref => { let { allow } = _ref; return allow; })) { if (Object.keys(universe).length === 0) { return true; } if (!_.every(_.pluck(universe, 'tag'))) { if (!Object.keys(universe).every(tagName => universe[tagName].tag)) { return false; } const tags = _.keys(universe); const tags = Object.keys(universe); for (let i = 0; i < tags.length; i++) { const tag = tags[i]; if (_.has(universe, tag)) { if (universe.hasOwnProperty(tag)) { if (universe[tag].touchedByAllowedPropertyRule === false) { delete universe[tag]; } } } return _.isEmpty(universe); return Object.keys(universe).length === 0; } return true; Loading Loading @@ -373,4 +370,4 @@ } }; })(jQuery, _, Drupal, document); No newline at end of file })(jQuery, Drupal, document); No newline at end of file
core/modules/filter/filter.filter_html.admin.es6.js +72 −55 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ * Attaches behavior for updating filter_html's settings automatically. */ (function ($, Drupal, _, document) { (function ($, Drupal, document) { if (Drupal.filterConfiguration) { /** * Implement a live setting parser to prevent text editors from automatically Loading Loading @@ -35,6 +35,21 @@ }; } /** * Gets the values that are present in one array but not another. * * @param {Array[]} args * The list of arrays to process. * * @return {Array} * Returns the first array without the values present in other arrays. */ function difference(...args) { return args.reduce((mainData, otherData) => mainData.filter((data) => !otherData.includes(data)), ); } /** * Displays and updates what HTML tags are allowed to use in a filter. * Loading Loading @@ -99,9 +114,9 @@ // When the allowed tags list is manually changed, update userTags. that.$allowedHTMLFormItem.on('change.updateUserTags', function () { that.userTags = _.difference( that._parseSetting(this.value), that.autoTags, that.userTags = difference( Object.values(that._parseSetting(this.value)), Object.values(that.autoTags), ); }); }); Loading @@ -121,14 +136,18 @@ this.$allowedHTMLDescription.find('.editor-update-message').remove(); // If any auto-created tags: insert message and update form item. if (!_.isEmpty(this.autoTags)) { if (Object.keys(this.autoTags).length > 0) { this.$allowedHTMLDescription.append( Drupal.theme('filterFilterHTMLUpdateMessage', this.autoTags), ); const userTagsWithoutOverrides = _.omit( this.userTags, _.keys(this.autoTags), ); const userTagsWithoutOverrides = {}; Object.keys(this.userTags) .filter((tag) => !this.autoTags.hasOwnProperty(tag)) .forEach((tag) => { userTagsWithoutOverrides[tag] = this.userTags[tag]; }); this.$allowedHTMLFormItem.val( `${this._generateSetting( userTagsWithoutOverrides, Loading Loading @@ -171,7 +190,7 @@ featureRule = feature[f]; for (let t = 0; t < featureRule.required.tags.length; t++) { tag = featureRule.required.tags[t]; if (!_.has(editorRequiredTags, tag)) { if (!editorRequiredTags.hasOwnProperty(tag)) { filterRule = new Drupal.FilterHTMLRule(); filterRule.restrictedTags.tags = [tag]; // @todo Neither Drupal.FilterHtmlRule nor Loading @@ -191,14 +210,14 @@ // attributes. else { filterRule = editorRequiredTags[tag]; filterRule.restrictedTags.allowed.attributes = _.union( filterRule.restrictedTags.allowed.attributes, featureRule.required.attributes, ); filterRule.restrictedTags.allowed.classes = _.union( filterRule.restrictedTags.allowed.classes, featureRule.required.classes, ); filterRule.restrictedTags.allowed.attributes = [ ...filterRule.restrictedTags.allowed.attributes, ...featureRule.required.attributes, ]; filterRule.restrictedTags.allowed.classes = [ ...filterRule.restrictedTags.allowed.classes, ...featureRule.required.classes, ]; } } } Loading @@ -214,7 +233,7 @@ Object.keys(editorRequiredTags).forEach((tag) => { // If userAllowedTags does not contain a rule for this editor-required // tag, then add it to the list of automatically allowed tags. if (!_.has(userAllowedTags, tag)) { if (!userAllowedTags.hasOwnProperty(tag)) { autoAllowedTags[tag] = editorRequiredTags[tag]; } // Otherwise, if userAllowedTags already allows this tag, then check if Loading @@ -227,28 +246,28 @@ userAllowedTags[tag].restrictedTags.allowed.attributes; const needsAdditionalAttributes = requiredAttributes.length && _.difference(requiredAttributes, allowedAttributes).length; difference(requiredAttributes, allowedAttributes).length; const requiredClasses = editorRequiredTags[tag].restrictedTags.allowed.classes; const allowedClasses = userAllowedTags[tag].restrictedTags.allowed.classes; const needsAdditionalClasses = requiredClasses.length && _.difference(requiredClasses, allowedClasses).length; difference(requiredClasses, allowedClasses).length; if (needsAdditionalAttributes || needsAdditionalClasses) { autoAllowedTags[tag] = userAllowedTags[tag].clone(); } if (needsAdditionalAttributes) { autoAllowedTags[tag].restrictedTags.allowed.attributes = _.union( allowedAttributes, requiredAttributes, ); autoAllowedTags[tag].restrictedTags.allowed.attributes = [ ...allowedAttributes, ...requiredAttributes, ]; } if (needsAdditionalClasses) { autoAllowedTags[tag].restrictedTags.allowed.classes = _.union( allowedClasses, requiredClasses, ); autoAllowedTags[tag].restrictedTags.allowed.classes = [ ...allowedClasses, ...requiredClasses, ]; } } }); Loading Loading @@ -322,9 +341,9 @@ * The string representation of the setting. e.g. "<p> <br> <a>" */ _generateSetting(tags) { return _.reduce( tags, (setting, rule, tag) => { return Object.keys(tags).reduce((setting, tag) => { const rule = tags[tag]; if (setting.length) { setting += ' '; } Loading @@ -346,9 +365,7 @@ setting += '>'; return setting; }, '', ); }, ''); }, }; Loading @@ -373,4 +390,4 @@ html += '</p>'; return html; }; })(jQuery, Drupal, _, document); })(jQuery, Drupal, document);
core/modules/filter/filter.filter_html.admin.js +27 −19 Original line number Diff line number Diff line Loading @@ -5,7 +5,7 @@ * @preserve **/ (function ($, Drupal, _, document) { (function ($, Drupal, document) { if (Drupal.filterConfiguration) { Drupal.filterConfiguration.liveSettingParsers.filter_html = { getRules() { Loading @@ -23,6 +23,14 @@ }; } function difference() { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return args.reduce((mainData, otherData) => mainData.filter(data => !otherData.includes(data))); } Drupal.behaviors.filterFilterHtmlUpdating = { $allowedHTMLFormItem: null, $allowedHTMLDescription: null, Loading Loading @@ -54,7 +62,7 @@ } }); that.$allowedHTMLFormItem.on('change.updateUserTags', function () { that.userTags = _.difference(that._parseSetting(this.value), that.autoTags); that.userTags = difference(Object.values(that._parseSetting(this.value)), Object.values(that.autoTags)); }); }); }, Loading @@ -63,11 +71,12 @@ this.autoTags = this._calculateAutoAllowedTags(this.userTags, this.newFeatures); this.$allowedHTMLDescription.find('.editor-update-message').remove(); if (!_.isEmpty(this.autoTags)) { if (Object.keys(this.autoTags).length > 0) { this.$allowedHTMLDescription.append(Drupal.theme('filterFilterHTMLUpdateMessage', this.autoTags)); const userTagsWithoutOverrides = _.omit(this.userTags, _.keys(this.autoTags)); const userTagsWithoutOverrides = {}; Object.keys(this.userTags).filter(tag => !this.autoTags.hasOwnProperty(tag)).forEach(tag => { userTagsWithoutOverrides[tag] = this.userTags[tag]; }); this.$allowedHTMLFormItem.val(`${this._generateSetting(userTagsWithoutOverrides)} ${this._generateSetting(this.autoTags)}`); } else { this.$allowedHTMLFormItem.val(this._generateSetting(this.userTags)); Loading @@ -88,7 +97,7 @@ for (let t = 0; t < featureRule.required.tags.length; t++) { tag = featureRule.required.tags[t]; if (!_.has(editorRequiredTags, tag)) { if (!editorRequiredTags.hasOwnProperty(tag)) { filterRule = new Drupal.FilterHTMLRule(); filterRule.restrictedTags.tags = [tag]; filterRule.restrictedTags.allowed.attributes = featureRule.required.attributes.slice(0); Loading @@ -96,37 +105,34 @@ editorRequiredTags[tag] = filterRule; } else { filterRule = editorRequiredTags[tag]; filterRule.restrictedTags.allowed.attributes = _.union(filterRule.restrictedTags.allowed.attributes, featureRule.required.attributes); filterRule.restrictedTags.allowed.classes = _.union(filterRule.restrictedTags.allowed.classes, featureRule.required.classes); filterRule.restrictedTags.allowed.attributes = [...filterRule.restrictedTags.allowed.attributes, ...featureRule.required.attributes]; filterRule.restrictedTags.allowed.classes = [...filterRule.restrictedTags.allowed.classes, ...featureRule.required.classes]; } } } }); const autoAllowedTags = {}; Object.keys(editorRequiredTags).forEach(tag => { if (!_.has(userAllowedTags, tag)) { if (!userAllowedTags.hasOwnProperty(tag)) { autoAllowedTags[tag] = editorRequiredTags[tag]; } else { const requiredAttributes = editorRequiredTags[tag].restrictedTags.allowed.attributes; const allowedAttributes = userAllowedTags[tag].restrictedTags.allowed.attributes; const needsAdditionalAttributes = requiredAttributes.length && _.difference(requiredAttributes, allowedAttributes).length; const needsAdditionalAttributes = requiredAttributes.length && difference(requiredAttributes, allowedAttributes).length; const requiredClasses = editorRequiredTags[tag].restrictedTags.allowed.classes; const allowedClasses = userAllowedTags[tag].restrictedTags.allowed.classes; const needsAdditionalClasses = requiredClasses.length && _.difference(requiredClasses, allowedClasses).length; const needsAdditionalClasses = requiredClasses.length && difference(requiredClasses, allowedClasses).length; if (needsAdditionalAttributes || needsAdditionalClasses) { autoAllowedTags[tag] = userAllowedTags[tag].clone(); } if (needsAdditionalAttributes) { autoAllowedTags[tag].restrictedTags.allowed.attributes = _.union(allowedAttributes, requiredAttributes); autoAllowedTags[tag].restrictedTags.allowed.attributes = [...allowedAttributes, ...requiredAttributes]; } if (needsAdditionalClasses) { autoAllowedTags[tag].restrictedTags.allowed.classes = _.union(allowedClasses, requiredClasses); autoAllowedTags[tag].restrictedTags.allowed.classes = [...allowedClasses, ...requiredClasses]; } } }); Loading Loading @@ -167,7 +173,9 @@ }, _generateSetting(tags) { return _.reduce(tags, (setting, rule, tag) => { return Object.keys(tags).reduce((setting, tag) => { const rule = tags[tag]; if (setting.length) { setting += ' '; } Loading Loading @@ -201,4 +209,4 @@ html += '</p>'; return html; }; })(jQuery, Drupal, _, document); No newline at end of file })(jQuery, Drupal, document); No newline at end of file