Auto-anchor attribute regexes, document _validTags

This commit is contained in:
riking 2014-10-05 11:31:40 -07:00
parent fa830c8d69
commit 22a4ceceee
1 changed files with 60 additions and 9 deletions

View File

@ -7,10 +7,44 @@
@namespace Discourse @namespace Discourse
@module Discourse @module Discourse
**/ **/
var _validClasses = {},
_validIframes = [], /**
_validTags = {}, * An object mapping from HTML tag names to an object mapping the valid
_decoratedCaja = false; * attributes on that tag to an array of permitted values.
*
* The permitted values can be strings or regexes.
*
* The pseduo-attribute 'data-*' can be used to validate any data-foo
* attributes without any specified validations.
*
* Code can insert into this map by calling Discourse.Markdown.whiteListTag().
*
* Example:
*
* <pre><code>
* {
* a: {
* href: ['*'],
* data-mention-id: [/^\d+$/],
* ...
* },
* code: {
* class: ['ada', 'haskell', 'c', 'cpp', ... ]
* },
* ...
* }
* </code></pre>
*
* @private
*/
var _validTags = {};
/**
* Classes valid on all elements. Map from class name to 'true'.
* @private
*/
var _validClasses = {};
var _validIframes = [];
var _decoratedCaja = false;
function validateAttribute(tagName, attribName, value) { function validateAttribute(tagName, attribName, value) {
var tag = _validTags[tagName]; var tag = _validTags[tagName];
@ -42,16 +76,33 @@ function validateAttribute(tagName, attribName, value) {
} }
} }
function anchorRegexp(regex) {
if (/^\^.*\$$/.test(regex.source)) {
return regex; // already anchored
}
var flags = "";
if (regex.global) { throw "Invalid attribute validation regex - cannot be global"; }
if (regex.ignoreCase) { flags += "i"; }
if (regex.multiline) { flags += "m"; }
if (regex.sticky) { throw "Invalid attribute validation regex - cannot be sticky"; }
return new RegExp("^" + regex.source + "$", flags);
}
Discourse.Markdown = { Discourse.Markdown = {
/** /**
Whitelist class for only a certain tag Add to the attribute whitelist for a certain HTML tag.
@param {String} tagName to whitelist @param {String} tagName tag to whitelist the attr for
@param {String} attribName to whitelist @param {String} attribName attr to whitelist for the tag
@param {String} value to whitelist @param {String | RegExp} [value] whitelisted value for the attribute
**/ **/
whiteListTag: function(tagName, attribName, value) { whiteListTag: function(tagName, attribName, value) {
if (value instanceof RegExp) {
value = anchorRegexp(value);
}
_validTags[tagName] = _validTags[tagName] || {}; _validTags[tagName] = _validTags[tagName] || {};
_validTags[tagName][attribName] = _validTags[tagName][attribName] || []; _validTags[tagName][attribName] = _validTags[tagName][attribName] || [];
_validTags[tagName][attribName].push(value || '*'); _validTags[tagName][attribName].push(value || '*');
@ -245,7 +296,7 @@ Discourse.Markdown.whiteListTag('a', 'class', 'mention');
Discourse.Markdown.whiteListTag('a', 'data-bbcode'); Discourse.Markdown.whiteListTag('a', 'data-bbcode');
Discourse.Markdown.whiteListTag('a', 'name'); Discourse.Markdown.whiteListTag('a', 'name');
Discourse.Markdown.whiteListTag('img', 'src', /^data:image.*/i); Discourse.Markdown.whiteListTag('img', 'src', /^data:image.*$/i);
Discourse.Markdown.whiteListTag('div', 'class', 'title'); Discourse.Markdown.whiteListTag('div', 'class', 'title');
Discourse.Markdown.whiteListTag('div', 'class', 'quote-controls'); Discourse.Markdown.whiteListTag('div', 'class', 'quote-controls');