Below, please find the release notes for VirtualViewer v5.7.0 and associated minor releases. For questions, please contact us at questions@snowbound.com or by phone at (617) 607-2010.

v5.7.0 - April 1, 2021

General availability release.

Known Issues

  • A license must be loaded into VirtualViewer to open and view DWG files.
  • The API virtualViewer.saveDocument() requires an additional parameter in order to save a new document with the original format in custom code. Saving a document as requires the parameter options.newDocumentId to be set. Saving as with original format requires the parameters options.saveAsFormat: "Original" and options.pageRangeType: "all". Due to a known issue in 5.7.0, custom code must add options.pageRangeValue: "undefined" in order to save a new document with original format. This issue only applies to the Javascript API; saving from the dialog UI works as expected.

Bug Fixes

  • The reloadAnnotations Javascript API may not be used if the document has any unsaved new pages, removed pages, or changes to page order. In this case, reloadDocument must be used instead.
  • Cancelling picture controls will attempt to reload the page as an SVG if available, instead of leaving the page as a raster version.
  • Document compare functions as expected. In the previous release, an update to the data structure of document text caused document compare to fail.

New features

Variable Opacity for Annotation Background Color

Text annotations, filled rectangles, filled ellipses, and filled polygons now support multiple levels of opacity in their background color. Selecting the Fill Color item in the annotation context menu or in User Preferences will now display an opacity slider. By dragging the slider, the user may change the transparency of the background color.

Annotations with semi-transparent backgrounds can only be saved to the Snowbound Annotation XML format; other formats, such as Filenet XML, do not support the required data fields. By default, the opacity options will be available only if Snowbound XML is the configured annotation output format. The opacity UI can be forced on or off, regardless of annotation format, with the configuration item enableCustomOpacity in config.js.

Highlights, sticky notes, and redactions may not modify their opacity.

Single-key Shortcuts

Hotkey configuration in config.js now allows single-key shortcuts. An example hotkey configuration is as follows:

   {
        key: 'p',   // The key that a user will press to trigger the action
        method: function() {        // A Javascript method to run when the key is pressed
            virtualViewer.printDocumentDialog();    
        },
        localizedValue: 'hotkeyHints.printDocument',   // A localization key pointing to a title string
        defaultValue: 'Print Document'                 // Default string for localization
    }

A hotkey configured in config.js requires the keypress, a Javascript function to call when pressed, and text to display in the hotkey assistance dialog.

Some keys are restricted by the browser and may not be used, while others work unreliably across browsers.

