Previously, when the wiki page format was anything other than `markdown`
or `asciidoc` the formatted content would be returned though a Gitaly
call. Gitaly in turn would delegate formatting to the gitlab-gollum-lib
gem, which in turn would delegate that to various gems (like RDoc for
`rdoc`) and then apply some very liberal sanitization.
It was too liberal!
This change brings our wiki content formatting in line with how we
format other markdown at GitLab, so we have a SSOT for sanitization.
https://gitlab.com/gitlab-org/gitlab/issues/30540
`simple_format` is not defined in ActionView::Helpers::TagHelper, but
it is actually located in ActionView::Helpers::TextHelper.
The solution is to include the correct helper.
I've also added tests for `#markup_unsafe` because they were missing.
This adds a `markdown_field` to our types.
Using this helper will render a model's markdown field using the
existing `MarkupHelper` with the context of the GraphQL query
available to the helper.
Having the context available to the helper is needed for redacting
links to resources that the current user is not allowed to see.
Because rendering the HTML can cause queries, the complexity of a
these fields is raised by 5 above the default.
The markdown field helper can be used as follows:
```
markdown_field :note_html, null: false
```
This would generate a field that will render the markdown field `note`
of the model. This could be overridden by adding the `method:`
argument. Passing a symbol for the method name:
```
markdown_field :body_html, null: false, method: :note
```
It will have this description by default:
> The GitLab Flavored Markdown rendering of `note`
This could be overridden by passing a `description:` argument.
The type of a `markdown_field` is always `GraphQL::STRING_TYPE`.
In Rails 5, including `ActionView::Context` can have a significant and
hidden performance penalty because this module also includes
`ActionView::CompiledTemplates`. This means that any module that
includes ActionView::Context becomes a descendant of
`CompiledTemplates`.
When a partial is rendered for the first time, it runs
`ActionView::CompiledTemplates#module_eval`, which will evaluate a
string that defines a new method for that partial. For example, the
source of partial might be this string:
```
def _app_views_project_show_html_haml___12345(local_assigns, output)
"hello world"
end
```
When this string is evaluated, the Ruby interpreter will define the
method and clear the global method cache for all descendants of
`ActionView::CompiledTemplates`. Previous to this change, we
inadvertently made a number of modules fall into this category:
* GroupChildEntity
* NoteUserEntity
* Notify
* MergeRequestUserEntity
* AnalyticsCommitEntity
* CommitEntity
* UserEntity
* Kaminari::Helpers::Paginator
* CurrentUserEntity
* ActionView::Base
* ActionDispatch::DebugExceptions::DebugView
* MarkupHelper
* MergeRequestPresenter
After this change:
* Kaminari::Helpers::Paginator
* ActionView::Base
* ActionDispatch::DebugExceptions::DebugView
Each time a partial is rendered for the first time, all methods for
those modules will have to be redefined. This can exact a significant
performance penalty.
How bad is this penalty? Using the following benchmark script, we can
use DTrace to sample the Ruby interpreter:
```
Benchmark.bm do |x|
x.report do
1000.times do
ActionView::CompiledTemplates.module_eval("def testme\nend")
end
end
end
```
This revealed a 11x jump in the time spent in `core#define_method`
alone.
Rails 6 fixes this behavior by moving the `include CompiledTemplates`
into ActionView::Base so that including `ActionView::Context` doesn't
quietly affect other modules in this way.
Closes https://gitlab.com/gitlab-org/gitlab-ee/issues/11198
By default, we now strip images in the 'first_line_in_markdown'
method. This keeps images from being displayed in the
one-liner of both todo and project activity panels.
Although not currently used, we allow images to be preserved
with the allow_images: true options.