FEATURE: site setting to allow html tables (which may come from imports)
(allow_html_tables , disabled by default)
This commit is contained in:
parent
c552f846ae
commit
e93665b9f7
|
@ -475,7 +475,7 @@ Discourse.Dialect = {
|
|||
|
||||
**/
|
||||
replaceBlock: function(args) {
|
||||
this.registerBlock(args.start.toString(), function(block, next) {
|
||||
var fn = function(block, next) {
|
||||
|
||||
var linebreaks = dialect.options.traditional_markdown_linebreaks ||
|
||||
Discourse.SiteSettings.traditional_markdown_linebreaks;
|
||||
|
@ -565,7 +565,13 @@ Discourse.Dialect = {
|
|||
var emitterResult = args.emitter.call(this, contentBlocks, match, dialect.options);
|
||||
if (emitterResult) { result.push(emitterResult); }
|
||||
return result;
|
||||
});
|
||||
};
|
||||
|
||||
if (args.priority) {
|
||||
fn.priority = args.priority;
|
||||
}
|
||||
|
||||
this.registerBlock(args.start.toString(), fn);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
var flattenBlocks = function(blocks) {
|
||||
var result = "";
|
||||
blocks.forEach(function(b) {
|
||||
result += b;
|
||||
if (b.trailing) { result += b.trailing; }
|
||||
});
|
||||
|
||||
// bypass newline insertion
|
||||
return result.replace(/[\n\r]/g, " ");
|
||||
};
|
||||
|
||||
var emitter = function(contents) {
|
||||
// TODO event should be fired when sanitizer loads
|
||||
if (window.html4 && window.html4.ELEMENTS.td !== 1) {
|
||||
window.html4.ELEMENTS.table = 0;
|
||||
window.html4.ELEMENTS.tbody = 1;
|
||||
window.html4.ELEMENTS.td = 1;
|
||||
window.html4.ELEMENTS.thead = 1;
|
||||
window.html4.ELEMENTS.th = 1;
|
||||
window.html4.ELEMENTS.tr = 1;
|
||||
}
|
||||
return ['table', {"class": "md-table"}, flattenBlocks.apply(this, [contents])];
|
||||
};
|
||||
|
||||
var tableBlock = {
|
||||
start: /(<table>)([\S\s]*)/igm,
|
||||
stop: /<\/table>/igm,
|
||||
rawContents: true,
|
||||
emitter: emitter,
|
||||
priority: 1
|
||||
};
|
||||
|
||||
var init = function(){
|
||||
if (Discourse.SiteSettings.allow_html_tables) {
|
||||
Discourse.Markdown.whiteListTag("table");
|
||||
Discourse.Markdown.whiteListTag("table", "class", "md-table");
|
||||
Discourse.Markdown.whiteListTag("tbody");
|
||||
Discourse.Markdown.whiteListTag("thead");
|
||||
Discourse.Markdown.whiteListTag("tr");
|
||||
Discourse.Markdown.whiteListTag("th");
|
||||
Discourse.Markdown.whiteListTag("td");
|
||||
Discourse.Dialect.replaceBlock(tableBlock);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
if (Discourse.SiteSettings) {
|
||||
init();
|
||||
} else {
|
||||
Discourse.initializer({initialize: init, name: 'enable-html-tables'});
|
||||
}
|
||||
|
|
@ -243,4 +243,20 @@ blockquote > *:last-child {
|
|||
}
|
||||
|
||||
|
||||
table.md-table {
|
||||
thead {
|
||||
border-bottom: 2px solid lighten($primary, 80%);
|
||||
th {
|
||||
text-align: left;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
td,th {
|
||||
padding: 3px 3px 3px 10px;
|
||||
}
|
||||
tr {
|
||||
border-bottom: 1px solid lighten($primary, 80%);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -842,6 +842,7 @@ en:
|
|||
flag_sockpuppets: "If a new user replies to a topic from the same IP address as the new user who started the topic, flag both of their posts as potential spam."
|
||||
|
||||
traditional_markdown_linebreaks: "Use traditional linebreaks in Markdown, which require two trailing spaces for a linebreak."
|
||||
allow_html_tables: "Allow tables to be entered in Markdown using HTML tags, TABLE, THEAD, TD, TR, TH are whiteliseted (requires full rebake on all old posts containing tables)"
|
||||
post_undo_action_window_mins: "Number of minutes users are allowed to undo recent actions on a post (like, flag, etc)."
|
||||
must_approve_users: "Staff must approve all new user accounts before they are allowed to access the site. WARNING: enabling this for a live site will revoke access for existing non-staff users!"
|
||||
ga_tracking_code: "Google analytics (ga.js) tracking code code, eg: UA-12345678-9; see http://google.com/analytics"
|
||||
|
|
|
@ -386,6 +386,9 @@ posting:
|
|||
traditional_markdown_linebreaks:
|
||||
client: true
|
||||
default: false
|
||||
allow_html_tables:
|
||||
client: true
|
||||
default: false
|
||||
suppress_reply_directly_below:
|
||||
client: true
|
||||
default: true
|
||||
|
|
|
@ -331,4 +331,30 @@ describe PrettyText do
|
|||
expect(PrettyText.cook(raw)).to match_html(cooked)
|
||||
end
|
||||
|
||||
describe 'tables' do
|
||||
before do
|
||||
PrettyText.reset_context
|
||||
end
|
||||
|
||||
after do
|
||||
PrettyText.reset_context
|
||||
end
|
||||
|
||||
it 'allows table html' do
|
||||
SiteSetting.allow_html_tables = true
|
||||
PrettyText.reset_context
|
||||
table = "<table><thead><tr>\n<th>test</th></tr></thead><tbody><tr><td>a</td></tr></tbody></table>"
|
||||
match = "<table class=\"md-table\"><thead><tr> <th>test</th> </tr></thead><tbody><tr><td>a</td></tr></tbody></table>"
|
||||
expect(PrettyText.cook(table)).to match_html(match)
|
||||
|
||||
end
|
||||
|
||||
it 'allows no tables when not enabled' do
|
||||
SiteSetting.allow_html_tables = false
|
||||
table = "<table><thead><tr><th>test</th></tr></thead><tbody><tr><td>a</td></tr></tbody></table>"
|
||||
expect(PrettyText.cook(table)).to match_html("")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -318,13 +318,26 @@
|
|||
|
||||
// Build default order from insertion order.
|
||||
Markdown.buildBlockOrder = function(d) {
|
||||
var ord = [];
|
||||
var ord = [[]];
|
||||
for ( var i in d ) {
|
||||
if ( i === "__order__" || i === "__call__" )
|
||||
continue;
|
||||
ord.push( i );
|
||||
|
||||
var priority = d[i].priority || 0;
|
||||
ord[priority] = ord[priority] || [];
|
||||
ord[priority].push( i );
|
||||
}
|
||||
d.__order__ = ord;
|
||||
|
||||
var flattend = [];
|
||||
for (i=ord.length-1; i>=0; i--){
|
||||
if (ord[i]) {
|
||||
for (var j=0; j<ord[i].length; j++){
|
||||
flattend.push(ord[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
d.__order__ = flattend;
|
||||
};
|
||||
|
||||
// Build patterns for inline matcher
|
||||
|
|
Loading…
Reference in New Issue