* to automatically adjust their settings based on the editor configuration.
*/
-(function ($, _, Drupal, document) {
+(function($, _, Drupal, document) {
/**
* Editor configuration namespace.
*
* @namespace
*/
Drupal.editorConfiguration = {
-
/**
* Must be called by a specific text editor's configuration whenever a
* feature is added by the user.
* Whether the given feature is allowed by the current filters.
*/
featureIsAllowedByFilters(feature) {
+ /**
+ * Provided a section of a feature or filter rule, checks if no property
+ * values are defined for all properties: attributes, classes and styles.
+ *
+ * @param {object} section
+ * The section to check.
+ *
+ * @return {bool}
+ * Returns true if the section has empty properties, false otherwise.
+ */
+ function emptyProperties(section) {
+ return (
+ section.attributes.length === 0 &&
+ section.classes.length === 0 &&
+ section.styles.length === 0
+ );
+ }
+
/**
* Generate the universe U of possible values that can result from the
* feature's rules' requirements.
}
/**
- * Provided a section of a feature or filter rule, checks if no property
- * values are defined for all properties: attributes, classes and styles.
- *
- * @param {object} section
- * The section to check.
- *
- * @return {bool}
- * Returns true if the section has empty properties, false otherwise.
- */
- function emptyProperties(section) {
- return section.attributes.length === 0 && section.classes.length === 0 && section.styles.length === 0;
- }
-
- /**
- * Calls findPropertyValueOnTag on the given tag for every property value
- * that is listed in the "propertyValues" parameter. Supports the wildcard
- * tag.
+ * Finds out if a specific property value (potentially containing
+ * wildcards) exists on the given tag. When the "allowing" parameter
+ * equals true, the universe will be updated if that specific property
+ * value exists. Returns true if found, false otherwise.
*
* @param {object} universe
* The universe to check.
* The tag to look for.
* @param {string} property
* The property to check.
- * @param {Array} propertyValues
- * Values of the property to check.
+ * @param {string} propertyValue
+ * The property value to check.
* @param {bool} allowing
* Whether to update the universe or not.
*
* @return {bool}
* Returns true if found, false otherwise.
*/
- function findPropertyValuesOnTag(universe, tag, property, propertyValues, allowing) {
- // Detect the wildcard case.
- if (tag === '*') {
- return findPropertyValuesOnAllTags(universe, property, propertyValues, allowing);
+ function findPropertyValueOnTag(
+ universe,
+ tag,
+ property,
+ propertyValue,
+ allowing,
+ ) {
+ // If the tag does not exist in the universe, then it definitely can't
+ // have this specific property value.
+ if (!_.has(universe, tag)) {
+ return false;
}
+ const key = `${property}:${propertyValue}`;
+
+ // Track whether a tag was touched by a filter rule that allows specific
+ // property values on this particular tag.
+ // @see generateUniverseFromFeatureRequirements
+ if (allowing) {
+ universe[tag].touchedByAllowedPropertyRule = true;
+ }
+
+ // The simple case: no wildcard in property value.
+ if (_.indexOf(propertyValue, '*') === -1) {
+ if (_.has(universe, tag) && _.has(universe[tag], key)) {
+ if (allowing) {
+ universe[tag][key] = true;
+ }
+ return true;
+ }
+ return false;
+ }
+ // The complex case: wildcard in property value.
+
let atLeastOneFound = false;
- _.each(propertyValues, (propertyValue) => {
- if (findPropertyValueOnTag(universe, tag, property, propertyValue, allowing)) {
+ const regex = key.replace(/\*/g, '[^ ]*');
+ _.each(_.keys(universe[tag]), key => {
+ if (key.match(regex)) {
atLeastOneFound = true;
+ if (allowing) {
+ universe[tag][key] = true;
+ }
}
});
return atLeastOneFound;
* @return {bool}
* Returns true if found, false otherwise.
*/
- function findPropertyValuesOnAllTags(universe, property, propertyValues, allowing) {
+ function findPropertyValuesOnAllTags(
+ universe,
+ property,
+ propertyValues,
+ allowing,
+ ) {
let atLeastOneFound = false;
- _.each(_.keys(universe), (tag) => {
- if (findPropertyValuesOnTag(universe, tag, property, propertyValues, allowing)) {
+ _.each(_.keys(universe), tag => {
+ if (
+ // eslint-disable-next-line no-use-before-define
+ findPropertyValuesOnTag(
+ universe,
+ tag,
+ property,
+ propertyValues,
+ allowing,
+ )
+ ) {
atLeastOneFound = true;
}
});
}
/**
- * Finds out if a specific property value (potentially containing
- * wildcards) exists on the given tag. When the "allowing" parameter
- * equals true, the universe will be updated if that specific property
- * value exists. Returns true if found, false otherwise.
+ * Calls findPropertyValueOnTag on the given tag for every property value
+ * that is listed in the "propertyValues" parameter. Supports the wildcard
+ * tag.
*
* @param {object} universe
* The universe to check.
* The tag to look for.
* @param {string} property
* The property to check.
- * @param {string} propertyValue
- * The property value to check.
+ * @param {Array} propertyValues
+ * Values of the property to check.
* @param {bool} allowing
* Whether to update the universe or not.
*
* @return {bool}
* Returns true if found, false otherwise.
*/
- function findPropertyValueOnTag(universe, tag, property, propertyValue, allowing) {
- // If the tag does not exist in the universe, then it definitely can't
- // have this specific property value.
- if (!_.has(universe, tag)) {
- return false;
- }
-
- const key = `${property}:${propertyValue}`;
-
- // Track whether a tag was touched by a filter rule that allows specific
- // property values on this particular tag.
- // @see generateUniverseFromFeatureRequirements
- if (allowing) {
- universe[tag].touchedByAllowedPropertyRule = true;
- }
-
- // The simple case: no wildcard in property value.
- if (_.indexOf(propertyValue, '*') === -1) {
- if (_.has(universe, tag) && _.has(universe[tag], key)) {
- if (allowing) {
- universe[tag][key] = true;
- }
- return true;
- }
- return false;
+ function findPropertyValuesOnTag(
+ universe,
+ tag,
+ property,
+ propertyValues,
+ allowing,
+ ) {
+ // Detect the wildcard case.
+ if (tag === '*') {
+ return findPropertyValuesOnAllTags(
+ universe,
+ property,
+ propertyValues,
+ allowing,
+ );
}
- // The complex case: wildcard in property value.
let atLeastOneFound = false;
- const regex = key.replace(/\*/g, '[^ ]*');
- _.each(_.keys(universe[tag]), (key) => {
- if (key.match(regex)) {
+ _.each(propertyValues, propertyValue => {
+ if (
+ findPropertyValueOnTag(
+ universe,
+ tag,
+ property,
+ propertyValue,
+ allowing,
+ )
+ ) {
atLeastOneFound = true;
- if (allowing) {
- universe[tag][key] = true;
- }
}
});
return atLeastOneFound;
}
+ /**
+ * Calls deleteFromUniverseIfAllowed for all tags in the universe.
+ *
+ * @param {object} universe
+ * The universe to delete from.
+ *
+ * @return {bool}
+ * Whether something was deleted from the universe.
+ */
+ function deleteAllTagsFromUniverseIfAllowed(universe) {
+ let atLeastOneDeleted = false;
+ _.each(_.keys(universe), tag => {
+ // eslint-disable-next-line no-use-before-define
+ if (deleteFromUniverseIfAllowed(universe, tag)) {
+ atLeastOneDeleted = true;
+ }
+ });
+ return atLeastOneDeleted;
+ }
+
/**
* Deletes a tag from the universe if the tag itself and each of its
* properties are marked as allowed.
if (tag === '*') {
return deleteAllTagsFromUniverseIfAllowed(universe);
}
- if (_.has(universe, tag) && _.every(_.omit(universe[tag], 'touchedByAllowedPropertyRule'))) {
+ if (
+ _.has(universe, tag) &&
+ _.every(_.omit(universe[tag], 'touchedByAllowedPropertyRule'))
+ ) {
delete universe[tag];
return true;
}
return false;
}
- /**
- * Calls deleteFromUniverseIfAllowed for all tags in the universe.
- *
- * @param {object} universe
- * The universe to delete from.
- *
- * @return {bool}
- * Whether something was deleted from the universe.
- */
- function deleteAllTagsFromUniverseIfAllowed(universe) {
- let atLeastOneDeleted = false;
- _.each(_.keys(universe), (tag) => {
- if (deleteFromUniverseIfAllowed(universe, tag)) {
- atLeastOneDeleted = true;
- }
- });
- return atLeastOneDeleted;
- }
-
/**
* Checks if any filter rule forbids either a tag or a tag property value
* that exists in the universe.
for (let n = 0; n < filterStatus.rules.length; n++) {
filterRule = filterStatus.rules[n];
// … if there are tags with restricted property values …
- if (filterRule.restrictedTags.tags.length && !emptyProperties(filterRule.restrictedTags.forbidden)) {
+ if (
+ filterRule.restrictedTags.tags.length &&
+ !emptyProperties(filterRule.restrictedTags.forbidden)
+ ) {
// … for all those tags …
for (let j = 0; j < filterRule.restrictedTags.tags.length; j++) {
const tag = filterRule.restrictedTags.tags[j];
const property = properties[k];
// … and return true if just one of the forbidden property
// values for this tag and property is listed in the universe.
- if (findPropertyValuesOnTag(universe, tag, property, filterRule.restrictedTags.forbidden[property], false)) {
+ if (
+ findPropertyValuesOnTag(
+ universe,
+ tag,
+ property,
+ filterRule.restrictedTags.forbidden[property],
+ false,
+ )
+ ) {
return true;
}
}
// Check if a tag in the universe is allowed.
let filterRule;
let tag;
- for (let l = 0; !_.isEmpty(universe) && l < filterStatus.rules.length; l++) {
+ for (
+ let l = 0;
+ !_.isEmpty(universe) && 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;
+ !_.isEmpty(universe) && m < filterRule.tags.length;
+ m++
+ ) {
tag = filterRule.tags[m];
if (_.has(universe, tag)) {
universe[tag].tag = true;
// Check if a property value of a tag in the universe is allowed.
// For all filter rules…
- for (let i = 0; !_.isEmpty(universe) && i < filterStatus.rules.length; i++) {
+ for (
+ let i = 0;
+ !_.isEmpty(universe) && i < filterStatus.rules.length;
+ i++
+ ) {
filterRule = filterStatus.rules[i];
// … if there are tags with restricted property values …
- if (filterRule.restrictedTags.tags.length && !emptyProperties(filterRule.restrictedTags.allowed)) {
+ if (
+ filterRule.restrictedTags.tags.length &&
+ !emptyProperties(filterRule.restrictedTags.allowed)
+ ) {
// … for all those tags …
- for (let j = 0; !_.isEmpty(universe) && j < filterRule.restrictedTags.tags.length; j++) {
+ for (
+ let j = 0;
+ !_.isEmpty(universe) && j < filterRule.restrictedTags.tags.length;
+ j++
+ ) {
tag = filterRule.restrictedTags.tags[j];
// … then iterate over all properties …
for (let k = 0; k < properties.length; k++) {
// of the allowed property values for this tag and property is
// listed in the universe. (Because everything might be allowed
// now.)
- if (findPropertyValuesOnTag(universe, tag, property, filterRule.restrictedTags.allowed[property], true)) {
+ if (
+ findPropertyValuesOnTag(
+ universe,
+ tag,
+ property,
+ filterRule.restrictedTags.allowed[property],
+ true,
+ )
+ ) {
deleteFromUniverseIfAllowed(universe, tag);
}
}
}
// Otherwise, it is still possible that this feature is allowed.
- // Every tag must be explicitly allowed if there are filter rules
- // doing tag whitelisting.
+ // Every tag must be explicitly allowed if there are filter rules
+ // doing tag whitelisting.
if (!_.every(_.pluck(universe, 'tag'))) {
return false;
}
- // Every tag was explicitly allowed, but since the universe is not
- // empty, one or more tag properties are disallowed. However, if
- // only blacklisting of tag properties was applied to these tags,
- // and no whitelisting was ever applied, then it's still fine:
- // since none of the tag properties were blacklisted, we got to
- // this point, and since no whitelisting was applied, it doesn't
- // matter that the properties: this could never have happened
- // anyway. It's only this late that we can know this for certain.
+ // Every tag was explicitly allowed, but since the universe is not
+ // empty, one or more tag properties are disallowed. However, if
+ // only blacklisting of tag properties was applied to these tags,
+ // and no whitelisting was ever applied, then it's still fine:
+ // since none of the tag properties were blacklisted, we got to
+ // this point, and since no whitelisting was applied, it doesn't
+ // 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);
- // Figure out if there was any rule applying whitelisting tag
- // restrictions to each of the remaining tags.
+ // 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 any filter's current status forbids the editor feature, return
// false.
Drupal.filterConfiguration.update();
- // eslint-disable-next-line no-restricted-syntax
- for (const filterID in Drupal.filterConfiguration.statuses) {
- if (Drupal.filterConfiguration.statuses.hasOwnProperty(filterID)) {
- const filterStatus = Drupal.filterConfiguration.statuses[filterID];
- if (!(filterStatusAllowsFeature(filterStatus, feature))) {
- return false;
- }
- }
- }
-
- return true;
+ return Object.keys(Drupal.filterConfiguration.statuses).every(filterID =>
+ filterStatusAllowsFeature(
+ Drupal.filterConfiguration.statuses[filterID],
+ feature,
+ ),
+ );
},
};
*
* @see Drupal.EditorFeature
*/
- Drupal.EditorFeatureHTMLRule = function () {
+ Drupal.EditorFeatureHTMLRule = function() {
/**
*
- * @type {object}
+ * @type {Object}
*
* @prop {Array} tags
* @prop {Array} attributes
* @prop {Array} styles
* @prop {Array} classes
*/
- this.required = { tags: [], attributes: [], styles: [], classes: [] };
+ this.required = {
+ tags: [],
+ attributes: [],
+ styles: [],
+ classes: [],
+ };
/**
*
- * @type {object}
+ * @type {Object}
*
* @prop {Array} tags
* @prop {Array} attributes
* @prop {Array} styles
* @prop {Array} classes
*/
- this.allowed = { tags: [], attributes: [], styles: [], classes: [] };
+ this.allowed = {
+ tags: [],
+ attributes: [],
+ styles: [],
+ classes: [],
+ };
/**
*
*
* @see Drupal.EditorFeatureHTMLRule
*/
- Drupal.EditorFeature = function (name) {
+ Drupal.EditorFeature = function(name) {
this.name = name;
this.rules = [];
};
* @param {Drupal.EditorFeatureHTMLRule} rule
* A text editor feature HTML rule.
*/
- Drupal.EditorFeature.prototype.addHTMLRule = function (rule) {
+ Drupal.EditorFeature.prototype.addHTMLRule = function(rule) {
this.rules.push(rule);
};
*
* @see Drupal.FilterHTMLRule
*/
- Drupal.FilterStatus = function (name) {
+ Drupal.FilterStatus = function(name) {
/**
*
* @type {string}
* @param {Drupal.FilterHTMLRule} rule
* A text filter HTML rule.
*/
- Drupal.FilterStatus.prototype.addHTMLRule = function (rule) {
+ Drupal.FilterStatus.prototype.addHTMLRule = function(rule) {
this.rules.push(rule);
};
*
* @see Drupal.FilterStatus
*/
- Drupal.FilterHTMLRule = function () {
+ Drupal.FilterHTMLRule = function() {
// Allow or forbid tags.
this.tags = [];
this.allow = null;
return this;
};
- Drupal.FilterHTMLRule.prototype.clone = function () {
+ Drupal.FilterHTMLRule.prototype.clone = function() {
const clone = new Drupal.FilterHTMLRule();
clone.tags = this.tags.slice(0);
clone.allow = this.allow;
clone.restrictedTags.tags = this.restrictedTags.tags.slice(0);
- clone.restrictedTags.allowed.attributes = this.restrictedTags.allowed.attributes.slice(0);
- clone.restrictedTags.allowed.styles = this.restrictedTags.allowed.styles.slice(0);
- clone.restrictedTags.allowed.classes = this.restrictedTags.allowed.classes.slice(0);
- clone.restrictedTags.forbidden.attributes = this.restrictedTags.forbidden.attributes.slice(0);
- clone.restrictedTags.forbidden.styles = this.restrictedTags.forbidden.styles.slice(0);
- clone.restrictedTags.forbidden.classes = this.restrictedTags.forbidden.classes.slice(0);
+ clone.restrictedTags.allowed.attributes = this.restrictedTags.allowed.attributes.slice(
+ 0,
+ );
+ clone.restrictedTags.allowed.styles = this.restrictedTags.allowed.styles.slice(
+ 0,
+ );
+ clone.restrictedTags.allowed.classes = this.restrictedTags.allowed.classes.slice(
+ 0,
+ );
+ clone.restrictedTags.forbidden.attributes = this.restrictedTags.forbidden.attributes.slice(
+ 0,
+ );
+ clone.restrictedTags.forbidden.styles = this.restrictedTags.forbidden.styles.slice(
+ 0,
+ );
+ clone.restrictedTags.forbidden.classes = this.restrictedTags.forbidden.classes.slice(
+ 0,
+ );
return clone;
};
* @namespace
*/
Drupal.filterConfiguration = {
-
/**
* Drupal.FilterStatus objects, keyed by filter ID.
*
* up-to-date.
*/
update() {
- Object.keys(Drupal.filterConfiguration.statuses || {}).forEach((filterID) => {
- // Update status.
- Drupal.filterConfiguration.statuses[filterID].active = $(`[name="filters[${filterID}][status]"]`).is(':checked');
+ Object.keys(Drupal.filterConfiguration.statuses || {}).forEach(
+ filterID => {
+ // Update status.
+ Drupal.filterConfiguration.statuses[filterID].active = $(
+ `[name="filters[${filterID}][status]"]`,
+ ).is(':checked');
- // Update current rules.
- if (Drupal.filterConfiguration.liveSettingParsers[filterID]) {
- Drupal.filterConfiguration.statuses[filterID].rules = Drupal.filterConfiguration.liveSettingParsers[filterID].getRules();
- }
- });
+ // Update current rules.
+ if (Drupal.filterConfiguration.liveSettingParsers[filterID]) {
+ Drupal.filterConfiguration.statuses[
+ filterID
+ ].rules = Drupal.filterConfiguration.liveSettingParsers[
+ filterID
+ ].getRules();
+ }
+ },
+ );
},
-
};
/**
attach(context, settings) {
const $context = $(context);
- $context.find('#filters-status-wrapper input.form-checkbox').once('filter-editor-status').each(function () {
- const $checkbox = $(this);
- const nameAttribute = $checkbox.attr('name');
+ $context
+ .find('#filters-status-wrapper input.form-checkbox')
+ .once('filter-editor-status')
+ .each(function() {
+ const $checkbox = $(this);
+ const nameAttribute = $checkbox.attr('name');
- // The filter's checkbox has a name attribute of the form
- // "filters[<name of filter>][status]", parse "<name of filter>"
- // from it.
- const filterID = nameAttribute.substring(8, nameAttribute.indexOf(']'));
+ // The filter's checkbox has a name attribute of the form
+ // "filters[<name of filter>][status]", parse "<name of filter>"
+ // from it.
+ const filterID = nameAttribute.substring(
+ 8,
+ nameAttribute.indexOf(']'),
+ );
- // Create a Drupal.FilterStatus object to track the state (whether it's
- // active or not and its current settings, if any) of each filter.
- Drupal.filterConfiguration.statuses[filterID] = new Drupal.FilterStatus(filterID);
- });
+ // Create a Drupal.FilterStatus object to track the state (whether it's
+ // active or not and its current settings, if any) of each filter.
+ Drupal.filterConfiguration.statuses[
+ filterID
+ ] = new Drupal.FilterStatus(filterID);
+ });
},
};
-}(jQuery, _, Drupal, document));
+})(jQuery, _, Drupal, document);