Skip to content
Snippets Groups Projects

Refactor rich blob viewers and add Code|Rendered switch

Merged Douwe Maan requested to merge dm-blob-viewers into master

Fixes https://gitlab.com/gitlab-org/gitlab-ce/issues/24287

EE port: https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/1720

After https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/10563, and while waiting for the build for https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/1556 to succeed, I couldn't help myself.

We now have:

  • a totally refactored backend for BlobViewers,
  • a Source|Rendered switch that shows "Rendered" by default, except when the URL anchor starts with #L, which means line number anchors now work to link to specific lines in Markdown source!
  • a file size limit of 10MB on client-side rendered files, so we don't force users to download huge files,
  • and a .blob-viewer[data-type=simple] that rich JS viewers can fall back to when the rich rendering fails for whatever reason. They should hide() their own blob viewer (.blob-viewer[data-type=rich]) and the switch buttons (.js-blob-viewer-switcher), and show() that simple fallback viewer, which will be the regular Download or Text view.

To do:

  • Split up in a sensible way
  • Specs

The switch can be seen in action with SVG, but also supported for Markdown and IPython Notebooks, as well as other supported Markup formats:

Screen_Shot_2017-04-11_at_15.33.11

Screen_Shot_2017-04-11_at_15.33.15

/cc @rspeicher @jschatz1 @rymai @grzesiek

Merge request reports

Loading
Loading

Activity

