Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
inject webview-events.js script into preview html (#5766)
## Summary - addresses #4276 - page load detection, title display for HTML files, copy/paste, back/forward navigation, etc. should now work in the Viewer in Positron Server Web / Positron on Workbench ### Release Notes #### New Features - Support page load detection, title display for HTML files, copy-paste, back/forward navigation, page refresh, etc. in the Viewer for Positron Server Web / Positron on Workbench (#4276) #### Bug Fixes - N/A ## Implementation Mainly, I used the "Create some sort of proxy layer of our own to inject the script" idea from #4276, with a bit of "[Run away from home and live in the woods](https://www.wikihow.com/Run-Away-from-Home-and-Live-in-the-Woods)" sprinkled in the process. ### Positron Proxy - We now have a `scripts_preview.html` file that serves a similar purpose for the Viewer as the `scripts_help.html` for the Help Pane, which is used as a "template" to inject resources like styles and scripts into the HTML content being presented in the Viewer - In particular, we inject the `webview-events.js` script (see extensions/positron-proxy/resources/webview-events.js) into this template. The webview-events.js script is a copy of the existing Electron version of the script (see src/vs/workbench/contrib/webview/browser/pre/webview-events.js), with a couple modifications for running in a Web context. Changes are fenced between `// --- Start Positron Proxy Changes ---` and `// --- End Positron Proxy Changes ---` comments. - The HTMLProxy does this injection only when we are running in Web, so that we don't interfere with the Electron webview-events.js script that is injected from the core Positron code. - Refactored Positron Proxy to load and inject Help or Preview resources, move util functions into the util.ts file and type-related declarations to a types.ts file. - Moved all content rewriting functions to util.ts ### Webview land - updated `previewOverlayWebview.ts:loadUri()` to align more closely with the HTML structure of src/vs/workbench/contrib/positronHelp/browser/resources/help.html - the HTML script in `previewOverlayWebview.ts:loadUri()` no longer handles reload/navigation and instead forwards messages along to the Webview or the iframe containing the content as applicable - when forwarding messages to the Webview, the flag `__positron_preview_message` is passed - added some handling to the `onmessage` handler in `webviewElement.ts` to unwrap messages flagged with `__positron_preview_message` and pass them to the appropriate handlers ### HTML Nesting Structure Here's a summary of the HTML nesting situation, with some pseudo-HTML. ```html <iframe from={vs/workbench/contrib/webview/browser/pre/index.html}> <iframe title="Positron Preview" id="active-frame" from={src/vs/workbench/contrib/webview/browser/pre/fake.html}> <body from={src/vs/workbench/contrib/positronPreview/browser/previewOverlayWebview.ts:loadUri()}> <iframe id="preview-iframe" title="Preview Content" src={POSITRON_PROXY_URL_OR_HTML_FILE_PATH}> <head> <style id="preview-style-defaults" from={extensions/positron-proxy/resources/scripts_preview.html}></style> <style id="preview-style-overrides" from={extensions/positron-proxy/resources/scripts_preview.html}></style> <script id="preview-script" from={extensions/positron-proxy/resources/scripts_preview.html}> {CONTENTS OF extensions/positron-proxy/resources/webview-events.js} </script> </head> <body>{HTML CONTENT OF FILE IN VIEWER}</body> </iframe id="preview-iframe" title="Preview Content" src={POSITRON_PROXY_URL_OR_HTML_FILE_PATH}> <script from={src/vs/workbench/contrib/positronPreview/browser/previewOverlayWebview.ts:loadUri()}> {FORWARD MESSAGES TO 'preview-iframe' OR TO PARENT WEBVIEW} </script> </body from={src/vs/workbench/contrib/positronPreview/browser/previewOverlayWebview.ts:loadUri()}> </iframe title="Positron Preview" id="active-frame" from={src/vs/workbench/contrib/webview/browser/pre/fake.html}> </iframe from={vs/workbench/contrib/webview/browser/pre/index.html}> ``` ## QA Notes The changes in this PR should only impact the Viewer in Positron Server Web / Workbench. The following keyboard actions should work: - Copy/Cut/Paste - Select All In the Viewer menu bar, the following buttons should work: - forward/back navigation buttons - refresh/reload button - page title should show for HTML files instead of the HTML file path ### Preview an HTML file directly 1. From the qa-examples-content directory, locate the [OilandGasMetadata.html](https://github.com/posit-dev/qa-example-content/blob/main/workspaces/dash-py-example/data/OilandGasMetadata.html) file 2. Open the HTML file in the Viewer by doing one of the following - Right-click on the file in the File Explorer and select "Open in Viewer" <img width="463" alt="image" src="https://github.com/user-attachments/assets/e867ba63-00c4-4a18-8f49-d521f6257e20" /> - Open the file in an editor and click the View eye icon <img width="349" alt="image" src="https://github.com/user-attachments/assets/15509935-066b-4534-8723-0071484f93d0" /> #### Things to verify - The file's title should show in the Viewer bar, instead of the file path <img width="438" alt="image" src="https://github.com/user-attachments/assets/3a6bae68-80e2-4662-a06b-ddaf9075296b" /> - Make a change to the `OilandGasMetadata.html` file, save the changes and click the Refresh button in the Viewer. The page in the Viewer should refresh and show the change you made. <img width="1085" alt="image" src="https://github.com/user-attachments/assets/41d23de7-d8eb-4c6f-acfe-94223caa7d68" /> - Copy/Cut/Paste/Select All should all work <img width="1088" alt="image" src="https://github.com/user-attachments/assets/ee221889-f561-4660-81e2-fa0e7d74dda1" /> ### Preview an HTML page being served Any of the qa-examples-content directory app frameworks should do, but I tested with the [flask_example](https://github.com/posit-dev/qa-example-content/tree/main/workspaces/python_apps/flask_example), as it's easier to test the back/forward navigation and copy/paste keyboard actions. 1. From the qa-examples-content directory, locate the [__init__.py](https://github.com/posit-dev/qa-example-content/blob/main/workspaces/python_apps/flask_example/__init__.py) file 2. Open the `__init__.py` file in an editor 3. Click the Launch App button <img width="235" alt="image" src="https://github.com/user-attachments/assets/86f69f22-280b-44a0-a238-fb7310399d60" /> #### Things to verify - Back/Forward navigation buttons work https://github.com/user-attachments/assets/06fcca91-230b-4beb-92c2-f8c53b9a8561 1. Click on "Registration" 2. Click on the back arrow -- we should get back to the "Posts" page 3. Click on the forward arrow -- we should go to the "Registration" page - Refresh button works https://github.com/user-attachments/assets/f7b6d016-8195-45c3-94a7-112e9b88c8fa 1. Click on "Registration" 2. Enter some text in one of the input boxes 3. Click the Viewer refresh button -- input should be cleared - Copy/Cut/Paste/Select All should all work
- Loading branch information