Project

General

Profile

Feature #42603 » 0001-Enable-common_mark-alerts.patch

Mizuki ISHIKAWA, 2025-04-28 09:45

View differences:

app/assets/stylesheets/application.css
1262 1262

  
1263 1263
.conflict-details {font-size:93%;}
1264 1264

  
1265
/***** CommonMark Alerts *****/
1266

  
1267
.markdown-alert {
1268
  border-left: 4px solid;
1269
  padding: 10px 10px 1px 10px;
1270
  margin: 10px 0;
1271
}
1272

  
1273
.markdown-alert-title + p {
1274
  margin-top: 2px;
1275
}
1276

  
1277
.markdown-alert-title {
1278
  font-weight: bold;
1279
  margin-bottom: 0.5em;
1280
  margin: 0px;
1281
}
1282

  
1283
.markdown-alert-tip { border-color: #5db651; }
1284
.markdown-alert-tip .markdown-alert-title { color: #005f00; }
1285

  
1286
.markdown-alert-important { border-color: #800080; }
1287
.markdown-alert-important .markdown-alert-title { color: #4b006e; }
1288

  
1289
.markdown-alert-caution { border-color: #c22; }
1290
.markdown-alert-caution .markdown-alert-title { color: #880000; }
1291

  
1292
.markdown-alert-warning { border-color: #e4bc4b; }
1293
.markdown-alert-warning .markdown-alert-title { color: #a7760c; }
1294

  
1295
.markdown-alert-note { border-color: #169; }
1296
.markdown-alert-note .markdown-alert-title { color: #1e40af; }
1297

  
1265 1298
/***** Ajax indicator ******/
1266 1299
#ajax-indicator {
1267 1300
position: absolute; /* fixed not supported by IE */
lib/redmine/wiki_formatting/common_mark/formatter.rb
34 34
          header_ids: nil,
35 35
          tasklist: true,
36 36
          shortcodes: false,
37
          alerts: true,
37 38
        }.freeze,
38 39

  
39 40
        # https://github.com/gjtorikian/commonmarker#parse-options
lib/redmine/wiki_formatting/common_mark/sanitization_filter.rb
68 68
            end
69 69
          }
70 70

  
71
          # Allow class on div and p tags only for alert blocks
72
          # (must be exactly: "markdown-alert markdown-alert-*" for div, and "markdown-alert-title" for p)
73
          (allowlist[:attributes]["div"] ||= []) << "class"
74
          (allowlist[:attributes]["p"] ||= []) << "class"
75
          allowlist[:transformers].push lambda{|env|
76
            node = env[:node]
77
            return unless node.element?
78

  
79
            case node.name
80
            when 'div'
81
              unless node['class'] =~ /\Amarkdown-alert markdown-alert-[a-z]+\z/
82
                node.remove_attribute('class')
83
              end
84
            when 'p'
85
              unless node['class'] == 'markdown-alert-title'
86
                node.remove_attribute('class')
87
              end
88
            end
89
          }
90

  
71 91
          # Allow table cell alignment by style attribute
72 92
          #
73 93
          # Only necessary if we used the TABLE_PREFER_STYLE_ATTRIBUTES
test/unit/lib/redmine/wiki_formatting/common_mark/formatter_test.rb
163 163
      # 0
164 164
      <<~STR.chomp,
165 165
        # Title
166
  
166

  
167 167
        Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
168 168
      STR
169 169
      # 1
170 170
      <<~STR.chomp,
171 171
        ## Heading 2
172
  
172

  
173 173
        ~~~ruby
174 174
          def foo
175 175
          end
176 176
        ~~~
177
  
177

  
178 178
        Morbi facilisis accumsan orci non pharetra.
179
  
179

  
180 180
        ~~~ ruby
181 181
        def foo
182 182
        end
183 183
        ~~~
184
  
184

  
185 185
        ```
186 186
        Pre Content:
187
  
187

  
188 188
        ## Inside pre
189
  
189

  
190 190
        <tag> inside pre block
191
  
191

  
192 192
        Morbi facilisis accumsan orci non pharetra.
193 193
        ```
194 194
      STR
195 195
      # 2
196 196
      <<~STR.chomp,
197 197
        ### Heading 3
198
  
198

  
199 199
        Nulla nunc nisi, egestas in ornare vel, posuere ac libero.
200 200
      STR
201 201
    ]
......
299 299
      assert_equal expected.gsub(%r{[\r\n\t]}, ''), to_html(text).gsub(%r{[\r\n\t]}, '').rstrip
300 300
    end
301 301

  
302
    def test_should_render_alert_blocks
303
      text = <<~MD
304
        > [!note]
305
        > This is a note.
306

  
307
        > [!tip]
308
        > This is a tip.
309

  
310
        > [!warning]
311
        > This is a warning.
312

  
313
        > [!caution]
314
        > This is a caution.
315

  
316
        > [!important]
317
        > This is a important.
318
      MD
319

  
320
      html = to_html(text)
321
      %w[note tip warning caution important].each do |alert|
322
        assert_include "<div class=\"markdown-alert markdown-alert-note\">\n<p class=\"markdown-alert-title\">Note</p>\n<p>This is a note.</p>\n</div>", html
323
      end
324
    end
325

  
326
    def test_should_not_render_unknown_alert_type
327
      text = <<~MD
328
        > [!unknown]
329
        > This should not become an alert.
330
      MD
331

  
332
      html = to_html(text)
333

  
334
      assert_include "<blockquote>", html
335
      assert_include "[!unknown]", html
336
      assert_include "This should not become an alert.", html
337

  
338
      assert_not_include 'markdown-alert', html
339
    end
340

  
302 341
    private
303 342

  
304 343
    def assert_section_with_hash(expected, text, index)
test/unit/lib/redmine/wiki_formatting/common_mark/sanitization_filter_test.rb
71 71
      assert_equal %(<code>foo</code>), filter(input)
72 72
    end
73 73

  
74
    def test_should_allow_valid_alert_div_and_p_classes
75
      html = <<~HTML
76
        <div class="markdown-alert markdown-alert-tip">
77
          <p class="markdown-alert-title">Tip</p>
78
          <p>Useful tip.</p>
79
        </div>
80
      HTML
81

  
82
      sanitized = filter(html)
83

  
84
      assert_include 'class="markdown-alert markdown-alert-tip"', sanitized
85
      assert_include 'class="markdown-alert-title"', sanitized
86
    end
87

  
88
    def test_should_remove_invalid_div_class
89
      html = '<div class="bad-class">Text</div>'
90
      sanitized = filter(html)
91
      refute_include 'bad-class', sanitized
92
    end
93

  
94
    def test_should_remove_invalid_p_class
95
      html = '<p class="bad-class">Text</p>'
96
      sanitized = filter(html)
97
      assert_not_include 'bad-class', sanitized
98
    end
99

  
74 100
    def test_should_allow_links_with_safe_url_schemes
75 101
      %w(http https ftp ssh foo).each do |scheme|
76 102
        input = %(<a href="#{scheme}://example.org/">foo</a>)
(1-1/2)