Project

General

Profile

Patch #42602 » 0001-Replaces-deckar01-task_list-gem-with-commonmark-task.patch

Marius BĂLTEANU, 2025-04-22 22:59

View differences:

Gemfile
49 49
# Optional CommonMark support, not for JRuby
50 50
group :common_mark do
51 51
  gem "commonmarker", '~> 2.3.0'
52
  gem 'deckar01-task_list', '2.3.2'
53 52
end
54 53

  
55 54
# Include database gems for the adapters found in the database
app/assets/stylesheets/application.css
1610 1610
h1:hover a.wiki-anchor, h2:hover a.wiki-anchor, h3:hover a.wiki-anchor, h4:hover a.wiki-anchor, h5:hover a.wiki-anchor, h6:hover a.wiki-anchor { display: inline; color: #ddd; }
1611 1611

  
1612 1612
div.wiki img {vertical-align:middle; max-width:100%;}
1613
div.wiki>.task-list {
1614
  padding-left: 0px;
1613

  
1614
div.wiki>.contains-task-list {
1615
  padding-left: 0;
1615 1616
}
1616
div.wiki .task-list {
1617
div.wiki .contains-task-list {
1617 1618
  list-style-type: none;
1618 1619
}
1619 1620
div.wiki .task-list input.task-list-item-checkbox {
lib/redmine/wiki_formatting/common_mark/formatter.rb
18 18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 19

  
20 20
require 'html/pipeline'
21
require 'task_list/filter'
22 21

  
23 22
module Redmine
24 23
  module WikiFormatting
......
33 32
          autolink: true,
34 33
          footnotes: true,
35 34
          header_ids: nil,
36
          tasklist: false,
35
          tasklist: true,
37 36
          shortcodes: false,
38 37
        }.freeze,
39 38

  
......
46 45
          unsafe: true,
47 46
          github_pre_lang: false,
48 47
          hardbreaks: Redmine::Configuration['common_mark_enable_hardbreaks'] == true,
48
          tasklist_classes: true,
49 49
        }.freeze,
50 50
        commonmarker_plugins: {
51 51
          syntax_highlighter: nil
......
57 57
        SanitizationFilter,
58 58
        SyntaxHighlightFilter,
59 59
        FixupAutoLinksFilter,
60
        ExternalLinksFilter,
61
        TaskList::Filter
60
        ExternalLinksFilter
62 61
      ], PIPELINE_CONFIG
63 62

  
64 63
      class Formatter
lib/redmine/wiki_formatting/common_mark/sanitization_filter.rb
78 78
          # allowlist[:attributes]["td"] = %w(style)
79 79
          # allowlist[:css] = { properties: ["text-align"] }
80 80

  
81
          # Allow `id` in a and li elements for footnotes
82
          # and remove any `id` properties not matching for footnotes
81
          # Allow `id` in a elements for footnotes
83 82
          allowlist[:attributes]["a"].push "id"
84
          allowlist[:attributes]["li"] = %w(id)
83
          # Remove any `id` property not matching for footnotes
85 84
          allowlist[:transformers].push lambda{|env|
86 85
            node = env[:node]
87
            return unless node.name == "a" || node.name == "li"
86
            return unless node.name == "a"
88 87
            return unless node.has_attribute?("id")
89 88
            return if node.name == "a" && node["id"] =~ /\Afnref-\d+\z/
90
            return if node.name == "li" && node["id"] =~ /\Afn-\d+\z/
91 89

  
92 90
            node.remove_attribute("id")
93 91
          }
94 92

  
93
          # allow `id` in li element for footnotes
94
          # allow `class` in li element for task list items
95
          allowlist[:attributes]["li"] = %w(id class)
96
          allowlist[:transformers].push lambda{|env|
97
            node = env[:node]
98
            return unless node.name == "li"
99

  
100
            if node.has_attribute?("id") && !(node["id"] =~ /\Afn-\d+\z/)
101
              node.remove_attribute("id")
102
            end
103

  
104
            if node.has_attribute?("class") && node["class"] != "task-list-item"
105
              node.remove_attribute("class")
106
            end
107
          }
108

  
109
          # allow input type = "checkbox" with class "task-list-item-checkbox"
110
          # for task list items
111
          allowlist[:elements].push('input')
112
          allowlist[:attributes]["input"] = %w(class type)
113
          allowlist[:transformers].push lambda{|env|
114
            node = env[:node]
115

  
116
            return unless node.name == "input"
117
            return if node['type'] == "checkbox" && node['class'] == "task-list-item-checkbox"
118

  
119
            node.replace(node.children)
120
          }
121

  
122
          # allow class "contains-task-list" on ul for task list items
123
          allowlist[:attributes]["ul"] = %w(class)
124
          allowlist[:transformers].push lambda{|env|
125
            node = env[:node]
126

  
127
            return unless node.name == "ul"
128
            return if node["class"] == "contains-task-list"
129

  
130
            node.remove_attribute("class")
131
          }
132

  
95 133
          # https://github.com/rgrove/sanitize/issues/209
96 134
          allowlist[:protocols].delete("a")
97 135
          allowlist[:transformers].push lambda{|env|
test/unit/lib/redmine/wiki_formatting/common_mark/formatter_test.rb
287 287

  
288 288
      expected = <<~EXPECTED
289 289
        <p>Task list:</p>
290
        <ul class="task-list">
290
        <ul class="contains-task-list">
291 291
        <li class="task-list-item">
292 292
        <input type="checkbox" class="task-list-item-checkbox" disabled> Task 1
293 293
        </li>
test/unit/lib/redmine/wiki_formatting/html_sanitizer_test.rb
35 35
    input = %(<a href="javascript:alert('hello');">foo</a>)
36 36
    assert_equal "<a>foo</a>", @sanitizer.call(input)
37 37
  end
38

  
39
  def test_should_be_strict_with_task_list_items
40
    to_test = {
41
      %(<input type="checkbox" class="">) => "",
42
      %(<input type="checkbox" class="task-list-item-checkbox other">) => "",
43
      %(<input type="checkbox" class="task-list-item-checkbox" id="item1">) => %(<input type="checkbox" class="task-list-item-checkbox">),
44
      %(<input type="text" class="">) => "",
45
      %(<input />) => "",
46
      %(<ul class="other"></ul) => "<ul></ul>",
47
      %(<ul class="contains-task-list"></ul) => "<ul class=\"contains-task-list\"></ul>",
48
      %(<ul class="contains-task-list" id="list1"></ul) => "<ul class=\"contains-task-list\"></ul>",
49
      %(<li class="other"></li>) => "",
50
      %(<li id="other"></li>) => "",
51
      %(<li class="task-list-item"></li>) => "",
52
      %(<li class="task-list-item">Item 1</li>) => "Item 1",
53
    }
54
    to_test.each do |input, result|
55
      assert_equal result, @sanitizer.call(input)
56
    end
57

  
58
  end
38 59
end
    (1-1/1)