Html element whitelisting in plugin not taking effect server side


(Benjamin Mosior) #1

I’m working with a group that focuses heavily on personal knowledge management (they use Evernote and similar software). Highlighting is important to them, so I’d like to support the <mark> html tag in posts through a plugin. I would like to avoid bbcode or using <ins> if possible. (As an aside, official support for <mark> could be neat.)

Based on what I could find in these forums and reading through the source code, I landed on the following directive to whitelist the tag in assets/javascripts/lib/discourse-markdown/my-plugin.js.es6:

// snip

export function setup(helper) {
  helper.whiteList([ 'mark' ]);
}

The above works client-side but fails server-side (the tags are stripped out).

(As an aside, you can see I’m also adding a button for it as well. Love how easy that was to do!)

I’m taking an educated guess (based on other forum posts) that this is related to the html_to_markdown function. This test fails despite the whitelist above:

require 'rails_helper'
require 'html_to_markdown'

describe HtmlToMarkdown do

  def html_to_markdown(html, opts={})
    HtmlToMarkdown.new(html, opts).to_markdown
  end

  it "supports <mark>" do
    expect(html_to_markdown("<mark>Highlighted</mark>")).to eq("<mark>Highlighted</mark>")
  end

end
Failures:

  1) HtmlToMarkdown supports <mark>
     Failure/Error: expect(html_to_markdown("<mark>Highlighted</mark>")).to eq("<mark>Highlighted</mark>")

       expected: "<mark>Highlighted</mark>"
            got: "Highlighted"

       (compared using ==)

Is this a reasonable pursuit? What am I missing to provide support for this server-side?


(cpradio) #2

Do you use reply by email often, as I thought HtmlToMarkdown was only utilized by incoming emails. Here is my spec (which @sam graciously wrote when upgrading to the new markdown engine)

require 'rails_helper'

describe PrettyText do

  context 'markdown it' do
    before do
      SiteSetting.enable_experimental_markdown_it = true
    end

    it 'can properly bake boxes' do
      md = <<~MD
        [],[ ],[_];[-]X[x]X [*] [\\*] are all checkboxes
        `[ ]` [x](hello) *[ ]* **[ ]** are not checkboxes
      MD

      html = <<~HTML
        <p><span class="chcklst-box fa fa-square-o"></span>,<span class="chcklst-box fa fa-square-o"></span>,<span class="chcklst-box fa fa-square"></span>;<span class="chcklst-box fa fa-minus-square-o"></span>X<span class="chcklst-box checked fa fa-check-square"></span>X <span class="chcklst-box checked fa fa-check-square-o"></span> <span class="chcklst-box checked fa fa-check-square-o"></span> are all checkboxes<br>
        <code>[ ]</code> <a>x</a> <em>[ ]</em> <strong>[ ]</strong> are not checkboxes</p>
      HTML
      cooked = PrettyText.cook(md)
      expect(cooked).to eq(html.strip)
    end
  end
end

And my whitelist that seems to work both server-side and client-side

export function setup(helper) {
  helper.whiteList([ 'span.chcklst-stroked',
                     'span.chcklst-box fa fa-square-o',
                     'span.chcklst-box fa fa-square',
                     'span.chcklst-box fa fa-minus-square-o',
                     'span.chcklst-box checked fa fa-check-square',
                     'span.chcklst-box checked fa fa-check-square-o' ]);
}

(Benjamin Mosior) #3

Taking another glance at the source code, right you are. That should have been obvious. My bad!

So the query changes… My whitelist is not taking effect server-side and I don’t know why.

I’ll take a look at your spec and see what I find out. Thanks!


(Benjamin Mosior) #4

Alright, I’m confounded. Must have been some sort of caching issue. The only change I introduced was rebooting the Vagrant box.

The spec passes, and highlighting takes effect like I’d expect.

require 'rails_helper'

describe PrettyText do

  context 'markdown it' do
    before do
      SiteSetting.enable_experimental_markdown_it = true
    end

    it 'can properly bake highlights' do
      md = <<~MD
        This is a <mark>highlighted phrase</mark>.
      MD

      html = <<~HTML
        <p>This is a <mark>highlighted phrase</mark>.</p>
      HTML
      cooked = PrettyText.cook(md)
      expect(cooked).to eq(html.strip)
    end
  end
end

Thanks for pushing me in the right direction!

Just in case anyone would like to take a look at the source for their own plugin work, here it is: