Commit a7fd95cd authored by Douwe Maan's avatar Douwe Maan

Render viewer error synchronously so that 'view the source' link will work

parent c69a0779
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
/* global Flash */ /* global Flash */
export default class BlobViewer { export default class BlobViewer {
constructor() { constructor() {
this.switcherBtns = document.querySelectorAll('.js-blob-viewer-switcher'); this.switcher = document.querySelector('.js-blob-viewer-switcher');
this.switcherBtns = document.querySelectorAll('.js-blob-viewer-switch-btn');
this.copySourceBtn = document.querySelector('.js-copy-blob-source-btn'); this.copySourceBtn = document.querySelector('.js-copy-blob-source-btn');
this.simpleViewer = document.querySelector('.blob-viewer[data-type="simple"]'); this.simpleViewer = document.querySelector('.blob-viewer[data-type="simple"]');
this.richViewer = document.querySelector('.blob-viewer[data-type="rich"]'); this.richViewer = document.querySelector('.blob-viewer[data-type="rich"]');
...@@ -10,22 +11,22 @@ export default class BlobViewer { ...@@ -10,22 +11,22 @@ export default class BlobViewer {
let initialViewerName = document.querySelector('.blob-viewer:not(.hidden)').getAttribute('data-type'); let initialViewerName = document.querySelector('.blob-viewer:not(.hidden)').getAttribute('data-type');
if (this.switcherBtns.length) {
this.initBindings(); this.initBindings();
if (location.hash.indexOf('#L') === 0) { if (this.switcher && location.hash.indexOf('#L') === 0) {
initialViewerName = 'simple'; initialViewerName = 'simple';
} }
}
this.switchToViewer(initialViewerName); this.switchToViewer(initialViewerName);
} }
initBindings() { initBindings() {
if (this.switcherBtns.length) {
Array.from(this.switcherBtns) Array.from(this.switcherBtns)
.forEach((el) => { .forEach((el) => {
el.addEventListener('click', this.switchViewHandler.bind(this)); el.addEventListener('click', this.switchViewHandler.bind(this));
}); });
}
if (this.copySourceBtn) { if (this.copySourceBtn) {
this.copySourceBtn.addEventListener('click', () => { this.copySourceBtn.addEventListener('click', () => {
...@@ -91,8 +92,8 @@ export default class BlobViewer { ...@@ -91,8 +92,8 @@ export default class BlobViewer {
const newViewer = document.querySelector(`.blob-viewer[data-type='${name}']`); const newViewer = document.querySelector(`.blob-viewer[data-type='${name}']`);
if (this.activeViewer === newViewer) return; if (this.activeViewer === newViewer) return;
const oldButton = document.querySelector('.js-blob-viewer-switcher.active'); const oldButton = document.querySelector('.js-blob-viewer-switch-btn.active');
const newButton = document.querySelector(`.js-blob-viewer-switcher[data-viewer='${name}']`); const newButton = document.querySelector(`.js-blob-viewer-switch-btn[data-viewer='${name}']`);
const oldViewer = document.querySelector(`.blob-viewer:not([data-type='${name}'])`); const oldViewer = document.querySelector(`.blob-viewer:not([data-type='${name}'])`);
if (oldButton) { if (oldButton) {
......
...@@ -11,7 +11,7 @@ module RendersBlob ...@@ -11,7 +11,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) html: view_to_html_string("projects/blob/_viewer", viewer: viewer, load_asynchronously: false)
} }
end end
end end
...@@ -233,7 +233,7 @@ module BlobHelper ...@@ -233,7 +233,7 @@ module BlobHelper
end end
if viewer.rich? && viewer.blob.rendered_as_text?(override_max_size: true) if viewer.rich? && viewer.blob.rendered_as_text?(override_max_size: true)
options << link_to('view the source', '#', class: 'js-blob-viewer-switcher', data: { viewer: 'simple' }) options << link_to('view the source', '#', class: 'js-blob-viewer-switch-btn', data: { viewer: 'simple' })
end end
options << link_to('download it', blob_raw_url, target: '_blank', rel: 'noopener noreferrer') options << link_to('download it', blob_raw_url, target: '_blank', rel: 'noopener noreferrer')
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
- rich_viewer = blob.rich_viewer - rich_viewer = blob.rich_viewer
- rich_viewer_active = rich_viewer && params[:viewer] != 'simple' - rich_viewer_active = rich_viewer && params[:viewer] != 'simple'
= render 'projects/blob/viewer_wrapper', viewer: simple_viewer, hidden: rich_viewer_active = render 'projects/blob/viewer', viewer: simple_viewer, hidden: rich_viewer_active
- if rich_viewer - if rich_viewer
= render 'projects/blob/viewer_wrapper', viewer: rich_viewer, hidden: !rich_viewer_active = render 'projects/blob/viewer', viewer: rich_viewer, hidden: !rich_viewer_active
- if error = viewer.render_error(override_max_size: params[:override_max_size]) - hidden = local_assigns.fetch(:hidden, false)
= render 'projects/blob/render_error', viewer: viewer, error: error - render_error = viewer.render_error(override_max_size: params[:override_max_size])
- else - load_asynchronously = local_assigns.fetch(:load_asynchronously, viewer.server_side?) && render_error.nil?
- url = url_for(params.merge(viewer: viewer.type, format: :json)) if load_asynchronously
.blob-viewer{ data: { type: viewer.type, url: url }, class: ('hidden' if hidden) }
- if load_asynchronously
.text-center.prepend-top-default.append-bottom-default
= icon('spinner spin 2x', 'aria-hidden' => 'true', 'aria-label' => 'Loading content')
- elsif render_error
= render 'projects/blob/render_error', viewer: viewer, error: render_error
- else
- viewer.prepare! - viewer.prepare!
= render viewer.partial_path, viewer: viewer = render viewer.partial_path, viewer: viewer
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
- simple_viewer = blob.simple_viewer - simple_viewer = blob.simple_viewer
- rich_viewer = blob.rich_viewer - rich_viewer = blob.rich_viewer
.btn-group{ role: "group" } .btn-group.js-blob-viewer-switcher{ role: "group" }
- simple_label = "Display #{simple_viewer.switcher_title}" - simple_label = "Display #{simple_viewer.switcher_title}"
%button.btn.btn-default.btn-sm.js-blob-viewer-switcher.has-tooltip{ 'aria-label' => simple_label, title: simple_label, data: { viewer: 'simple', container: 'body' } }> %button.btn.btn-default.btn-sm.js-blob-viewer-switch-btn.has-tooltip{ 'aria-label' => simple_label, title: simple_label, data: { viewer: 'simple', container: 'body' } }>
= icon(simple_viewer.switcher_icon) = icon(simple_viewer.switcher_icon)
- rich_label = "Display #{rich_viewer.switcher_title}" - rich_label = "Display #{rich_viewer.switcher_title}"
%button.btn.btn-default.btn-sm.js-blob-viewer-switcher.has-tooltip{ 'aria-label' => rich_label, title: rich_label, data: { viewer: 'rich', container: 'body' } }> %button.btn.btn-default.btn-sm.js-blob-viewer-switch-btn.has-tooltip{ 'aria-label' => rich_label, title: rich_label, data: { viewer: 'rich', container: 'body' } }>
= icon(rich_viewer.switcher_icon) = icon(rich_viewer.switcher_icon)
- hidden = local_assigns.fetch(:hidden, false)
- url = url_for(params.merge(format: :json, viewer: viewer.type)) if viewer.server_side?
.blob-viewer{ data: { type: viewer.type, url: url }, class: ('hidden' if hidden) }
- if viewer.server_side?
.text-center.prepend-top-default.append-bottom-default
= icon('spinner spin 2x', 'aria-hidden' => 'true', 'aria-label' => 'Loading content')
- else
= render 'projects/blob/viewer', viewer: viewer
...@@ -19,7 +19,7 @@ feature 'File blob', feature: true do ...@@ -19,7 +19,7 @@ feature 'File blob', feature: true do
it 'switches to code view' do it 'switches to code view' do
visit_blob('files/images/wm.svg') visit_blob('files/images/wm.svg')
first('.js-blob-viewer-switcher').click first('.js-blob-viewer-switch-btn').click
expect(page).to have_selector('.blob-viewer[data-type="rich"]', visible: false) expect(page).to have_selector('.blob-viewer[data-type="rich"]', visible: false)
expect(page).to have_selector('.blob-viewer[data-type="simple"]') expect(page).to have_selector('.blob-viewer[data-type="simple"]')
......
...@@ -26,12 +26,12 @@ describe('Blob viewer', () => { ...@@ -26,12 +26,12 @@ describe('Blob viewer', () => {
}); });
it('loads source file after switching views', (done) => { it('loads source file after switching views', (done) => {
document.querySelector('.js-blob-viewer-switcher[data-viewer="simple"]').click(); document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click();
setTimeout(() => { setTimeout(() => {
expect($.ajax).toHaveBeenCalled(); expect($.ajax).toHaveBeenCalled();
expect( expect(
document.querySelector('.js-blob-viewer-switcher[data-viewer="simple"]') document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]')
.classList.contains('hidden'), .classList.contains('hidden'),
).toBeFalsy(); ).toBeFalsy();
...@@ -47,7 +47,7 @@ describe('Blob viewer', () => { ...@@ -47,7 +47,7 @@ describe('Blob viewer', () => {
setTimeout(() => { setTimeout(() => {
expect($.ajax).toHaveBeenCalled(); expect($.ajax).toHaveBeenCalled();
expect( expect(
document.querySelector('.js-blob-viewer-switcher[data-viewer="simple"]') document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]')
.classList.contains('hidden'), .classList.contains('hidden'),
).toBeFalsy(); ).toBeFalsy();
...@@ -57,7 +57,7 @@ describe('Blob viewer', () => { ...@@ -57,7 +57,7 @@ describe('Blob viewer', () => {
it('doesnt reload file if already loaded', (done) => { it('doesnt reload file if already loaded', (done) => {
const asyncClick = () => new Promise((resolve) => { const asyncClick = () => new Promise((resolve) => {
document.querySelector('.js-blob-viewer-switcher[data-viewer="simple"]').click(); document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click();
setTimeout(resolve); setTimeout(resolve);
}); });
...@@ -91,7 +91,7 @@ describe('Blob viewer', () => { ...@@ -91,7 +91,7 @@ describe('Blob viewer', () => {
}); });
it('enables after switching to simple view', (done) => { it('enables after switching to simple view', (done) => {
document.querySelector('.js-blob-viewer-switcher[data-viewer="simple"]').click(); document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click();
setTimeout(() => { setTimeout(() => {
expect($.ajax).toHaveBeenCalled(); expect($.ajax).toHaveBeenCalled();
...@@ -104,7 +104,7 @@ describe('Blob viewer', () => { ...@@ -104,7 +104,7 @@ describe('Blob viewer', () => {
}); });
it('updates tooltip after switching to simple view', (done) => { it('updates tooltip after switching to simple view', (done) => {
document.querySelector('.js-blob-viewer-switcher[data-viewer="simple"]').click(); document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click();
setTimeout(() => { setTimeout(() => {
expect($.ajax).toHaveBeenCalled(); expect($.ajax).toHaveBeenCalled();
......
require 'spec_helper'
describe 'app/views/projects/blob/_viewer_wrapper.html.haml' do
# TODO: Test
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment