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
acffc062
Commit
acffc062
authored
May 12, 2017
by
Douwe Maan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Specify explicitly whether a blob viewer should be loaded asynchronously
parent
4328bc17
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
73 additions
and
69 deletions
+73
-69
app/controllers/concerns/renders_blob.rb
app/controllers/concerns/renders_blob.rb
+1
-1
app/models/blob_viewer/base.rb
app/models/blob_viewer/base.rb
+11
-27
app/models/blob_viewer/client_side.rb
app/models/blob_viewer/client_side.rb
+1
-1
app/models/blob_viewer/download.rb
app/models/blob_viewer/download.rb
+1
-9
app/models/blob_viewer/license.rb
app/models/blob_viewer/license.rb
+1
-4
app/models/blob_viewer/server_side.rb
app/models/blob_viewer/server_side.rb
+14
-1
app/models/blob_viewer/static.rb
app/models/blob_viewer/static.rb
+14
-0
app/views/projects/blob/_viewer.html.haml
app/views/projects/blob/_viewer.html.haml
+3
-3
spec/helpers/blob_helper_spec.rb
spec/helpers/blob_helper_spec.rb
+2
-1
spec/models/blob_viewer/base_spec.rb
spec/models/blob_viewer/base_spec.rb
+4
-17
spec/models/blob_viewer/server_side_spec.rb
spec/models/blob_viewer/server_side_spec.rb
+16
-0
spec/views/projects/blob/_viewer.html.haml_spec.rb
spec/views/projects/blob/_viewer.html.haml_spec.rb
+5
-5
No files found.
app/controllers/concerns/renders_blob.rb
View file @
acffc062
...
@@ -14,7 +14,7 @@ module RendersBlob
...
@@ -14,7 +14,7 @@ module RendersBlob
return
render_404
unless
viewer
return
render_404
unless
viewer
render
json:
{
render
json:
{
html:
view_to_html_string
(
"projects/blob/_viewer"
,
viewer:
viewer
,
load_async
hronously
:
false
)
html:
view_to_html_string
(
"projects/blob/_viewer"
,
viewer:
viewer
,
load_async:
false
)
}
}
end
end
...
...
app/models/blob_viewer/base.rb
View file @
acffc062
...
@@ -2,11 +2,11 @@ module BlobViewer
...
@@ -2,11 +2,11 @@ module BlobViewer
class
Base
class
Base
PARTIAL_PATH_PREFIX
=
'projects/blob/viewers'
.
freeze
PARTIAL_PATH_PREFIX
=
'projects/blob/viewers'
.
freeze
class_attribute
:partial_name
,
:loading_partial_name
,
:type
,
:extensions
,
:file_types
,
:
client_side
,
:binary
,
:switcher_icon
,
:switcher_title
,
:max_size
,
:absolute_max_size
class_attribute
:partial_name
,
:loading_partial_name
,
:type
,
:extensions
,
:file_types
,
:
load_async
,
:binary
,
:switcher_icon
,
:switcher_title
,
:max_size
,
:absolute_max_size
self
.
loading_partial_name
=
'loading'
self
.
loading_partial_name
=
'loading'
delegate
:partial_path
,
:loading_partial_path
,
:rich?
,
:simple?
,
:
client_side?
,
:server_side?
,
:
text?
,
:binary?
,
to: :class
delegate
:partial_path
,
:loading_partial_path
,
:rich?
,
:simple?
,
:text?
,
:binary?
,
to: :class
attr_reader
:blob
attr_reader
:blob
attr_accessor
:override_max_size
attr_accessor
:override_max_size
...
@@ -35,12 +35,8 @@ module BlobViewer
...
@@ -35,12 +35,8 @@ module BlobViewer
type
==
:auxiliary
type
==
:auxiliary
end
end
def
self
.
client_side?
def
self
.
load_async?
client_side
load_async
end
def
self
.
server_side?
!
client_side?
end
end
def
self
.
binary?
def
self
.
binary?
...
@@ -59,6 +55,10 @@ module BlobViewer
...
@@ -59,6 +55,10 @@ module BlobViewer
false
false
end
end
def
load_async?
self
.
class
.
load_async?
&&
render_error
.
nil?
end
def
too_large?
def
too_large?
max_size
&&
blob
.
raw_size
>
max_size
max_size
&&
blob
.
raw_size
>
max_size
end
end
...
@@ -83,29 +83,13 @@ module BlobViewer
...
@@ -83,29 +83,13 @@ module BlobViewer
# binary from `blob_raw_url` and does its own format validation and error
# binary from `blob_raw_url` and does its own format validation and error
# rendering, especially for potentially large binary formats.
# rendering, especially for potentially large binary formats.
def
render_error
def
render_error
return
@render_error
if
defined?
(
@render_error
)
if
override_max_size
?
absolutely_too_large?
:
too_large?
:too_large
@render_error
=
end
if
server_side_but_stored_externally?
# Files that are not stored in the repository, like LFS files and
# build artifacts, can only be rendered using a client-side viewer,
# since we do not want to read large amounts of data into memory on the
# server side. Client-side viewers use JS and can fetch the file from
# `blob_raw_url` using AJAX.
:server_side_but_stored_externally
elsif
override_max_size
?
absolutely_too_large?
:
too_large?
:too_large
end
end
end
def
prepare!
def
prepare!
# To be overridden by subclasses
# To be overridden by subclasses
end
end
private
def
server_side_but_stored_externally?
server_side?
&&
blob
.
stored_externally?
end
end
end
end
end
app/models/blob_viewer/client_side.rb
View file @
acffc062
...
@@ -3,7 +3,7 @@ module BlobViewer
...
@@ -3,7 +3,7 @@ module BlobViewer
extend
ActiveSupport
::
Concern
extend
ActiveSupport
::
Concern
included
do
included
do
self
.
client_side
=
tru
e
self
.
load_async
=
fals
e
self
.
max_size
=
10
.
megabytes
self
.
max_size
=
10
.
megabytes
self
.
absolute_max_size
=
50
.
megabytes
self
.
absolute_max_size
=
50
.
megabytes
end
end
...
...
app/models/blob_viewer/download.rb
View file @
acffc062
module
BlobViewer
module
BlobViewer
class
Download
<
Base
class
Download
<
Base
include
Simple
include
Simple
# We treat the Download viewer as if it renders the content client-side,
include
Static
# so that it doesn't attempt to load the entire blob contents and is
# rendered synchronously instead of loaded asynchronously.
include
ClientSide
self
.
partial_name
=
'download'
self
.
partial_name
=
'download'
self
.
binary
=
true
self
.
binary
=
true
# We can always render the Download viewer, even if the blob is in LFS or too large.
def
render_error
nil
end
end
end
end
end
app/models/blob_viewer/license.rb
View file @
acffc062
module
BlobViewer
module
BlobViewer
class
License
<
Base
class
License
<
Base
# We treat the License viewer as if it renders the content client-side,
# so that it doesn't attempt to load the entire blob contents and is
# rendered synchronously instead of loaded asynchronously.
include
ClientSide
include
Auxiliary
include
Auxiliary
include
Static
self
.
partial_name
=
'license'
self
.
partial_name
=
'license'
self
.
file_types
=
%i(license)
self
.
file_types
=
%i(license)
...
...
app/models/blob_viewer/server_side.rb
View file @
acffc062
...
@@ -3,7 +3,7 @@ module BlobViewer
...
@@ -3,7 +3,7 @@ module BlobViewer
extend
ActiveSupport
::
Concern
extend
ActiveSupport
::
Concern
included
do
included
do
self
.
client_side
=
fals
e
self
.
load_async
=
tru
e
self
.
max_size
=
2
.
megabytes
self
.
max_size
=
2
.
megabytes
self
.
absolute_max_size
=
5
.
megabytes
self
.
absolute_max_size
=
5
.
megabytes
end
end
...
@@ -13,5 +13,18 @@ module BlobViewer
...
@@ -13,5 +13,18 @@ module BlobViewer
blob
.
load_all_data!
(
blob
.
project
.
repository
)
blob
.
load_all_data!
(
blob
.
project
.
repository
)
end
end
end
end
def
render_error
if
blob
.
stored_externally?
# Files that are not stored in the repository, like LFS files and
# build artifacts, can only be rendered using a client-side viewer,
# since we do not want to read large amounts of data into memory on the
# server side. Client-side viewers use JS and can fetch the file from
# `blob_raw_url` using AJAX.
return
:server_side_but_stored_externally
end
super
end
end
end
end
end
app/models/blob_viewer/static.rb
0 → 100644
View file @
acffc062
module
BlobViewer
module
Static
extend
ActiveSupport
::
Concern
included
do
self
.
load_async
=
false
end
# We can always render a static viewer, even if the blob is too large.
def
render_error
nil
end
end
end
app/views/projects/blob/_viewer.html.haml
View file @
acffc062
-
hidden
=
local_assigns
.
fetch
(
:hidden
,
false
)
-
hidden
=
local_assigns
.
fetch
(
:hidden
,
false
)
-
render_error
=
viewer
.
render_error
-
render_error
=
viewer
.
render_error
-
load_async
hronously
=
local_assigns
.
fetch
(
:load_asynchronously
,
viewer
.
server_side?
)
&&
render_error
.
nil?
-
load_async
=
local_assigns
.
fetch
(
:load_async
,
viewer
.
load_async?
)
-
viewer_url
=
local_assigns
.
fetch
(
:viewer_url
)
{
url_for
(
params
.
merge
(
viewer:
viewer
.
type
,
format: :json
))
}
if
load_async
hronously
-
viewer_url
=
local_assigns
.
fetch
(
:viewer_url
)
{
url_for
(
params
.
merge
(
viewer:
viewer
.
type
,
format: :json
))
}
if
load_async
.blob-viewer
{
data:
{
type:
viewer
.
type
,
url:
viewer_url
},
class:
(
'hidden'
if
hidden
)
}
.blob-viewer
{
data:
{
type:
viewer
.
type
,
url:
viewer_url
},
class:
(
'hidden'
if
hidden
)
}
-
if
load_async
hronously
-
if
load_async
=
render
viewer
.
loading_partial_path
,
viewer:
viewer
=
render
viewer
.
loading_partial_path
,
viewer:
viewer
-
elsif
render_error
-
elsif
render_error
=
render
'projects/blob/render_error'
,
viewer:
viewer
=
render
'projects/blob/render_error'
,
viewer:
viewer
...
...
spec/helpers/blob_helper_spec.rb
View file @
acffc062
...
@@ -116,10 +116,11 @@ describe BlobHelper do
...
@@ -116,10 +116,11 @@ describe BlobHelper do
let
(
:viewer_class
)
do
let
(
:viewer_class
)
do
Class
.
new
(
BlobViewer
::
Base
)
do
Class
.
new
(
BlobViewer
::
Base
)
do
include
BlobViewer
::
ServerSide
self
.
max_size
=
1
.
megabyte
self
.
max_size
=
1
.
megabyte
self
.
absolute_max_size
=
5
.
megabytes
self
.
absolute_max_size
=
5
.
megabytes
self
.
type
=
:rich
self
.
type
=
:rich
self
.
client_side
=
false
end
end
end
end
...
...
spec/models/blob_viewer/base_spec.rb
View file @
acffc062
...
@@ -7,11 +7,12 @@ describe BlobViewer::Base, model: true do
...
@@ -7,11 +7,12 @@ describe BlobViewer::Base, model: true do
let
(
:viewer_class
)
do
let
(
:viewer_class
)
do
Class
.
new
(
described_class
)
do
Class
.
new
(
described_class
)
do
include
BlobViewer
::
ServerSide
self
.
extensions
=
%w(pdf)
self
.
extensions
=
%w(pdf)
self
.
binary
=
true
self
.
binary
=
true
self
.
max_size
=
1
.
megabyte
self
.
max_size
=
1
.
megabyte
self
.
absolute_max_size
=
5
.
megabytes
self
.
absolute_max_size
=
5
.
megabytes
self
.
client_side
=
false
end
end
end
end
...
@@ -38,10 +39,10 @@ describe BlobViewer::Base, model: true do
...
@@ -38,10 +39,10 @@ describe BlobViewer::Base, model: true do
context
'when the file type is supported'
do
context
'when the file type is supported'
do
before
do
before
do
viewer_class
.
file_type
=
:license
viewer_class
.
file_type
s
=
%i(license)
viewer_class
.
binary
=
false
viewer_class
.
binary
=
false
end
end
context
'when the binaryness matches'
do
context
'when the binaryness matches'
do
let
(
:blob
)
{
fake_blob
(
path:
'LICENSE'
,
binary:
false
)
}
let
(
:blob
)
{
fake_blob
(
path:
'LICENSE'
,
binary:
false
)
}
...
@@ -172,19 +173,5 @@ describe BlobViewer::Base, model: true do
...
@@ -172,19 +173,5 @@ describe BlobViewer::Base, model: true do
end
end
end
end
end
end
context
'when the viewer is server side but the blob is stored externally'
do
let
(
:project
)
{
build
(
:empty_project
,
lfs_enabled:
true
)
}
let
(
:blob
)
{
fake_blob
(
path:
'file.pdf'
,
lfs:
true
)
}
before
do
allow
(
Gitlab
.
config
.
lfs
).
to
receive
(
:enabled
).
and_return
(
true
)
end
it
'return :server_side_but_stored_externally'
do
expect
(
viewer
.
render_error
).
to
eq
(
:server_side_but_stored_externally
)
end
end
end
end
end
end
spec/models/blob_viewer/server_side_spec.rb
View file @
acffc062
...
@@ -22,4 +22,20 @@ describe BlobViewer::ServerSide, model: true do
...
@@ -22,4 +22,20 @@ describe BlobViewer::ServerSide, model: true do
subject
.
prepare!
subject
.
prepare!
end
end
end
end
describe
'#render_error'
do
context
'when the blob is stored externally'
do
let
(
:project
)
{
build
(
:empty_project
,
lfs_enabled:
true
)
}
let
(
:blob
)
{
fake_blob
(
path:
'file.pdf'
,
lfs:
true
)
}
before
do
allow
(
Gitlab
.
config
.
lfs
).
to
receive
(
:enabled
).
and_return
(
true
)
end
it
'return :server_side_but_stored_externally'
do
expect
(
subject
.
render_error
).
to
eq
(
:server_side_but_stored_externally
)
end
end
end
end
end
spec/views/projects/blob/_viewer.html.haml_spec.rb
View file @
acffc062
...
@@ -12,7 +12,7 @@ describe 'projects/blob/_viewer.html.haml', :view do
...
@@ -12,7 +12,7 @@ describe 'projects/blob/_viewer.html.haml', :view do
self
.
partial_name
=
'text'
self
.
partial_name
=
'text'
self
.
max_size
=
1
.
megabyte
self
.
max_size
=
1
.
megabyte
self
.
absolute_max_size
=
5
.
megabytes
self
.
absolute_max_size
=
5
.
megabytes
self
.
client_side
=
fals
e
self
.
load_async
=
tru
e
end
end
end
end
...
@@ -35,9 +35,9 @@ describe 'projects/blob/_viewer.html.haml', :view do
...
@@ -35,9 +35,9 @@ describe 'projects/blob/_viewer.html.haml', :view do
render
partial:
'projects/blob/viewer'
,
locals:
{
viewer:
viewer
}
render
partial:
'projects/blob/viewer'
,
locals:
{
viewer:
viewer
}
end
end
context
'when the viewer is
server side
'
do
context
'when the viewer is
loaded asynchronously
'
do
before
do
before
do
viewer_class
.
client_side
=
fals
e
viewer_class
.
load_async
=
tru
e
end
end
context
'when there is no render error'
do
context
'when there is no render error'
do
...
@@ -65,9 +65,9 @@ describe 'projects/blob/_viewer.html.haml', :view do
...
@@ -65,9 +65,9 @@ describe 'projects/blob/_viewer.html.haml', :view do
end
end
end
end
context
'when the viewer is
client side
'
do
context
'when the viewer is
loaded synchronously
'
do
before
do
before
do
viewer_class
.
client_side
=
tru
e
viewer_class
.
load_async
=
fals
e
end
end
context
'when there is no render error'
do
context
'when there is no render error'
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