diff options
author | Stan Hu <stanhu@gmail.com> | 2016-07-03 22:31:43 -0700 |
---|---|---|
committer | Stan Hu <stanhu@gmail.com> | 2016-07-11 15:09:21 -0700 |
commit | af3727b34a3e61668ffca8dc4db85e3c57ff2cc8 (patch) | |
tree | 0bcdece17af6a14e7e5793f7204ca29a34fc535f /lib | |
parent | 734e44ee79590be6d9f01ca3e815304221a5c88d (diff) | |
download | gitlab-ce-af3727b34a3e61668ffca8dc4db85e3c57ff2cc8.tar.gz |
Optimize system note visibility checking by hiding notes that
have been fully redacted and contain cross-project references.
The previous implementation relied on Note#cross_reference_not_visible_for?,
which essentially tries to render all the Markdown references in a system note
and only displays the note if the user can see the referring project. But this
duplicated the work that Banzai::NotesRenderer was doing already. Instead, for
each note we render, we memoize the number of visible user references and
use it later if it is available.
Improves #19273
Diffstat (limited to 'lib')
-rw-r--r-- | lib/banzai/object_renderer.rb | 10 | ||||
-rw-r--r-- | lib/banzai/redactor.rb | 37 |
2 files changed, 29 insertions, 18 deletions
diff --git a/lib/banzai/object_renderer.rb b/lib/banzai/object_renderer.rb index f0e4f28bf12..dc83b87a6c1 100644 --- a/lib/banzai/object_renderer.rb +++ b/lib/banzai/object_renderer.rb @@ -31,10 +31,10 @@ module Banzai redacted = redact_documents(documents) objects.each_with_index do |object, index| - object.__send__("#{attribute}_html=", redacted.fetch(index)) + redacted_data = redacted[index] + object.__send__("#{attribute}_html=", redacted_data[:document].to_html.html_safe) + object.user_visible_reference_count = redacted_data[:visible_reference_count] end - - objects end # Renders the attribute of every given object. @@ -50,9 +50,7 @@ module Banzai def redact_documents(documents) redactor = Redactor.new(project, user) - redactor.redact(documents).map do |document| - document.to_html.html_safe - end + redactor.redact(documents) end # Returns a Banzai context for the given object and attribute. diff --git a/lib/banzai/redactor.rb b/lib/banzai/redactor.rb index ffd267d5e9a..0df3a72d1c4 100644 --- a/lib/banzai/redactor.rb +++ b/lib/banzai/redactor.rb @@ -19,29 +19,36 @@ module Banzai # # Returns the documents passed as the first argument. def redact(documents) - nodes = documents.flat_map do |document| - Querying.css(document, 'a.gfm[data-reference-type]') - end - - redact_nodes(nodes) + all_document_nodes = document_nodes(documents) - documents + redact_document_nodes(all_document_nodes) end - # Redacts the given nodes + # Redacts the given node documents # - # nodes - An Array of HTML nodes to redact. - def redact_nodes(nodes) - visible = nodes_visible_to_user(nodes) + # data - An Array of a Hashes mapping an HTML document to nodes to redact. + def redact_document_nodes(all_document_nodes) + all_nodes = all_document_nodes.map { |x| x[:nodes] }.flatten + visible = nodes_visible_to_user(all_nodes) + metadata = [] - nodes.each do |node| - unless visible.include?(node) + all_document_nodes.each do |entry| + nodes_for_document = entry[:nodes] + doc_data = { document: entry[:document], visible_reference_count: nodes_for_document.count } + metadata << doc_data + + nodes_for_document.each do |node| + next if visible.include?(node) + + doc_data[:visible_reference_count] -= 1 # The reference should be replaced by the original text, # which is not always the same as the rendered text. text = node.attr('data-original') || node.text node.replace(text) end end + + metadata end # Returns the nodes visible to the current user. @@ -65,5 +72,11 @@ module Banzai visible end + + def document_nodes(documents) + documents.map do |document| + { document: document, nodes: Querying.css(document, 'a.gfm[data-reference-type]') } + end + end end end |