• 
      

    Only add static media once per bundle in the diff viewer.

    Review Request #14545 — Created Aug. 1, 2025 and submitted

    Information

    Review Board
    release-7.1.x

    Reviewers

    We're able to display certain binary files in our diff viewer. A binary
    file is associated with a review UI, which renders the file. Some Review
    UIs have static media bundles which get loaded onto the webpage.
    Previously, we'd load these bundles unconditionally. However, now that
    we use review UIs in the diff viewer, we've discovered that the static
    media of a review UI gets loaded multiple times onto the page, depending
    on how many instances of the review UI are in the diff viewer.
    
    This lead to a problem with Power Pack's PDF and Office Document review
    UIs in the diff viewer. The review UIs include a bundle for the pdf.js
    module, which handles PDF rendering. This module sets up some global
    state that is meant to facilitate rendering multiple PDF documents on
    one page. However, since we were reloading the review UI's static
    bundles everytime a new instance was added to the page, this global
    state would get overwritten each time which would lead to PDF rendering
    issues.
    
    This change updates the diff viewer page to keep note of what static
    bundles have already been loaded onto the page, and to skip loading any
    existing bundles when rendering a new diff reviewable onto the diff
    viewer. This ensures that any state from the static media of a review
    UI will be shared between all instances of that review UI type on the
    page. And we're avoiding unnecessary requests for loading the duplicate
    static media.
    • Ran unit tests (no new failures).
    • Ran JS unit tests (no new failures).
    • Tested with multiple PDF and Office documents in the diff viewer,
      as well as non-binary files.
    • Tested changing the first and last commits in the diff viewer.
    • Tested with only non-binary files in the diff viewer.
    • Tested viewing standalone review UI pages.
    Summary ID
    Only add static media once per review UI type in the diff viewer.
    We're able to display certain binary files in our diff viewer. A binary file is associated with a review UI, which renders the file. Some Review UIs have static media bundles which get loaded onto the webpage. Previously, we'd load these bundles unconditionally. However, now that we use review UIs in the diff viewer, we've discovered that the static media of a review UI gets loaded multiple times onto the page, depending on how many instances of the review UI are in the diff viewer. This lead to a problem with Power Pack's PDF and Office Document review UIs in the diff viewer. The review UIs include a bundle for the pdf.js module, which handles PDF rendering. This module sets up some global state that is meant to facilitate rendering multiple PDF documents on one page. However, since we were reloading the review UI's static bundles everytime a new instance was added to the page, this global state would get overwritten each time which would lead to PDF rendering issues. This change updates the diff viewer page to keep note of what static bundles have already been loaded onto the page, and to skip loading any existing bundles when rendering a new diff reviewable onto the diff viewer. This ensures that any state from the static media of a review UI will be shared between all instances of that review UI type on the page. And we're avoiding unnecessary requests for loading the duplicate static media.
    1a5cbe3f69f3cdc641d5c16949b7ab36d21fb7ac
    Description From Last Updated

    Elsewhere, we name this css_bundles and the JavaScript js_bundles. Maybe css_bundle_names and js_bundle_names would be appropriate here. That'll help differentiate …

    chipx86chipx86

    The diff viewer code doesn't have anything else about attachments or review UIs. This is probably better done in reviewboard/reviews/views/diffviewer.py:ReviewsDiffViewerView.get_context_data, …

    daviddavid

    I assume there's a circular import if we put this at the module level?

    chipx86chipx86

    line too long (82 > 79 characters) Column: 80 Error code: E501

    reviewbotreviewbot

    You could combine the statements for these.

    chipx86chipx86

    Same comments here.

    chipx86chipx86

    This should be safe to import at the file level now.

    daviddavid

    And probably these to match.

    chipx86chipx86

    No need for the backticks here (or really the one below, but it was already like that).

    chipx86chipx86

    New unit tests can use () => instead of function(). We used to use function() because older Jasmine required that, …

    chipx86chipx86

    We should be documenting these. The others didn't get documented, but at least for new ones it'd be worth doing …

    chipx86chipx86

    Can you swap these so they're in alphabetical order?

    chipx86chipx86

    line too long (82 > 79 characters) Column: 80 Error code: E501

    reviewbotreviewbot

    This should go below the next option (alphabetical).

    chipx86chipx86

    This line's too long.

    chipx86chipx86

    Can you add a blank line between these, so it doesn't get lost with the commented one?

    chipx86chipx86
    Checks run (1 failed, 1 succeeded)
    flake8 failed.
    JSHint passed.

    flake8

    david
    1. 
        
    2. reviewboard/diffviewer/diffutils.py (Diff revision 1)
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
      Show all issues

      The diff viewer code doesn't have anything else about attachments or review UIs. This is probably better done in reviewboard/reviews/views/diffviewer.py:ReviewsDiffViewerView.get_context_data, where we iterate over context['files'] and add a bunch of additional stuff.

      css_media and js_media would then become fields of SerializedReviewsDiffFile (defined in that same file)

    3. 
        
    chipx86
    1. Looks great. I just have comments on naming and some small modernization nits.

    2. reviewboard/diffviewer/diffutils.py (Diff revision 1)
       
       
      Show all issues

      Elsewhere, we name this css_bundles and the JavaScript js_bundles. Maybe css_bundle_names and js_bundle_names would be appropriate here. That'll help differentiate from, say, arbitrary CSS or JavaScript URLs.

      1. I went with _media because we have an old ReviewUI.js_files attribute where people can list JavaScript URLs to include on the page instead of bundle names. So technically the js_media set can include arbitrary JavaScript URLs. The css_media will only include bundle names though.

      2. Ah okay, I didn't see that was getting populated. Sounds good then.

    3. reviewboard/diffviewer/diffutils.py (Diff revision 1)
       
       
      Show all issues

      I assume there's a circular import if we put this at the module level?

    4. reviewboard/diffviewer/diffutils.py (Diff revision 1)
       
       
       
       
       
       
      Show all issues

      You could combine the statements for these.

    5. reviewboard/reviews/views/diffviewer.py (Diff revision 1)
       
       
      Show all issues

      Same comments here.

    6. Show all issues

      And probably these to match.

    7. Show all issues

      No need for the backticks here (or really the one below, but it was already like that).

    8. Show all issues

      New unit tests can use () => instead of function().

      We used to use function() because older Jasmine required that, but now () => is recommended.

      Same with other tests.

    9. Show all issues

      We should be documenting these. The others didn't get documented, but at least for new ones it'd be worth doing so intent is clear.

    10. Show all issues

      Can you swap these so they're in alphabetical order?

    11. 
        
    maubin
    david
    1. 
        
    2. reviewboard/reviews/views/diffviewer.py (Diff revisions 1 - 2)
       
       
      Show all issues

      This should be safe to import at the file level now.

    3. 
        
    maubin
    Review request changed
    Change Summary:

    Added an optimization where we try take advantage of already loaded file attachments instead of hitting the database, when possible.

    Commits:
    Summary ID
    Only add static media once per review UI type in the diff viewer.
    We're able to display certain binary files in our diff viewer. A binary file is associated with a review UI, which renders the file. Some Review UIs have static media bundles which get loaded onto the webpage. Previously, we'd load these bundles unconditionally. However, now that we use review UIs in the diff viewer, we've discovered that the static media of a review UI gets loaded multiple times onto the page, depending on how many instances of the review UI are in the diff viewer. This lead to a problem with Power Pack's PDF and Office Document review UIs in the diff viewer. The review UIs include a bundle for the pdf.js module, which handles PDF rendering. This module sets up some global state that is meant to facilitate rendering multiple PDF documents on one page. However, since we were reloading the review UI's static bundles everytime a new instance was added to the page, this global state would get overwritten each time which would lead to PDF rendering issues. This change updates the diff viewer page to keep note of what static bundles have already been loaded onto the page, and to skip loading any existing bundles when rendering a new diff reviewable onto the diff viewer. This ensures that any state from the static media of a review UI will be shared between all instances of that review UI type on the page. And we're avoiding unnecessary requests for loading the duplicate static media.
    e3cd17ac5c048c48a6fd3d0797271d5da9481492
    Only add static media once per review UI type in the diff viewer.
    We're able to display certain binary files in our diff viewer. A binary file is associated with a review UI, which renders the file. Some Review UIs have static media bundles which get loaded onto the webpage. Previously, we'd load these bundles unconditionally. However, now that we use review UIs in the diff viewer, we've discovered that the static media of a review UI gets loaded multiple times onto the page, depending on how many instances of the review UI are in the diff viewer. This lead to a problem with Power Pack's PDF and Office Document review UIs in the diff viewer. The review UIs include a bundle for the pdf.js module, which handles PDF rendering. This module sets up some global state that is meant to facilitate rendering multiple PDF documents on one page. However, since we were reloading the review UI's static bundles everytime a new instance was added to the page, this global state would get overwritten each time which would lead to PDF rendering issues. This change updates the diff viewer page to keep note of what static bundles have already been loaded onto the page, and to skip loading any existing bundles when rendering a new diff reviewable onto the diff viewer. This ensures that any state from the static media of a review UI will be shared between all instances of that review UI type on the page. And we're avoiding unnecessary requests for loading the duplicate static media.
    1a5cbe3f69f3cdc641d5c16949b7ab36d21fb7ac

    Checks run (1 failed, 1 succeeded)

    flake8 failed.
    JSHint passed.

    flake8

    david
    1. Ship It!
    2. 
        
    chipx86
    1. Tiny things, but everything looks good! Ship it after this.

    2. Show all issues

      This should go below the next option (alphabetical).

    3. Show all issues

      This line's too long.

    4. Show all issues

      Can you add a blank line between these, so it doesn't get lost with the commented one?

    5. 
        
    maubin
    Review request changed
    Status:
    Completed
    Change Summary:
    Pushed to release-7.1.x (47c5d7e)