X-Git-Url: http://aleph1.co.uk/gitweb/?a=blobdiff_plain;f=web%2Fcore%2Fmodules%2Ffilter%2Ffilter.filter_html.admin.js;h=5f4c6ef9fad351c9f98aa9d617b364c96f368e75;hb=9424afc6c1f518c301bf87a23c047d1873435d05;hp=7ddca90bba847fb3871df55c25f9c0539623ee7a;hpb=a2bd1bf0c2c1f1a17d188f4dc0726a45494cefae;p=yaffs-website diff --git a/web/core/modules/filter/filter.filter_html.admin.js b/web/core/modules/filter/filter.filter_html.admin.js index 7ddca90bb..5f4c6ef9f 100644 --- a/web/core/modules/filter/filter.filter_html.admin.js +++ b/web/core/modules/filter/filter.filter_html.admin.js @@ -1,32 +1,17 @@ /** - * @file - * Attaches behavior for updating filter_html's settings automatically. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal, _, document) { - - 'use strict'; - if (Drupal.filterConfiguration) { - - /** - * Implement a live setting parser to prevent text editors from automatically - * enabling buttons that are not allowed by this filter's configuration. - * - * @namespace - */ Drupal.filterConfiguration.liveSettingParsers.filter_html = { - - /** - * @return {Array} - * An array of filter rules. - */ - getRules: function () { + getRules: function getRules() { var currentValue = $('#edit-filters-filter-html-settings-allowed-html').val(); var rules = Drupal.behaviors.filterFilterHtmlUpdating._parseSetting(currentValue); - // Build a FilterHTMLRule that reflects the hard-coded behavior that - // strips all "style" attribute and all "on*" attributes. var rule = new Drupal.FilterHTMLRule(); rule.restrictedTags.tags = ['*']; rule.restrictedTags.forbidden.attributes = ['style', 'on*']; @@ -37,232 +22,138 @@ }; } - /** - * Displays and updates what HTML tags are allowed to use in a filter. - * - * @type {Drupal~behavior} - * - * @todo Remove everything but 'attach' and 'detach' and make a proper object. - * - * @prop {Drupal~behaviorAttach} attach - * Attaches behavior for updating allowed HTML tags. - */ Drupal.behaviors.filterFilterHtmlUpdating = { - - // The form item contains the "Allowed HTML tags" setting. $allowedHTMLFormItem: null, - // The description for the "Allowed HTML tags" field. $allowedHTMLDescription: null, - /** - * The parsed, user-entered tag list of $allowedHTMLFormItem - * - * @var {Object.} - */ userTags: {}, - // The auto-created tag list thus far added. autoTags: null, - // Track which new features have been added to the text editor. newFeatures: {}, - attach: function (context, settings) { + attach: function attach(context, settings) { var that = this; $(context).find('[name="filters[filter_html][settings][allowed_html]"]').once('filter-filter_html-updating').each(function () { that.$allowedHTMLFormItem = $(this); that.$allowedHTMLDescription = that.$allowedHTMLFormItem.closest('.js-form-item').find('.description'); that.userTags = that._parseSetting(this.value); - // Update the new allowed tags based on added text editor features. - $(document) - .on('drupalEditorFeatureAdded', function (e, feature) { + $(document).on('drupalEditorFeatureAdded', function (e, feature) { + that.newFeatures[feature.name] = feature.rules; + that._updateAllowedTags(); + }).on('drupalEditorFeatureModified', function (e, feature) { + if (that.newFeatures.hasOwnProperty(feature.name)) { that.newFeatures[feature.name] = feature.rules; that._updateAllowedTags(); - }) - .on('drupalEditorFeatureModified', function (e, feature) { - if (that.newFeatures.hasOwnProperty(feature.name)) { - that.newFeatures[feature.name] = feature.rules; - that._updateAllowedTags(); - } - }) - .on('drupalEditorFeatureRemoved', function (e, feature) { - if (that.newFeatures.hasOwnProperty(feature.name)) { - delete that.newFeatures[feature.name]; - that._updateAllowedTags(); - } - }); + } + }).on('drupalEditorFeatureRemoved', function (e, feature) { + if (that.newFeatures.hasOwnProperty(feature.name)) { + delete that.newFeatures[feature.name]; + that._updateAllowedTags(); + } + }); - // 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); }); }); }, - - /** - * Updates the "Allowed HTML tags" setting and shows an informative message. - */ - _updateAllowedTags: function () { - // Update the list of auto-created tags. + _updateAllowedTags: function _updateAllowedTags() { this.autoTags = this._calculateAutoAllowedTags(this.userTags, this.newFeatures); - // Remove any previous auto-created tag message. this.$allowedHTMLDescription.find('.editor-update-message').remove(); - // If any auto-created tags: insert message and update form item. if (!_.isEmpty(this.autoTags)) { this.$allowedHTMLDescription.append(Drupal.theme('filterFilterHTMLUpdateMessage', this.autoTags)); var userTagsWithoutOverrides = _.omit(this.userTags, _.keys(this.autoTags)); this.$allowedHTMLFormItem.val(this._generateSetting(userTagsWithoutOverrides) + ' ' + this._generateSetting(this.autoTags)); - } - // Restore to original state. - else { - this.$allowedHTMLFormItem.val(this._generateSetting(this.userTags)); - } + } else { + this.$allowedHTMLFormItem.val(this._generateSetting(this.userTags)); + } }, - - /** - * Calculates which HTML tags the added text editor buttons need to work. - * - * The filter_html filter is only concerned with the required tags, not with - * any properties, nor with each feature's "allowed" tags. - * - * @param {Array} userAllowedTags - * The list of user-defined allowed tags. - * @param {object} newFeatures - * A list of {@link Drupal.EditorFeature} objects' rules, keyed by - * their name. - * - * @return {Array} - * A list of new allowed tags. - */ - _calculateAutoAllowedTags: function (userAllowedTags, newFeatures) { - var featureName; - var feature; - var featureRule; - var filterRule; - var tag; + _calculateAutoAllowedTags: function _calculateAutoAllowedTags(userAllowedTags, newFeatures) { var editorRequiredTags = {}; - // Map the newly added Text Editor features to Drupal.FilterHtmlRule - // objects (to allow comparing userTags with autoTags). - for (featureName in newFeatures) { - if (newFeatures.hasOwnProperty(featureName)) { - feature = newFeatures[featureName]; - for (var f = 0; f < feature.length; f++) { - featureRule = feature[f]; - for (var t = 0; t < featureRule.required.tags.length; t++) { - tag = featureRule.required.tags[t]; - if (!_.has(editorRequiredTags, tag)) { - filterRule = new Drupal.FilterHTMLRule(); - filterRule.restrictedTags.tags = [tag]; - // @todo Neither Drupal.FilterHtmlRule nor - // Drupal.EditorFeatureHTMLRule allow for generic attribute - // value restrictions, only for the "class" and "style" - // attribute's values to be restricted. The filter_html filter - // always disallows the "style" attribute, so we only need to - // support "class" attribute value restrictions. Fix once - // https://www.drupal.org/node/2567801 lands. - filterRule.restrictedTags.allowed.attributes = featureRule.required.attributes.slice(0); - filterRule.restrictedTags.allowed.classes = featureRule.required.classes.slice(0); - editorRequiredTags[tag] = filterRule; - } - // The tag is already allowed, add any additionally allowed - // attributes. - else { + + Object.keys(newFeatures || {}).forEach(function (featureName) { + var feature = newFeatures[featureName]; + var featureRule = void 0; + var filterRule = void 0; + var tag = void 0; + + for (var f = 0; f < feature.length; f++) { + featureRule = feature[f]; + for (var t = 0; t < featureRule.required.tags.length; t++) { + tag = featureRule.required.tags[t]; + if (!_.has(editorRequiredTags, tag)) { + filterRule = new Drupal.FilterHTMLRule(); + filterRule.restrictedTags.tags = [tag]; + + filterRule.restrictedTags.allowed.attributes = featureRule.required.attributes.slice(0); + filterRule.restrictedTags.allowed.classes = featureRule.required.classes.slice(0); + 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); } - } } } - } + }); - // Now compare userAllowedTags with editorRequiredTags, and build - // autoAllowedTags, which contains: - // - any tags in editorRequiredTags but not in userAllowedTags (i.e. tags - // that are additionally going to be allowed) - // - any tags in editorRequiredTags that already exists in userAllowedTags - // but does not allow all attributes or attribute values var autoAllowedTags = {}; - for (tag in editorRequiredTags) { - // If userAllowedTags does not contain a rule for this editor-required - // tag, then add it to the list of automatically allowed tags. + Object.keys(editorRequiredTags).forEach(function (tag) { if (!_.has(userAllowedTags, tag)) { autoAllowedTags[tag] = editorRequiredTags[tag]; - } - // Otherwise, if userAllowedTags already allows this tag, then check if - // additional attributes and classes on this tag are required by the - // editor. - else { - var requiredAttributes = editorRequiredTags[tag].restrictedTags.allowed.attributes; - var allowedAttributes = userAllowedTags[tag].restrictedTags.allowed.attributes; - var needsAdditionalAttributes = requiredAttributes.length && _.difference(requiredAttributes, allowedAttributes).length; - var requiredClasses = editorRequiredTags[tag].restrictedTags.allowed.classes; - var allowedClasses = userAllowedTags[tag].restrictedTags.allowed.classes; - var 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); - } - if (needsAdditionalClasses) { - autoAllowedTags[tag].restrictedTags.allowed.classes = _.union(allowedClasses, requiredClasses); + } else { + var requiredAttributes = editorRequiredTags[tag].restrictedTags.allowed.attributes; + var allowedAttributes = userAllowedTags[tag].restrictedTags.allowed.attributes; + var needsAdditionalAttributes = requiredAttributes.length && _.difference(requiredAttributes, allowedAttributes).length; + var requiredClasses = editorRequiredTags[tag].restrictedTags.allowed.classes; + var allowedClasses = userAllowedTags[tag].restrictedTags.allowed.classes; + var 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); + } + if (needsAdditionalClasses) { + autoAllowedTags[tag].restrictedTags.allowed.classes = _.union(allowedClasses, requiredClasses); + } } - } - } + }); return autoAllowedTags; }, - - /** - * Parses the value of this.$allowedHTMLFormItem. - * - * @param {string} setting - * The string representation of the setting. For example: - *