Filter activity
  • Approvals
  • Assignees & reviewers
  • Comments (from bots)
  • Comments (from users)
  • Commits & branches
  • Edits
  • Labels
  • Lock status
  • Mentions
  • Merge request status
  • Tracking
  • Douwe Maan
  • Douwe Maan mentioned in merge request !10563 (merged)

    mentioned in merge request !10563 (merged)

  • By the way, I think the JS viewers should have a max file size set on them, so that we don't force the user to download a huge file from the repo or LFS. We could also require the user to press some button to load the viewer if the file size is over some amount... Would 10MB be a good limit, or do we expect things like STL and Sketch files to be larger than that?

    Yeah I agree, was something I was thinking about after the STL viewer was merged in. I'll work on that outside of this :thumbsup:

    The STL files might be larger than that (not sure about Sketch) but then I guess giving the user an option to view the file instead of being forced to download the file is better, especially if on a mobile device.

  • @DouweM At the moment it just hides & shows a div, which for large files just destroys the performance. Is there anyway we can do this through a link? ie. click code link & it has ?raw=1 at the end of the URL which shows the code instead?

  • Phil Hughes added 1 commit

    added 1 commit

    Compare with previous version

  • Author Contributor

    Yeah I agree, was something I was thinking about after the STL viewer was merged in. I'll work on that outside of this :thumbsup:

    @iamphill I already implemented the 10MB limit here :) Since this is likely to go into 9.2, there's no need for you to do any separate effort before this goes in.

    The STL files might be larger than that (not sure about Sketch) but then I guess giving the user an option to view the file instead of being forced to download the file is better, especially if on a mobile device.

    True, we can allow an override of the max file size limit. Let me look into that.

  • Author Contributor

    @DouweM At the moment it just hides & shows a div, which for large files just destroys the performance. Is there anyway we can do this through a link? ie. click code link & it has ?raw=1 at the end of the URL which shows the code instead?

    @iamphill How do you mean destroys the performance? That's totally something we can do, but not requiring a reload is nice, and has this benefit:

    [We now have] a .blob-viewer[data-type=simple] that rich JS viewers can fall back to when the rich rendering fails for whatever reason. They should hide() their own blob viewer (.blob-viewer[data-type=rich]) and the switch buttons (.js-blob-viewer-switcher), and show() that simple fallback viewer, which will be the regular Download or Text view.

  • Douwe Maan
  • Douwe Maan
  • How do you mean destroys the performance? That's totally something we can do, but not requiring a reload is nice, and has this benefit:

    Yeah I really like that benefit as well. But on a IPython notebook file I have locally, it has ~5000 lines, so going from rendered view to code view freezes the browser for a second or so.

    Maybe we could get the code through a AJAX request? So we still handle it on the frontend, but don't render it initially.

  • Douwe Maan
  • Author Contributor

    Yeah I really like that benefit as well. But on a IPython notebook file I have locally, it has ~5000 lines, so going from rendered view to code view freezes the browser for a second or so.

    Maybe we could get the code through a AJAX request? So we still handle it on the frontend, but don't render it initially.

    @iamphill Hmm, yeah, we could do that. If I add a json format to the blob endpoint, could you have a look at that? It will return whatever should go inside .blob-viewer[data-type=simple]. I can of course add that URL in a data-attribute on that .blob-viewer.

    Edited by Douwe Maan
  • @DouweM Yeah I can look at that :thumbsup:

  • Phil Hughes added 1 commit

    added 1 commit

    Compare with previous version

  • Douwe Maan
  • Douwe Maan
  • Douwe Maan
  • Douwe Maan
  • Author Contributor

    @iamphill Can you update the description with a new screenshot now that you've changed the switcher?

  • Douwe Maan added 190 commits

    added 190 commits

    Compare with previous version

  • Douwe Maan added 1 commit

    added 1 commit

    • 4767c509 - Consistent naming for source/rendered/raw/download

    Compare with previous version

  • Douwe Maan added 2 commits

    added 2 commits

    • 414af4e7 - Add JSON endpoint to get simple blob viewer
    • 29e847d6 - Allow viewers to override switcher icon and title

    Compare with previous version

  • Douwe Maan added 2 commits

    added 2 commits

    • 414af4e7 - Add JSON endpoint to get simple blob viewer
    • 29e847d6 - Allow viewers to override switcher icon and title

    Compare with previous version

  • Douwe Maan added 1 commit

    added 1 commit

    • 3e4bfeba - Allow max size to be overridden

    Compare with previous version

  • Douwe Maan
  • Douwe Maan
  • @iamphill if we don't want the freeze the view on bigger files, then we could use a worker. Other than that I don't think there is much else you can do to make it "fast enough" for no jank. Because there will always be a file too big to make it jank.

  • @jschatz1 Pulling the content down by AJAX reduces a lot of jank, yeah it'll still be there on really large files, but its a massive improvement on what it was for me.

  • @iamphill yes we could do that and it would reduce jank. I was thinking of the rendering itself. Like the js functions that have to get run to parse the file. For a large file that itself could create jankage.

  • Author Contributor

    @jschatz1 This MR doesn't concern itself with the implementation of the individual JS viewers, but using workers sounds like a good idea :)

    Edited by Douwe Maan
  • Douwe Maan added 1 commit

    added 1 commit

    • 1f52bcb6 - Use blob viewers on snippets

    Compare with previous version

  • Douwe Maan added 5 commits

    added 5 commits

    • b4e422c9 - Fix issue with markdown helper
    • 0cbde70e - Use class attributes instead of method overrides for immutable blob viewer properties
    • 9ee66c2b - Use BlobViewer instance instead of passing blob as an argument constantly
    • 50fcdf77 - Use correct raw URL for snippets
    • e9da0715 - Add JSON format to snippet show endpoints

    Compare with previous version

  • Just made it pull the source file async, however i've found a bug with the copy contents button. It doesn't actually work when you click it, it will change to view the source file, but it won't actually copy anything until the element is visible & you click it again. Going to look for a solution to this.

  • Phil Hughes added 1 commit

    added 1 commit

    Compare with previous version

  • Author Contributor

    @iamphill Ah right, it switches and then immediately triggers the copy. We should somehow have that wait until the text is actually loaded. That may be tricky, and we'd need to give clear feedback to te user to that affect so they know it's not copied until the page is loaded.

  • Douwe Maan
  • Ah right, it switches and then immediately triggers the copy. We should somehow have that wait until the text is actually loaded. That may be tricky, and we'd need to give clear feedback to te user to that affect so they know it's not copied until the page is loaded.

    It doesn't look like the clipboard library allows for waiting which sucks & it also looks like the user needs to explicitly click the button. I tried triggering it with JS & didn't seem to do it. Will try a few different ways & see if it works.

  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Please register or sign in to reply
    Loading