diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-08-18 11:17:02 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-08-18 11:17:02 +0300 |
commit | b39512ed755239198a9c294b6a45e65c05900235 (patch) | |
tree | d234a3efade1de67c46b9e5a38ce813627726aa7 /lib/banzai/filter | |
parent | d31474cf3b17ece37939d20082b07f6657cc79a9 (diff) |
Add latest changes from gitlab-org/gitlab@15-3-stable-eev15.3.0-rc42
Diffstat (limited to 'lib/banzai/filter')
5 files changed, 95 insertions, 11 deletions
diff --git a/lib/banzai/filter/custom_emoji_filter.rb b/lib/banzai/filter/custom_emoji_filter.rb index ae95c7f66b6..b589d264526 100644 --- a/lib/banzai/filter/custom_emoji_filter.rb +++ b/lib/banzai/filter/custom_emoji_filter.rb @@ -29,7 +29,7 @@ module Banzai @emoji_pattern ||= /(?<=[^[:alnum:]:]|\n|^) :(#{CustomEmoji::NAME_REGEXP}): - (?=[^[:alnum:]:]|$)/x + (?=[^[:alnum:]:]|$)/xo end def custom_emoji_name_element_filter(text) @@ -58,7 +58,7 @@ module Banzai end def custom_emoji_candidates - doc.to_html.scan(/:(#{CustomEmoji::NAME_REGEXP}):/).flatten + doc.to_html.scan(/:(#{CustomEmoji::NAME_REGEXP}):/o).flatten end def all_custom_emoji diff --git a/lib/banzai/filter/references/abstract_reference_filter.rb b/lib/banzai/filter/references/abstract_reference_filter.rb index 521fd7bf4cc..1ca38d2612d 100644 --- a/lib/banzai/filter/references/abstract_reference_filter.rb +++ b/lib/banzai/filter/references/abstract_reference_filter.rb @@ -240,11 +240,11 @@ module Banzai object_parent_type = parent.is_a?(Group) ? :group : :project { - original: escape_html_entities(text), - link: link_content, - link_reference: link_reference, + original: escape_html_entities(text), + link: link_content, + link_reference: link_reference, object_parent_type => parent.id, - object_sym => object.id + object_sym => object.id } end diff --git a/lib/banzai/filter/references/label_reference_filter.rb b/lib/banzai/filter/references/label_reference_filter.rb index a019ae0108e..6020c7b7f58 100644 --- a/lib/banzai/filter/references/label_reference_filter.rb +++ b/lib/banzai/filter/references/label_reference_filter.rb @@ -12,13 +12,13 @@ module Banzai return Label.none unless parent.is_a?(Project) || parent.is_a?(Group) labels = find_labels(parent) - label_ids = ids.map {|y| y[:label_id]}.compact + label_ids = ids.map { |y| y[:label_id] }.compact unless label_ids.empty? id_relation = labels.where(id: label_ids) end - label_names = ids.map {|y| y[:label_name]}.compact + label_names = ids.map { |y| y[:label_name] }.compact unless label_names.empty? label_relation = labels.where(title: label_names) end diff --git a/lib/banzai/filter/references/milestone_reference_filter.rb b/lib/banzai/filter/references/milestone_reference_filter.rb index 609aaf885ba..77658f72d34 100644 --- a/lib/banzai/filter/references/milestone_reference_filter.rb +++ b/lib/banzai/filter/references/milestone_reference_filter.rb @@ -11,12 +11,12 @@ module Banzai def parent_records(parent, ids) return Milestone.none unless valid_context?(parent) - milestone_iids = ids.map {|y| y[:milestone_iid]}.compact + milestone_iids = ids.map { |y| y[:milestone_iid] }.compact unless milestone_iids.empty? iid_relation = find_milestones(parent, true).where(iid: milestone_iids) end - milestone_names = ids.map {|y| y[:milestone_name]}.compact + milestone_names = ids.map { |y| y[:milestone_name] }.compact unless milestone_names.empty? milestone_relation = find_milestones(parent, false).where(name: milestone_names) end diff --git a/lib/banzai/filter/task_list_filter.rb b/lib/banzai/filter/task_list_filter.rb index 896f67cb875..e8a7677b102 100644 --- a/lib/banzai/filter/task_list_filter.rb +++ b/lib/banzai/filter/task_list_filter.rb @@ -8,9 +8,93 @@ require 'task_list/filter' # - app/assets/javascripts/behaviors/markdown/nodes/task_list_item.js module Banzai module Filter + # TaskList filter replaces task list item markers (`[ ]`, `[x]`, and `[~]`) + # with checkboxes, marked up with metadata and behavior. + # + # This should be run on the HTML generated by the Markdown filter, after the + # SanitizationFilter. + # + # Syntax + # ------ + # + # Task list items must be in a list format: + # + # ``` + # - [ ] incomplete + # - [x] complete + # - [~] inapplicable + # ``` + # + # This class overrides TaskList::Filter in the `deckar01-task_list` gem + # to add support for inapplicable task items class TaskListFilter < TaskList::Filter + extend ::Gitlab::Utils::Override + + XPATH = 'descendant-or-self::li[input[@data-inapplicable]] | descendant-or-self::li[p[input[@data-inapplicable]]]' + INAPPLICABLE = '[~]' + INAPPLICABLEPATTERN = /\[~\]/.freeze + + # Pattern used to identify all task list items. + # Useful when you need iterate over all items. + NEWITEMPATTERN = / + ^ + (?:\s*[-+*]|(?:\d+\.))? # optional list prefix + \s* # optional whitespace prefix + ( # checkbox + #{CompletePattern}| + #{IncompletePattern}| + #{INAPPLICABLEPATTERN} + ) + (?=\s) # followed by whitespace + /x.freeze + + # Force the gem's constant to use our new one + superclass.send(:remove_const, :ItemPattern) # rubocop: disable GitlabSecurity/PublicSend + superclass.const_set(:ItemPattern, NEWITEMPATTERN) + + def inapplicable?(item) + !!(item.checkbox_text =~ INAPPLICABLEPATTERN) + end + + override :render_item_checkbox def render_item_checkbox(item) - "<task-button></task-button>#{super}" + %(<task-button></task-button><input type="checkbox" + class="task-list-item-checkbox" + #{'checked="checked"' if item.complete?} + #{'data-inapplicable' if inapplicable?(item)} + disabled="disabled"/>) + end + + override :render_task_list_item + def render_task_list_item(item) + source = item.source + + if inapplicable?(item) + # Add a `<s>` tag around the list item text. However because of the + # way tasks are built, the source can include an embedded sublist, like + # `[~] foobar\n<ol><li....` + # The `<s>` should only be added to the main text. + source = source.partition("#{INAPPLICABLE} ") + text = source.last.partition(/\<(ol|ul)/) + text[0] = "<s>#{text[0]}</s>" + source[-1] = text.join + source = source.join + end + + Nokogiri::HTML.fragment \ + source.sub(ItemPattern, render_item_checkbox(item)), 'utf-8' + end + + override :call + def call + super + + # add class to li for any inapplicable checkboxes + doc.xpath(XPATH).each do |li| + li.add_class('inapplicable') + end + + doc end end end |