- * - * @return {Object.} - * The corresponding text filter HTML rule objects, one per tag, keyed by - * tag name. - */ - _parseSetting: function (setting) { - var node; - var tag; - var rule; - var attributes; - var attribute; + _parseSetting: function _parseSetting(setting) { + var node = void 0; + var tag = void 0; + var rule = void 0; + var attributes = void 0; + var attribute = void 0; var allowedTags = setting.match(/(<[^>]+>)/g); var sandbox = document.createElement('div'); var rules = {}; for (var t = 0; t < allowedTags.length; t++) { - // Let the browser do the parsing work for us. sandbox.innerHTML = allowedTags[t]; node = sandbox.firstChild; tag = node.tagName.toLowerCase(); - // Build the Drupal.FilterHtmlRule object. rule = new Drupal.FilterHTMLRule(); - // We create one rule per allowed tag, so always one tag. + rule.restrictedTags.tags = [tag]; - // Add the attribute restrictions. + attributes = node.attributes; for (var i = 0; i < attributes.length; i++) { attribute = attributes.item(i); var attributeName = attribute.nodeName; - // @todo Drupal.FilterHtmlRule does not allow for generic attribute - // value restrictions, only for the "class" and "style" attribute's - // values. The filter_html filter always disallows the "style" - // attribute, so we only need to support "class" attribute value - // restrictions. Fix once https://www.drupal.org/node/2567801 lands. + if (attributeName === 'class') { var attributeValue = attribute.textContent; rule.restrictedTags.allowed.classes = attributeValue.split(' '); - } - else { + } else { rule.restrictedTags.allowed.attributes.push(attributeName); } } @@ -271,17 +162,7 @@ } return rules; }, - - /** - * Generates the value of this.$allowedHTMLFormItem. - * - * @param {Object.} tags - * The parsed representation of the setting. - * - * @return {Array} - * The string representation of the setting. e.g. "


" - */ - _generateSetting: function (tags) { + _generateSetting: function _generateSetting(tags) { return _.reduce(tags, function (setting, rule, tag) { if (setting.length) { setting += ' '; @@ -291,11 +172,7 @@ if (rule.restrictedTags.allowed.attributes.length) { setting += ' ' + rule.restrictedTags.allowed.attributes.join(' '); } - // @todo Drupal.FilterHtmlRule does not allow for generic attribute - // value restrictions, only for the "class" and "style" attribute's - // values. The filter_html filter always disallows the "style" - // attribute, so we only need to support "class" attribute value - // restrictions. Fix once https://www.drupal.org/node/2567801 lands. + if (rule.restrictedTags.allowed.classes.length) { setting += ' class="' + rule.restrictedTags.allowed.classes.join(' ') + '"'; } @@ -304,25 +181,14 @@ return setting; }, ''); } - }; - /** - * Theme function for the filter_html update message. - * - * @param {Array} tags - * An array of the new tags that are to be allowed. - * - * @return {string} - * The corresponding HTML. - */ Drupal.theme.filterFilterHTMLUpdateMessage = function (tags) { var html = ''; var tagList = Drupal.behaviors.filterFilterHtmlUpdating._generateSetting(tags); html += '

'; - html += Drupal.t('Based on the text editor configuration, these tags have automatically been added: @tag-list.', {'@tag-list': tagList}); + html += Drupal.t('Based on the text editor configuration, these tags have automatically been added: @tag-list.', { '@tag-list': tagList }); html += '

'; return html; }; - -})(jQuery, Drupal, _, document); +})(jQuery, Drupal, _, document); \ No newline at end of file