diff options
author | Guillaume Grossetie <ggrossetie@gmail.com> | 2019-07-10 10:30:10 +0200 |
---|---|---|
committer | Guillaume Grossetie <ggrossetie@gmail.com> | 2019-07-16 12:53:38 +0200 |
commit | 0cba81c0ecc71f411153b1f2a2952c07125217f9 (patch) | |
tree | 48198eb6c5e9feb42065a8b539a00344b2d60216 /lib/banzai | |
parent | 1def071991dddf6a1500c84d9e53a0edd64d45a1 (diff) | |
download | gitlab-ce-0cba81c0ecc71f411153b1f2a2952c07125217f9.tar.gz |
Enable section anchors
Diffstat (limited to 'lib/banzai')
-rw-r--r-- | lib/banzai/filter/ascii_doc_sanitization_filter.rb | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/lib/banzai/filter/ascii_doc_sanitization_filter.rb b/lib/banzai/filter/ascii_doc_sanitization_filter.rb index a78bb60103c..d8d63075752 100644 --- a/lib/banzai/filter/ascii_doc_sanitization_filter.rb +++ b/lib/banzai/filter/ascii_doc_sanitization_filter.rb @@ -6,6 +6,9 @@ module Banzai # # Extends Banzai::Filter::BaseSanitizationFilter with specific rules. class AsciiDocSanitizationFilter < Banzai::Filter::BaseSanitizationFilter + # Section anchor link pattern + SECTION_LINK_REF_PATTERN = /\A#{Gitlab::Asciidoc::DEFAULT_ADOC_ATTRS['idprefix']}(:?[[:alnum:]]|-|_)+\z/.freeze + # Classes used by Asciidoctor to style components ADMONITION_CLASSES = %w(fa icon-note icon-tip icon-warning icon-caution icon-important).freeze CALLOUT_CLASSES = ['conum'].freeze @@ -19,14 +22,17 @@ module Banzai td: ['icon'].freeze, i: ADMONITION_CLASSES + CALLOUT_CLASSES + CHECKLIST_CLASSES, ul: LIST_CLASSES, - ol: LIST_CLASSES + ol: LIST_CLASSES, + a: ['anchor'].freeze }.freeze + ALLOWED_HEADERS = %w(h2 h3 h4 h5 h6).freeze + def customize_whitelist(whitelist) # Allow marks whitelist[:elements].push('mark') - # Allow any classes in `span`, `i`, `div`, `td`, `ul` and `ol` elements + # Allow any classes in `span`, `i`, `div`, `td`, `ul`, `ol` and `a` elements # but then remove any unknown classes whitelist[:attributes]['span'] = %w(class) whitelist[:attributes]['div'].push('class') @@ -34,12 +40,32 @@ module Banzai whitelist[:attributes]['i'] = %w(class) whitelist[:attributes]['ul'] = %w(class) whitelist[:attributes]['ol'] = %w(class) + whitelist[:attributes]['a'].push('class') whitelist[:transformers].push(self.class.remove_element_classes) + # Allow `id` in heading elements for section anchors + ALLOWED_HEADERS.each do |header| + whitelist[:attributes][header] = %w(id) + end + whitelist[:transformers].push(self.class.remove_non_heading_ids) + whitelist end class << self + def remove_non_heading_ids + lambda do |env| + node = env[:node] + + return unless ALLOWED_HEADERS.any?(node.name) + return unless node.has_attribute?('id') + + return if node['id'] =~ SECTION_LINK_REF_PATTERN + + node.remove_attribute('id') + end + end + def remove_element_classes lambda do |env| node = env[:node] |