Valid single keys
a to z (lowercase)
F1 to F9
-, =, ;, /
’ (must be escaped, so instead of key: ''' in the configuration, it should be key: '\'')
“Backspace”, “Tab”, “Return”, “Shift”, “Ctrl”, “Alt”, “Pause”, “CapsLock”, “Esc”, “Space”, “Page Up”, “Page Down”, “End”, “Home”, “Left”, “Up”, “Right”, “Down”, “Insert”, “Del”, “numlock”, “scroll”

Email Attachment Support

VirtualViewer is now able to extract and display attached documents on EML and MSG files. If an email file contains an attached document, VirtualViewer will display a small paperclip icon on the document tab. Clicking this paperclip icon will open a dropdown menu listing attached documents.

If the content handler does not implement CreateDocumentInterface, or if document creation fails, selecting an attachment in the dropdown will extract the attachment from the document and allow the user to download the attachment.

Otherwise, if the content handler does implement CreateDocumentInterface, the attachment will open as a new tab in the viewer. It will create a new document from the attachment. In order to distinguish email attachments from newly uploaded documents, a new key and getter in ContentHandlerInput are provided: getParentDocumentId will retrieve the ID of the original email.

Configurable Toolbar Collapse Thresholds

New configuration items in config.js and toolbar-config.js allow administrators to fine-tune toolbar collapse behavior.

At large window sizes, the toolbar in the viewer will display all icons laid out as individual buttons. As the window becomes smaller, or when the viewer is embedded in a small iframe, the toolbar buttons will collapse into dropdown menus. Finally, at extremely small sizes and on mobile devices, all buttons move into a single menu opened by a hamburger button.

The default toolbar collapse thresholds are generally tuned to be appropriate across different screen resolutions, viewer sizes, and button configurations. If buttons remain laid out side-by-side when the screen is too small to display all of them, buttons may be hidden or overflow. It is recommended to use the new toolbar configuration cautiously.

Items in config.js

windowHorizontalThreshold is a new configuration item in config.js. This item may be set to a pixel value. When the width of the browser window or the width of the iframe is below that pixel value, top toolbar buttons will collapse from individual icons into their group dropdown menus. At widths above that pixel value, toolbar buttons will return to individual icons.

windowVerticalThreshold is a new configuration item in config.js. This item may be set to a pixel value. When the height of the browser window or the height of the iframe is below that pixel value, the annotation toolbar buttons will collapse from individual icons into their group dropdown menus. At heights above that pixel value, toolbar buttons will return to individual icons.

disableToolbarHamburger existed in config.js before 5.7, but is relevant. Setting this item to true will ensure that buttons do not collapse into the hamburger menu at small sizes.

Items in toolbar-config.js

Note that the configuration in toolbar-config.js is optional and should only be used when high levels of VirtualViewer customization and fine-tuning are required.

In toolbar-config.js, there are a few different lists of toolbar configurations. The new configuration can be set in the array toolbarButtonLogicalGroups.

toolbarButtonLogicalGroups is a variable storing an array of json objects. Each json object represents a group of toolbar buttons. For example, the vvZoomGroup contains the buttons for zooming in and out, fitting the page, and rubberband zoom. When the toolbar collapses from individual button layout into multiple dropdowns, buttons in a group will all be in the same dropdown.

Now, each json object in toolbarButtonLogicalGroups may include a new attribute, collapseThreshold. Similarly to windowHorizontalThreshold and windowVerticalThreshold, this may be a pixel value. For groups in the top toolbar, it represents a width. For groups in the annotation toolbar, it represents a height.

The collapseThreshold item in a group will individually control when the buttons in that group transition from individual layout to dropdown menu. For example, if vvZoomGroup includes a collapseThreshold item set to 1400, when the browser window has a width less than 1400px, the zoom buttons will shrink down into a dropdown menu. When the browser window has a width greater than 1400px, the zoom buttons will expand to be laid out side-by-side. This will be independent from the overall windowHorizontalThreshold, so the zoom buttons could be collapsed when the rest of the toolbar is laid out, or expanded when the rest of the toolbar is collapsed.

If the collapseThreshold is set to 0, that group will never collapse into a dropdown menu. This allows administrators to ensure that some buttons never collapse into dropdown menus–perhaps buttons that are highly-used in users’ workflow might remain visible and laid out individually, while less-used buttons collapse into dropdowns.

New API to Print or Export Multiple Documents

Two new Javascript API will take an array of document IDs as a parameter, and export or print all of the given documents as a single, compiled document.

The provided documents do not have to be open in the viewer. If any of the documents are open in the viewer, unsaved manipulations like crop, rotation, picture controls, or rearranged pages will be included in the final document. Given document IDs can be any valid ID–virtual, sparse, and compound documents will all be able to be exported.

If any of the requested document IDs encounter an error, the entire document will fail, with an error message noting the problematic document. Media files such as videos or audio files may not be included in the final document, and will throw an error.

There is no restriction on how many documents may be requested. The API will attempt to compile all requested document IDs into a single document; custom code calling these API should enforce a maximum number of documents to request that will work for the parameters of deployment.

Annotations and document notes will not be included in documents generated by this API.

New API

  • virtualViewer.printMultipleDocuments(documentIdArray, options)
    • documentIdArray {array of strings} Pass an array of document IDs. For example: ["1.pdf", "a.tiff", "VirtualDocument:z.gif,y.gif"]
    • options.printDocumentList {boolean} true means that the function will pull its document ID array from the document list, and will attempt to compile all documents into a single result. The default is false.
    • options.fitToPage {boolean} This option is the same as the “fit to page” checkbox in the Print Document dialog. If this is set to true, the final document will consist of 8.5”x11” pages, with images centered on each page.
  • virtualViewer.exportMultipleDocuments(documentIdArray, options)
    • documentIdArray {array of strings} Pass an array of document IDs. For example: ["1.pdf", "a.tiff", "VirtualDocument:z.gif,y.gif"]
    • options.exportDocumentList {boolean} true means that the function will pull its document ID array from the document list, and will attempt to compile all documents into a single result. The default is false.
    • options.exportFormat {string} This item may be set to either “pdf” or “tiff”, and controls the output format of the compiled document. “Original” format will not be accepted. The default option is "pdf".

Notes

Documents created by exportMultipleDocuments will, by default, have the filename ExportedDocument.pdf or ExportedDocument.tif. In order to customize this, use the existing exportDocumentNameGenerator callback: this callback is set using the API virtualViewer.setExportDocumentNameGenerator(callbackFn). The callback function must return a string, which will be used as the exported document’s name.

Note that the document list may be configured by setting config.js:multipleDocMode to vvDefines.multipleDocModes.availableDocuments, vvDefines.multipleDocModes.specifiedDocuments, or vvDefines.multipleDocModes.viewedDocuments. Some of these options may create very long document lists, so the printDocumentList and exportDocumentList options should be used with caution.

Callbacks

  • exportMultipleDocumentsError will fire if exportMultipleDocuments encounters an error. Note that, similarly to exportDocument, there is no “success” callback. The following parameters will be provided to the callback in the argument object:
    • documentIds {array} The IDs of all the documents to be compiled together and exported.
    • format {string} The format that the documents were exported as. This will be “PDF” or “TIFF”
    • filename {string} The preferred filename for the exported document.
    • clientInstanceId {string} The clientInstanceId sent to the server.
    • exceptionMessage {string} An exception message, either one returned from the server or one noting a JSON parse error.
  • exportMultipleDocumentsBegin is called when VirtualViewer compiles a document from an array to be exported–this is called when the process has been validated and initiated on the client. This will be called before any server calls. The following parameters will be provided to the callback in the argument object:
    • documentIds {array} The IDs of all the documents to be compiled together and exported.
    • format {string} The format that the documents will be exported as. This will be “PDF” or “TIFF”.
    • filename {string} The preferred filename for the exported document.
    • clientInstanceId {string} The clientInstanceId to be sent to the server.
  • printMultipleDocumentsBegin is called when VirtualViewer compiles a document from an array to be printed–this is called when the process has been validated and initiated on the client. This will be called before any server calls. The following parameters will be provided to the callback in the argument object:
    • documentIds {array} The set of IDs to be compiled into the printed document.
    • fitToPage {boolean} Whether to force image PDFs to letter-sized pages with the image centered.
    • clientInstanceId {string} The clientInstanceId to be sent to the server.
  • printMultipleDocumentsError is called when VirtualViewer compiles a document from an array to be printed, and the document encounters an error while printing. The following parameters will be provided to the callback in the argument object:
    • documentIds {array} The set of IDs compiled into the printed document.
    • clientInstanceId {string} The clientInstanceId sent to the server.
    • exceptionMessage {string} A brief description of the error.
  • printMultipleDocuments is called when VirtualViewer has compiled a document from an array to be printed. Essentially, VirtualViewer’s role is to publish the document so the browser can handle printing from that point forward. This callback is called when VirtualViewer’s role is complete and the viewer sees the system print dialog.The following parameters will be provided to the callback in the argument object:
    • documentIds {array} The set of IDs compiled into the printed document.
    • clientInstanceId {string} The clientInstanceId sent to the server.

Changes to Dynamic Font Loading

VirtualViewer is able to dynamically load fonts into RasterMaster from ttf files. Now, that font loading is performed on servlet startup.

New configuration is required to load fonts dynamically into VirtualViewer. web.xml.example contains an example of the new item. The following xml element should be added to web.xml, as a child of the web-app element:

    <listener>
        <listener-class>
            com.snowbound.ajax.servlet.ContextListener
        </listener-class>
    </listener>

Fonts must be provided as ttf files, and are read as resources from the path [web-app route]/fonts.

User Preferences Export and Import

Added two API for users to save out a snapshot of their user preferences in JSON and to load in that JSON to apply it overwriting your current User Preferences. This can be used to generate an enforced set of user preferences that load in any time a user opens Virtual Viewer.

  • virtualViewer.exportUserPreferences: Generates a JSON object of the Virtual Viewer user preferences. We do not recommend modifying this JSON by adding or deleting values from it.
  • virtualViewer.importUserPreferences: Takes in the JSON that export created. If you modify the object by adding or removing values to it VirtualViewer will not load the object properly and you will have to generate a new one.

Media Load Completion Callbacks

These callbacks fire for both video and audio files.

  • canPlay will fire once the media is ready to play on the browser. The following parameters will be provided to the callback in the argument object:
    • type The type of media that’s being loaded, either “video” or “audio”
    • event The event object that is passed to the canplay media event.
    • documentId The ID of the media file.
  • canPlayThrough will fire once the media is able to play from start to finish with no pause for buffering. The following parameters will be provided to the callback in the argument object:
    • type The type of media that’s being loaded, either “video” or “audio”
    • event The event object that is passed to the canplay media event.
    • documentId The ID of the media file.
  • mediaEnded will fire once the media is finished with it’s playback. The following parameters will be provided to the callback in the argument object:
    • type The type of media that’s being loaded, either “video” or “audio”
    • event The event object that is passed to the canplay media event.
    • documentId The ID of the media file.
  • mediaError will fire if there is an error in the media playing process. An error object is passed through to the callback function. The following parameters will be provided to the callback in the argument object:
    • type The type of media that’s being loaded, either “video” or “audio”
    • error The error object that is passed to the error media event.
    • documentId The ID of the media file.
  • mediaPause will fire if the media gets paused. The following parameters will be provided to the callback in the argument object:
    • type The type of media that’s being loaded, either “video” or “audio”
    • event The event object that is passed to the canplay media event.
    • documentId The ID of the media file.
  • mediaPlay will fire when the media gets played. The following parameters will be provided to the callback in the argument object:
    • type The type of media that’s being loaded, either “video” or “audio”
    • event The event object that is passed to the canplay media event.
    • documentId The ID of the media file.

Small features

  • The configuration item maxNumberOfTabs has been moved from vvDefines.js to config.js, allowing administrators to set how many tabs may be opened in VirtualViewer.
  • The web.xml init param xlsxMaximumPageLimit has been removed and will have no effect if set. This item was provided as a stopgap solution to prevent extremely large XLSX documents from using too much memory; now, the underlying render code has been significantly improved and provides better protection without hiding data from users.
  • The configuration item imageScrollbars in config.js has been removed and has been replaced with the item panToolPreference. This can be set to vvDefines.panToolPref.noPanTool, vvDefines.panToolPref.panToolWithoutScrollbars, or vvDefines.panToolPref.panToolWithScrollbars. The option vvDefines.panToolPref.noPanTool disables the pan tool by default, while the other two options both enable the pan tool. This configuration may also be set in User Preferences.
  • The email event notification now has more informational parameters, in addition to the document ID: the document format (PDF, TIFF, or Original), “From:” address, “To:” addresses, “CC:” addresses, “BCC:” addresses, subject line, and message.