157 lines
3.8 KiB
JavaScript
157 lines
3.8 KiB
JavaScript
'use strict';
|
|
|
|
var addonLimit = require('./limit').addon;
|
|
|
|
// Banned CSS declaration property names, for security reasons.
|
|
var banned = [
|
|
'behavior',
|
|
'-moz-binding',
|
|
];
|
|
|
|
var warnOnImportant = function (renderer) {
|
|
var putRaw = renderer.putRaw;
|
|
|
|
renderer.putRaw = function (rawCssRule) {
|
|
if (rawCssRule.indexOf('!important') > -1) {
|
|
console.error(
|
|
'!important modifier is not allowed in AMP apps. ' +
|
|
'Detected !important modifier in below CSS rule. ' +
|
|
rawCssRule
|
|
);
|
|
}
|
|
|
|
return putRaw(rawCssRule);
|
|
};
|
|
};
|
|
|
|
var removeImportant = function (renderer) {
|
|
var putRaw = renderer.putRaw;
|
|
|
|
renderer.putRaw = function (rawCssRule) {
|
|
rawCssRule = rawCssRule.replace(/!important/g, '');
|
|
|
|
return putRaw(rawCssRule);
|
|
};
|
|
};
|
|
|
|
var warnOnReservedSelectors = function (renderer) {
|
|
var putRaw = renderer.putRaw;
|
|
|
|
renderer.putRaw = function (rawCssRule) {
|
|
var pos = rawCssRule.indexOf('{');
|
|
|
|
if (pos < 0)
|
|
return putRaw(rawCssRule);
|
|
|
|
var selectors = ' ' + rawCssRule.substr(0, pos);
|
|
|
|
if (selectors.match(/\s\.-amp-/g)) {
|
|
console.error(
|
|
'Detected class name that starts with "-amp-". ' +
|
|
'Class names starting with "-amp-" are reserved from AMP components. ' +
|
|
rawCssRule
|
|
);
|
|
}
|
|
|
|
if (selectors.match(/\si-amp-/g)) {
|
|
console.error(
|
|
'Detected CSS selector that matches "i-amp-" elements. ' +
|
|
'Slectors for "i-amp-" elements are reserved from AMP components. ' +
|
|
rawCssRule
|
|
);
|
|
}
|
|
|
|
return putRaw(rawCssRule);
|
|
};
|
|
};
|
|
|
|
var removeReservedSelectors = function (renderer) {
|
|
var putRaw = renderer.putRaw;
|
|
|
|
renderer.putRaw = function (rawCssRule) {
|
|
var pos = rawCssRule.indexOf('{');
|
|
|
|
if (pos < 0)
|
|
return putRaw(rawCssRule);
|
|
|
|
var selectors = ' ' + rawCssRule.substr(0, pos);
|
|
|
|
if (selectors.match(/\s\.-amp-/g) || selectors.match(/\si-amp-/g)) {
|
|
return;
|
|
}
|
|
|
|
return putRaw(rawCssRule);
|
|
};
|
|
};
|
|
|
|
var warnOnBanned = function (renderer) {
|
|
var decl = renderer.decl;
|
|
|
|
renderer.decl = function (prop, value) {
|
|
if (banned.indexOf(renderer.kebab(prop)) > -1) {
|
|
|
|
console.error(
|
|
'Detected banned CSS prop, "' + prop + '" is not allowed in AMP apps.'
|
|
);
|
|
}
|
|
|
|
return decl(prop, value);
|
|
};
|
|
};
|
|
|
|
var removeBanned = function (renderer) {
|
|
var decl = renderer.decl;
|
|
|
|
renderer.decl = function (prop, value) {
|
|
if (banned.indexOf(renderer.kebab(prop)) > -1) {
|
|
|
|
return '';
|
|
}
|
|
|
|
return decl(prop, value);
|
|
};
|
|
};
|
|
|
|
exports.addon = function (renderer, config) {
|
|
config = config || {};
|
|
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
require('./__dev__/warnOnMissingDependencies')('limit', renderer, ['putRaw']);
|
|
}
|
|
|
|
if (renderer.client) return;
|
|
|
|
// Enforce max style sheet size.
|
|
addonLimit(renderer, config.limit || 50000);
|
|
|
|
// Warn on `!important` specifiers, which are not allowed.
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
warnOnImportant(renderer);
|
|
}
|
|
|
|
// Remove all !important modifiers.
|
|
if (config.removeImportant) {
|
|
removeImportant(renderer);
|
|
}
|
|
|
|
// Warn on reserved selectors.
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
warnOnReservedSelectors(renderer);
|
|
}
|
|
|
|
// Remove reserved selectors ".-amp-" and "i-amp-".
|
|
if (config.removeReserved) {
|
|
removeReservedSelectors(renderer);
|
|
}
|
|
|
|
// Warn on banned CSS properties.
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
warnOnBanned(renderer);
|
|
}
|
|
|
|
// Remove banned CSS properties.
|
|
if (config.removeBanned) {
|
|
removeBanned(renderer);
|
|
}
|
|
};
|