Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
109816c4
Commit
109816c4
authored
Oct 06, 2016
by
Nick Thomas
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use CacheMarkdownField for notes
parent
e94cd6fd
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
55 additions
and
75 deletions
+55
-75
app/models/note.rb
app/models/note.rb
+4
-1
app/views/projects/notes/_note.html.haml
app/views/projects/notes/_note.html.haml
+1
-1
lib/banzai/note_renderer.rb
lib/banzai/note_renderer.rb
+2
-3
lib/banzai/object_renderer.rb
lib/banzai/object_renderer.rb
+24
-29
spec/lib/banzai/note_renderer_spec.rb
spec/lib/banzai/note_renderer_spec.rb
+1
-2
spec/lib/banzai/object_renderer_spec.rb
spec/lib/banzai/object_renderer_spec.rb
+23
-39
No files found.
app/models/note.rb
View file @
109816c4
...
...
@@ -6,10 +6,13 @@ class Note < ActiveRecord::Base
include
Awardable
include
Importable
include
FasterCacheKeys
include
CacheMarkdownField
cache_markdown_field
:note
,
pipeline: :note
# Attribute containing rendered and redacted Markdown as generated by
# Banzai::ObjectRenderer.
attr_accessor
:note_html
attr_accessor
:
redacted_
note_html
# An Array containing the number of visible references as generated by
# Banzai::ObjectRenderer
...
...
app/views/projects/notes/_note.html.haml
View file @
109816c4
...
...
@@ -61,7 +61,7 @@
.note-body
{
class:
note_editable
?
'js-task-list-container'
:
''
}
.note-text.md
=
preserve
do
=
note
.
note_html
=
note
.
redacted_
note_html
=
edited_time_ago_with_tooltip
(
note
,
placement:
'bottom'
,
html_class:
'note_edited_ago'
,
include_author:
true
)
-
if
note_editable
=
render
'projects/notes/edit_form'
,
note:
note
...
...
lib/banzai/note_renderer.rb
View file @
109816c4
...
...
@@ -3,7 +3,7 @@ module Banzai
# Renders a collection of Note instances.
#
# notes - The notes to render.
# project - The project to use for re
ndering/re
dacting.
# project - The project to use for redacting.
# user - The user viewing the notes.
# path - The request path.
# wiki - The project's wiki.
...
...
@@ -13,8 +13,7 @@ module Banzai
user
,
requested_path:
path
,
project_wiki:
wiki
,
ref:
git_ref
,
pipeline: :note
)
ref:
git_ref
)
renderer
.
render
(
notes
,
:note
)
end
...
...
lib/banzai/object_renderer.rb
View file @
109816c4
module
Banzai
# Class for rendering multiple objects (e.g. Note instances) in a single pass.
# Class for rendering multiple objects (e.g. Note instances) in a single pass,
# using +render_field+ to benefit from caching in the database. Rendering and
# redaction are both performed.
#
# Rendered Markdown is stored in an attribute in every object based on the
# name of the attribute containing the Markdown. For example, when the
# attribute `note` is rendered the HTML is stored in `note_html`.
# The unredacted HTML is generated according to the usual +render_field+
# policy, so specify the pipeline and any other context options on the model.
#
# The *redacted* (i.e., suitable for use) HTML is placed in an attribute
# named "redacted_<foo>", where <foo> is the name of the cache field for the
# chosen attribute.
#
# As an example, rendering the attribute `note` would place the unredacted
# HTML into `note_html` and the redacted HTML into `redacted_note_html`.
class
ObjectRenderer
attr_reader
:project
,
:user
# Make sure to set the appropriate pipeline in the `raw_context` attribute
# (e.g. `:note` for Note instances).
#
# project - A Project to use for rendering and redacting Markdown.
# project - A Project to use for redacting Markdown.
# user - The user viewing the Markdown/HTML documents, if any.
# context - A Hash containing extra attributes to use in the rendering
# pipeline.
def
initialize
(
project
,
user
=
nil
,
raw_context
=
{})
# context - A Hash containing extra attributes to use during redaction
def
initialize
(
project
,
user
=
nil
,
redaction_context
=
{})
@project
=
project
@user
=
user
@r
aw_context
=
raw
_context
@r
edaction_context
=
redaction
_context
end
# Renders and redacts an Array of objects.
#
# objects - The objects to render
# objects - The objects to render
.
# attribute - The attribute containing the raw Markdown to render.
#
# Returns the same input objects.
...
...
@@ -32,7 +36,7 @@ module Banzai
objects
.
each_with_index
do
|
object
,
index
|
redacted_data
=
redacted
[
index
]
object
.
__send__
(
"
#{
attribute
}
_html="
,
redacted_data
[
:document
].
to_html
.
html_safe
)
object
.
__send__
(
"
redacted_
#{
attribute
}
_html="
,
redacted_data
[
:document
].
to_html
.
html_safe
)
object
.
user_visible_reference_count
=
redacted_data
[
:visible_reference_count
]
end
end
...
...
@@ -53,12 +57,8 @@ module Banzai
# Returns a Banzai context for the given object and attribute.
def
context_for
(
object
,
attribute
)
context
=
base_context
.
merge
(
cache_key:
[
object
,
attribute
])
if
object
.
respond_to?
(
:author
)
context
[
:author
]
=
object
.
author
end
context
=
base_context
.
dup
context
=
context
.
merge
(
object
.
banzai_render_context
(
attribute
))
context
end
...
...
@@ -66,21 +66,16 @@ module Banzai
#
# Returns an Array of `Nokogiri::HTML::Document`.
def
render_attributes
(
objects
,
attribute
)
strings_and_contexts
=
objects
.
map
do
|
object
|
objects
.
map
do
|
object
|
string
=
Banzai
.
render_field
(
object
,
attribute
)
context
=
context_for
(
object
,
attribute
)
string
=
object
.
__send__
(
attribute
)
{
text:
string
,
context:
context
}
end
Banzai
.
cache_collection_render
(
strings_and_contexts
).
each_with_index
.
map
do
|
html
,
index
|
Banzai
::
Pipeline
[
:relative_link
].
to_document
(
html
,
strings_and_contexts
[
index
][
:context
])
Banzai
::
Pipeline
[
:relative_link
].
to_document
(
string
,
context
)
end
end
def
base_context
@base_context
||=
@r
aw
_context
.
merge
(
current_user:
user
,
project:
project
)
@base_context
||=
@r
edaction
_context
.
merge
(
current_user:
user
,
project:
project
)
end
end
end
spec/lib/banzai/note_renderer_spec.rb
View file @
109816c4
...
...
@@ -12,8 +12,7 @@ describe Banzai::NoteRenderer do
with
(
project
,
user
,
requested_path:
'foo'
,
project_wiki:
wiki
,
ref:
'bar'
,
pipeline: :note
).
ref:
'bar'
).
and_call_original
expect_any_instance_of
(
Banzai
::
ObjectRenderer
).
...
...
spec/lib/banzai/object_renderer_spec.rb
View file @
109816c4
...
...
@@ -4,10 +4,18 @@ describe Banzai::ObjectRenderer do
let
(
:project
)
{
create
(
:empty_project
)
}
let
(
:user
)
{
project
.
owner
}
def
fake_object
(
attrs
=
{})
object
=
double
(
attrs
.
merge
(
"new_record?"
:
true
,
"destroyed?"
:
true
))
allow
(
object
).
to
receive
(
:markdown_cache_field_for
).
with
(
:note
).
and_return
(
:note_html
)
allow
(
object
).
to
receive
(
:banzai_render_context
).
with
(
:note
).
and_return
(
project:
nil
,
author:
nil
)
allow
(
object
).
to
receive
(
:update_column
).
with
(
:note_html
,
anything
).
and_return
(
true
)
object
end
describe
'#render'
do
it
'renders and redacts an Array of objects'
do
renderer
=
described_class
.
new
(
project
,
user
)
object
=
double
(
:object
,
note:
'hello'
,
note_html:
nil
)
object
=
fake_object
(
note:
'hello'
,
note_html:
nil
)
expect
(
renderer
).
to
receive
(
:render_objects
).
with
([
object
],
:note
).
and_call_original
...
...
@@ -16,7 +24,7 @@ describe Banzai::ObjectRenderer do
with
(
an_instance_of
(
Array
)).
and_call_original
expect
(
object
).
to
receive
(
:note_html
=
).
with
(
'<p>hello</p>'
)
expect
(
object
).
to
receive
(
:
redacted_
note_html
=
).
with
(
'<p>hello</p>'
)
expect
(
object
).
to
receive
(
:user_visible_reference_count
=
).
with
(
0
)
renderer
.
render
([
object
],
:note
)
...
...
@@ -25,7 +33,7 @@ describe Banzai::ObjectRenderer do
describe
'#render_objects'
do
it
'renders an Array of objects'
do
object
=
double
(
:object
,
note:
'hello'
)
object
=
fake_object
(
note:
'hello'
,
note_html:
nil
)
renderer
=
described_class
.
new
(
project
,
user
)
...
...
@@ -57,49 +65,29 @@ describe Banzai::ObjectRenderer do
end
describe
'#context_for'
do
let
(
:object
)
{
double
(
:object
,
note:
'hello'
)
}
let
(
:object
)
{
fake_object
(
note:
'hello'
)
}
let
(
:renderer
)
{
described_class
.
new
(
project
,
user
)
}
it
'returns a Hash'
do
expect
(
renderer
.
context_for
(
object
,
:note
)).
to
be_an_instance_of
(
Hash
)
end
it
'includes the cache key'
do
it
'includes the banzai render context for the object'
do
expect
(
object
).
to
receive
(
:banzai_render_context
).
with
(
:note
).
and_return
(
foo: :bar
)
context
=
renderer
.
context_for
(
object
,
:note
)
expect
(
context
[
:cache_key
]).
to
eq
([
object
,
:note
])
end
context
'when the object responds to "author"'
do
it
'includes the author in the context'
do
expect
(
object
).
to
receive
(
:author
).
and_return
(
'Alice'
)
context
=
renderer
.
context_for
(
object
,
:note
)
expect
(
context
[
:author
]).
to
eq
(
'Alice'
)
end
end
context
'when the object does not respond to "author"'
do
it
'does not include the author in the context'
do
context
=
renderer
.
context_for
(
object
,
:note
)
expect
(
context
.
key?
(
:author
)).
to
eq
(
false
)
end
expect
(
context
).
to
have_key
(
:foo
)
expect
(
context
[
:foo
]).
to
eq
(
:bar
)
end
end
describe
'#render_attributes'
do
it
'renders the attribute of a list of objects'
do
objects
=
[
double
(
:doc
,
note:
'hello'
),
double
(
:doc
,
note:
'bye'
)]
renderer
=
described_class
.
new
(
project
,
user
,
pipeline: :note
)
objects
=
[
fake_object
(
note:
'hello'
,
note_html:
nil
),
fake_object
(
note:
'bye'
,
note_html:
nil
)]
renderer
=
described_class
.
new
(
project
,
user
)
expect
(
Banzai
).
to
receive
(
:cache_collection_render
).
with
([
{
text:
'hello'
,
context:
renderer
.
context_for
(
objects
[
0
],
:note
)
},
{
text:
'bye'
,
context:
renderer
.
context_for
(
objects
[
1
],
:note
)
}
]).
and_call_original
objects
.
each
do
|
object
|
expect
(
Banzai
).
to
receive
(
:render_field
).
with
(
object
,
:note
).
and_call_original
end
docs
=
renderer
.
render_attributes
(
objects
,
:note
)
...
...
@@ -114,17 +102,13 @@ describe Banzai::ObjectRenderer do
objects
=
[]
renderer
=
described_class
.
new
(
project
,
user
,
pipeline: :note
)
expect
(
Banzai
).
to
receive
(
:cache_collection_render
).
with
([]).
and_call_original
expect
(
renderer
.
render_attributes
(
objects
,
:note
)).
to
eq
([])
end
end
describe
'#base_context'
do
let
(
:context
)
do
described_class
.
new
(
project
,
user
,
pipeline: :note
).
base_context
described_class
.
new
(
project
,
user
,
foo: :bar
).
base_context
end
it
'returns a Hash'
do
...
...
@@ -132,7 +116,7 @@ describe Banzai::ObjectRenderer do
end
it
'includes the custom attributes'
do
expect
(
context
[
:
pipeline
]).
to
eq
(
:note
)
expect
(
context
[
:
foo
]).
to
eq
(
:bar
)
end
it
'includes the current user'
do
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment