EPICLab / synectic

Cards-based IDE for research into context-aware, heuristic problem-solving development tools.
https://epiclab.github.io/synectic/
MIT License
5 stars 0 forks source link

Browser card #39

Open nelsonni opened 7 years ago

nelsonni commented 7 years ago

The Browser component will provide web browser capabilities within a card, allowing users to view websites while working within Synectic. The initial set of features are:

Navigation

History

Bookmarks

Scroll Navigation

Error Handling

nelsonni commented 6 years ago

Possible reference site for pulling in WebView to use within the Browser card: https://blog.jscrambler.com/building-a-web-browser-using-electron/

nelsonni commented 6 years ago

@Marjan-Adeli Anita wanted me to have you attempt a small, reasonably-scoped implementation task within this project. So using the latest version of the IDE v0.7.3 available on the API_architecture branch, please try to complete just steps 1 and 2 listed above within the next week or two. Obviously jumping into the code might be difficult, so please ask questions if you get stuck.

Marjan-Adeli commented 6 years ago

4e47071e2c340a111f234e87bbecb62303353300 Used webview instead of BrowserWindow, since BrowserWindow controls the entire Electron window and does not allow the Synectic canvas to be maintained during switches in the URL of the BrowserWindow.

nelsonni commented 4 years ago

Searches for React components that wrap around a webview tag will primarily direct towards the React Native WebView component, however, since Synectic is not based on React Native this is an unfeasible solution at this time.

Additionally, there are some concerns when wrapping a React component around the HTML webview tag: electron/electron#6046: webview tag ignores attributes when rendered via React

nelsonni commented 4 years ago

The solution in PR #110 uses the webview tag provided through Electron, which has an internal implementation of:

Under the hood webview is implemented with Out-of-Process iframes (OOPIFs). The webview tag is essentially a custom element using shadow DOM to wrap an iframe element inside it.

So the behavior of webview is very similar to a cross-domain iframe, as examples:

  • When clicking into a webview, the page focus will move from the embedder frame to webview.
  • You can not add keyboard, mouse, and scroll event listeners to webview.
  • All reactions between the embedder frame and webview are asynchronous.

Therefore, in order to style webview tag (for rounded corners in this case) we must apply CSS rules to the internal iframe element which is wrapped in a shadow DOM root. This requires special consideration, per the StackOverflow post Styling a child of a shadow root in Shadow DOM, up to and including the use of the :host pseudo selector.

An initial unsuccessful attempt at using this solution resulted in being able to inject <style> elements beyond the boundaries of the shadow DOM root, but none of the style rules were applied directly to the <iframe> element:

useEffect(() => {
  const webviewTag = document.querySelector('webview');
  if (webviewTag) {
    const updatedInnerHTML = webviewTag.innerHTML + '<style> :host iframe {border-radius: 10px;} </style>';
    webviewTag.innerHTML = updatedInnerHTML;
  }
}, [browserState.current]);